diff options
Diffstat (limited to 'app-c')
828 files changed, 78274 insertions, 0 deletions
diff --git a/app-c/.gitignore b/app-c/.gitignore new file mode 100644 index 000000000..91ac94890 --- /dev/null +++ b/app-c/.gitignore @@ -0,0 +1,10 @@ +**/*.iml +/.idea/ + +# Used to not upload Blackduck Scans +**/appc_bdio.jsonld +**/blackDuckHubProjectName.txt +**/blackDuckHubProjectVersionName.txt + +# Userd to not upload any maven dependency graph outputs +**/deptree.text diff --git a/app-c/appc/.code_styling/APPC CheckStyle Preferences.xml b/app-c/appc/.code_styling/APPC CheckStyle Preferences.xml new file mode 100644 index 000000000..11bc3ed92 --- /dev/null +++ b/app-c/appc/.code_styling/APPC CheckStyle Preferences.xml @@ -0,0 +1,342 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd"> + +<!-- + This configuration file was written by the eclipse-cs plugin configuration editor +--> +<!-- + Checkstyle-Configuration: APPC Rules + Description: none +--> +<module name="Checker"> + <property name="severity" value="warning"/> + <property name="charset" value="UTF-8"/> + <module name="TreeWalker"> + <module name="FileContentsHolder"/> + <module name="OuterTypeFilename"> + <property name="severity" value="error"/> + </module> + <module name="IllegalTokenText"> + <property name="severity" value="warning"/> + <property name="tokens" value="CHAR_LITERAL,STRING_LITERAL"/> + <property name="format" value="\\u00(08|09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/> + <property name="message" value="Avoid using corresponding octal or Unicode escape."/> + <message key="illegal.token.text" value="Token text matches the illegal pattern ''{0}''. Avoid using Octal or Unicode escape sequences. They are confusing and often error prone."/> + </module> + <module name="AvoidEscapedUnicodeCharacters"> + <property name="severity" value="warning"/> + <property name="allowEscapesForControlCharacters" value="true"/> + <property name="allowByTailComment" value="true"/> + <property name="allowNonPrintableEscapes" value="true"/> + </module> + <module name="LineLength"> + <property name="severity" value="info"/> + <property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/> + <property name="max" value="120"/> + </module> + <module name="AvoidStarImport"> + <property name="severity" value="error"/> + </module> + <module name="NoLineWrap"/> + <module name="EmptyBlock"> + <property name="severity" value="error"/> + <property name="option" value="text"/> + <property name="tokens" value="LITERAL_TRY,LITERAL_CATCH,LITERAL_FINALLY,LITERAL_IF,LITERAL_ELSE,LITERAL_SWITCH"/> + </module> + <module name="NeedBraces"> + <property name="severity" value="warning"/> + </module> + <module name="OneStatementPerLine"> + <property name="severity" value="warning"/> + </module> + <module name="MultipleVariableDeclarations"> + <property name="severity" value="warning"/> + </module> + <module name="ArrayTypeStyle"> + <property name="severity" value="info"/> + </module> + <module name="UpperEll"> + <property name="severity" value="warning"/> + </module> + <module name="ModifierOrder"> + <property name="severity" value="warning"/> + </module> + <module name="EmptyLineSeparator"> + <property name="severity" value="info"/> + <property name="allowNoEmptyLineBetweenFields" value="true"/> + </module> + <module name="PackageName"> + <property name="severity" value="warning"/> + <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/> + <message key="name.invalidPattern" value="Package name ''{0}'' must match pattern ''{1}''."/> + </module> + <module name="TypeName"> + <property name="severity" value="warning"/> + <message key="name.invalidPattern" value="Type name ''{0}'' must match pattern ''{1}''."/> + </module> + <module name="MemberName"> + <property name="severity" value="warning"/> + <property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/> + <message key="name.invalidPattern" value="Member name ''{0}'' must match pattern ''{1}''."/> + </module> + <module name="ParameterName"> + <property name="severity" value="warning"/> + <property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/> + <message key="name.invalidPattern" value="Parameter name ''{0}'' must match pattern ''{1}''."/> + </module> + <module name="LocalVariableName"> + <property name="severity" value="warning"/> + <property name="format" value="^[a-z][a-zA-Z0-9_]*$"/> + <property name="allowOneCharVarInForLoop" value="true"/> + <message key="name.invalidPattern" value="Local variable name ''{0}'' must match pattern ''{1}''."/> + </module> + <module name="ClassTypeParameterName"> + <property name="severity" value="warning"/> + <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/> + <message key="name.invalidPattern" value="Class type name ''{0}'' must match pattern ''{1}''."/> + </module> + <module name="MethodTypeParameterName"> + <property name="severity" value="warning"/> + <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/> + <message key="name.invalidPattern" value="Method type name ''{0}'' must match pattern ''{1}''."/> + </module> + <module name="NoFinalizer"> + <property name="severity" value="error"/> + </module> + <module name="VariableDeclarationUsageDistance"> + <property name="severity" value="info"/> + <property name="allowedDistance" value="5"/> + </module> + <module name="MethodParamPad"> + <property name="severity" value="info"/> + </module> + <module name="AnnotationLocation"> + <property name="severity" value="warning"/> + <property name="allowSamelineMultipleAnnotations" value="true"/> + </module> + <module name="NonEmptyAtclauseDescription"> + <property name="severity" value="warning"/> + </module> + <module name="SummaryJavadocCheck"> + <property name="severity" value="ignore"/> + <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/> + </module> + <module name="JavadocMethod"> + <property name="severity" value="warning"/> + <property name="minLineCount" value="2"/> + <property name="allowedAnnotations" value="Override, Test"/> + <property name="scope" value="protected"/> + <property name="allowThrowsTagsForSubclasses" value="true"/> + <property name="allowMissingThrowsTags" value="true"/> + <property name="allowMissingReturnTag" value="true"/> + <property name="suppressLoadErrors" value="true"/> + </module> + <module name="MethodName"> + <property name="severity" value="warning"/> + <property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$"/> + <message key="name.invalidPattern" value="Method name ''{0}'' must match pattern ''{1}''."/> + </module> + <module name="JavadocType"> + <property name="severity" value="warning"/> + <property name="scope" value="protected"/> + </module> + <module name="JavadocStyle"> + <property name="severity" value="warning"/> + <property name="scope" value="protected"/> + <property name="checkFirstSentence" value="false"/> + </module> + <module name="JavadocVariable"> + <property name="severity" value="warning"/> + <property name="excludeScope" value="private"/> + <property name="scope" value="protected"/> + </module> + <module name="ConstantName"> + <property name="severity" value="warning"/> + </module> + <module name="InterfaceTypeParameterName"> + <property name="severity" value="warning"/> + </module> + <module name="IllegalImport"> + <property name="severity" value="error"/> + </module> + <module name="RedundantImport"> + <property name="severity" value="warning"/> + </module> + <module name="UnusedImports"> + <property name="severity" value="info"/> + </module> + <module name="AnonInnerLength"> + <property name="severity" value="info"/> + </module> + <module name="MethodLength"> + <property name="severity" value="info"/> + </module> + <module name="ParameterNumber"> + <property name="severity" value="info"/> + </module> + <module name="OuterTypeNumber"> + <property name="severity" value="error"/> + </module> + <module name="EmptyForInitializerPad"> + <property name="severity" value="info"/> + </module> + <module name="EmptyForIteratorPad"> + <property name="severity" value="info"/> + </module> + <module name="ParenPad"> + <property name="severity" value="info"/> + </module> + <module name="TypecastParenPad"> + <property name="severity" value="info"/> + <property name="tokens" value="RPAREN,TYPECAST"/> + </module> + <module name="RedundantModifier"> + <property name="severity" value="warning"/> + </module> + <module name="AvoidNestedBlocks"> + <property name="severity" value="warning"/> + <property name="allowInSwitchCase" value="true"/> + </module> + <module name="CovariantEquals"> + <property name="severity" value="warning"/> + </module> + <module name="DefaultComesLast"> + <property name="severity" value="info"/> + </module> + <module name="DeclarationOrder"> + <property name="severity" value="ignore"/> + <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="info"/> + </module> + <module name="EmptyStatement"> + <property name="severity" value="error"/> + </module> + <module name="EqualsAvoidNull"> + <property name="severity" value="warning"/> + </module> + <module name="EqualsHashCode"> + <property name="severity" value="warning"/> + </module> + <module name="HiddenField"> + <property name="severity" value="warning"/> + <property name="ignoreConstructorParameter" value="true"/> + <property name="ignoreSetter" value="true"/> + </module> + <module name="IllegalInstantiation"> + <property name="severity" value="warning"/> + <property name="classes" value="java.lang.Boolean"/> + </module> + <module name="IllegalCatch"> + <property name="severity" value="warning"/> + <message key="illegal.catch" value="Catching java.lang.Exception or unchecked exceptions should not be done!"/> + </module> + <module name="IllegalThrows"> + <property name="severity" value="warning"/> + </module> + <module name="InnerAssignment"> + <property name="severity" value="warning"/> + </module> + <module name="MagicNumber"> + <property name="severity" value="warning"/> + </module> + <module name="MissingCtor"> + <property name="severity" value="info"/> + </module> + <module name="ModifiedControlVariable"> + <property name="severity" value="error"/> + </module> + <module name="MultipleStringLiterals"> + <property name="severity" value="info"/> + </module> + <module name="MultipleVariableDeclarations"> + <property name="severity" value="warning"/> + </module> + <module name="NestedForDepth"> + <property name="severity" value="warning"/> + <property name="max" value="4"/> + </module> + <module name="NestedIfDepth"> + <property name="severity" value="warning"/> + <property name="max" value="4"/> + </module> + <module name="NestedTryDepth"> + <property name="severity" value="warning"/> + <property name="max" value="2"/> + </module> + <module name="PackageDeclaration"> + <property name="severity" value="error"/> + </module> + <module name="ParameterAssignment"> + <property name="severity" value="error"/> + <message key="parameter.assignment" value="Assignment of parameter ''{0}'' should not be done. The effect of doing this could cause side effects with the calling method(s)."/> + </module> + <module name="ReturnCount"> + <property name="severity" value="warning"/> + </module> + <module name="SimplifyBooleanExpression"> + <property name="severity" value="info"/> + </module> + <module name="SimplifyBooleanReturn"> + <property name="severity" value="info"/> + </module> + <module name="StringLiteralEquality"> + <property name="severity" value="warning"/> + </module> + <module name="SuperClone"> + <property name="severity" value="error"/> + </module> + <module name="UnnecessaryParentheses"> + <property name="severity" value="info"/> + </module> + <module name="OneStatementPerLine"> + <property name="severity" value="warning"/> + </module> + <module name="FinalClass"> + <property name="severity" value="warning"/> + </module> + <module name="InnerTypeLast"> + <property name="severity" value="warning"/> + </module> + <module name="HideUtilityClassConstructor"> + <property name="severity" value="error"/> + </module> + <module name="InterfaceIsType"> + <property name="severity" value="warning"/> + </module> + <module name="VisibilityModifier"> + <property name="severity" value="error"/> + <property name="protectedAllowed" value="true"/> + </module> + <module name="ClassDataAbstractionCoupling"> + <property name="severity" value="info"/> + </module> + <module name="ClassFanOutComplexity"> + <property name="severity" value="info"/> + </module> + <module name="CyclomaticComplexity"> + <property name="severity" value="info"/> + </module> + <module name="NPathComplexity"> + <property name="severity" value="info"/> + </module> + <module name="TodoComment"> + <property name="severity" value="warning"/> + </module> + <module name="UncommentedMain"> + <property name="severity" value="warning"/> + </module> + </module> + <module name="FileTabCharacter"> + <property name="severity" value="warning"/> + <property name="eachLine" value="true"/> + </module> + <module name="UniqueProperties"> + <property name="severity" value="warning"/> + </module> + <module name="SuppressionFilter"> + <property name="file" value="${samedir}/Checkstyle_Suppression_Filter.xml"/> + </module> + <module name="SuppressionCommentFilter"> + <property name="offCommentFormat" value="@sonar:off"/> + <property name="onCommentFormat" value="@sonar:on"/> + </module> +</module> diff --git a/app-c/appc/.code_styling/Checkstyle_Suppression_Filter.xml b/app-c/appc/.code_styling/Checkstyle_Suppression_Filter.xml new file mode 100644 index 000000000..fe36353f3 --- /dev/null +++ b/app-c/appc/.code_styling/Checkstyle_Suppression_Filter.xml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> + +<!DOCTYPE suppressions PUBLIC + "-//Puppy Crawl//DTD Suppressions 1.1//EN" + "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd"> + +<!-- The suppression filter uses the pattern matcher .find method to match + the expressions against each file being examined. --> +<suppressions> + <!-- Suppress checks for eclipse metafiles and directories --> + <suppress files="\.(project|classpath|settings)$" checks=".*" /> + + <!-- Suppress checks for all test code --> + <suppress files="[\\/]src[\\/]test[\\/]" checks=".*" /> + + <!-- Suppress checks for all generated code --> + <suppress files="[\\/]target[\\/]" checks=".*" /> + + <!-- Suppress checks for all archive type files --> + <suppress files=".+\.(?:jar|zip|war|class|tar|bin)$" checks=".*" /> + + <!-- Suppress checks for all image files --> + <suppress files=".+\.(?:png|gif|jpg|jpeg)$" checks=".*" /> + + <!-- Suppress checks for certain non-java files --> + <suppress files=".+\.(?:cql|xml|xsd|xsl|wsdl)$" checks=".*" /> +</suppressions> diff --git a/app-c/appc/.code_styling/appc-code-cleanup-preferences.xml b/app-c/appc/.code_styling/appc-code-cleanup-preferences.xml new file mode 100644 index 000000000..cc2b1343d --- /dev/null +++ b/app-c/appc/.code_styling/appc-code-cleanup-preferences.xml @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<profiles version="2"> + <profile kind="CleanUpProfile" name="APPC Cleanup Profile" + version="2"> + <setting id="cleanup.format_source_code" value="false" /> + <setting id="cleanup.convert_functional_interfaces" value="false" /> + <setting id="cleanup.add_missing_annotations" value="true" /> + <setting + id="cleanup.use_this_for_non_static_method_access_only_if_necessary" + value="true" /> + <setting id="cleanup.remove_unused_private_types" value="true" /> + <setting id="cleanup.insert_inferred_type_arguments" value="false" /> + <setting + id="cleanup.qualify_static_member_accesses_through_instances_with_declaring_class" + value="true" /> + <setting + id="cleanup.qualify_static_method_accesses_with_declaring_class" + value="false" /> + <setting id="cleanup.add_generated_serial_version_id" value="false" /> + <setting id="cleanup.make_variable_declarations_final" + value="true" /> + <setting id="cleanup.add_missing_methods" value="false" /> + <setting id="cleanup.always_use_this_for_non_static_field_access" + value="false" /> + <setting id="cleanup.use_type_arguments" value="false" /> + <setting id="cleanup.remove_trailing_whitespaces_ignore_empty" + value="false" /> + <setting id="cleanup.correct_indentation" value="true" /> + <setting id="cleanup.never_use_parentheses_in_expressions" + value="true" /> + <setting id="cleanup.add_serial_version_id" value="true" /> + <setting id="cleanup.remove_unused_private_methods" value="true" /> + <setting id="cleanup.use_this_for_non_static_field_access" + value="true" /> + <setting id="cleanup.use_blocks_only_for_return_and_throw" + value="false" /> + <setting id="cleanup.remove_unused_private_members" value="false" /> + <setting + id="cleanup.add_missing_override_annotations_interface_methods" + value="true" /> + <setting id="cleanup.remove_trailing_whitespaces_all" value="true" /> + <setting id="cleanup.make_type_abstract_if_missing_method" + value="false" /> + <setting id="cleanup.always_use_this_for_non_static_method_access" + value="false" /> + <setting id="cleanup.remove_unnecessary_nls_tags" value="true" /> + <setting id="cleanup.format_source_code_changes_only" value="false" /> + <setting + id="cleanup.qualify_static_field_accesses_with_declaring_class" + value="false" /> + <setting id="cleanup.add_missing_nls_tags" value="false" /> + <setting + id="cleanup.use_this_for_non_static_field_access_only_if_necessary" + value="true" /> + <setting + id="cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class" + value="true" /> + <setting id="cleanup.remove_unnecessary_casts" value="true" /> + <setting + id="cleanup.qualify_static_member_accesses_with_declaring_class" + value="true" /> + <setting id="cleanup.use_parentheses_in_expressions" value="false" /> + <setting id="cleanup.remove_unused_private_fields" value="true" /> + <setting id="cleanup.make_parameters_final" value="true" /> + <setting id="cleanup.remove_redundant_type_arguments" value="true" /> + <setting id="cleanup.remove_trailing_whitespaces" value="true" /> + <setting id="cleanup.remove_unused_imports" value="false" /> + <setting id="cleanup.use_anonymous_class_creation" value="false" /> + <setting id="cleanup.organize_imports" value="false" /> + <setting id="cleanup.sort_members" value="false" /> + <setting id="cleanup.remove_private_constructors" value="true" /> + <setting id="cleanup.convert_to_enhanced_for_loop" value="true" /> + <setting id="cleanup.always_use_blocks" value="true" /> + <setting id="cleanup.never_use_blocks" value="false" /> + <setting id="cleanup.use_lambda" value="true" /> + <setting id="cleanup.always_use_parentheses_in_expressions" + value="false" /> + <setting id="cleanup.use_this_for_non_static_method_access" + value="true" /> + <setting id="cleanup.remove_unused_local_variables" value="false" /> + <setting id="cleanup.make_private_fields_final" value="false" /> + <setting id="cleanup.add_missing_deprecated_annotations" + value="true" /> + <setting id="cleanup.add_default_serial_version_id" value="true" /> + <setting id="cleanup.sort_members_all" value="false" /> + <setting id="cleanup.use_blocks" value="true" /> + <setting id="cleanup.add_missing_override_annotations" + value="true" /> + <setting id="cleanup.make_local_variable_final" value="false" /> + </profile> +</profiles> diff --git a/app-c/appc/.code_styling/appc-code-templates-preferences.xml b/app-c/appc/.code_styling/appc-code-templates-preferences.xml new file mode 100644 index 000000000..008445d35 --- /dev/null +++ b/app-c/appc/.code_styling/appc-code-templates-preferences.xml @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<templates> + <template autoinsert="false" context="gettercomment_context" + deleted="false" description="Comment for getter method" enabled="true" + id="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name="gettercomment">/** + * + @return the value of ${bare_field_name} + */</template> + <template autoinsert="false" context="settercomment_context" + deleted="false" description="Comment for setter method" enabled="true" + id="org.eclipse.jdt.ui.text.codetemplates.settercomment" name="settercomment">/** + * + @param ${param} the value for ${bare_field_name} + */</template> + <template autoinsert="true" context="constructorcomment_context" + deleted="false" description="Comment for created constructors" + enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" + name="constructorcomment">/** + * ${tags} + */</template> + <template autoinsert="false" context="filecomment_context" + deleted="false" description="Comment for created Java files" + enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.filecomment" + name="filecomment">/** + * Copyright (C) 2017, AT&T Inc. Intellectual Property. + */ + </template> + <template autoinsert="false" context="typecomment_context" + deleted="false" description="Comment for created types" enabled="true" + id="org.eclipse.jdt.ui.text.codetemplates.typecomment" name="typecomment"> + </template> + <template autoinsert="true" context="fieldcomment_context" + deleted="false" description="Comment for fields" enabled="true" + id="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name="fieldcomment">/** + * + */</template> + <template autoinsert="true" context="methodcomment_context" + deleted="false" description="Comment for non-overriding methods" + enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.methodcomment" + name="methodcomment">/** + * ${tags} + */</template> + <template autoinsert="false" context="overridecomment_context" + deleted="false" description="Comment for overriding methods" + enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.overridecomment" + name="overridecomment">/** + * ${see_to_overridden} + */</template> + <template autoinsert="true" context="delegatecomment_context" + deleted="false" description="Comment for delegate methods" enabled="true" + id="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name="delegatecomment">/** + * ${tags} + * ${see_to_target} + */</template> + <template autoinsert="true" context="newtype_context" + deleted="false" description="Newly created files" enabled="true" + id="org.eclipse.jdt.ui.text.codetemplates.newtype" name="newtype">${filecomment} + ${package_declaration} + + ${typecomment} + ${type_declaration}</template> + <template autoinsert="true" context="classbody_context" + deleted="false" description="Code in new class type bodies" enabled="true" + id="org.eclipse.jdt.ui.text.codetemplates.classbody" name="classbody"> + </template> + <template autoinsert="true" context="interfacebody_context" + deleted="false" description="Code in new interface type bodies" + enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.interfacebody" + name="interfacebody"> + </template> + <template autoinsert="true" context="enumbody_context" + deleted="false" description="Code in new enum type bodies" enabled="true" + id="org.eclipse.jdt.ui.text.codetemplates.enumbody" name="enumbody"> + </template> + <template autoinsert="true" context="annotationbody_context" + deleted="false" description="Code in new annotation type bodies" + enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.annotationbody" + name="annotationbody"> + </template> + <template autoinsert="true" context="catchblock_context" + deleted="false" description="Code in new catch blocks" enabled="true" + id="org.eclipse.jdt.ui.text.codetemplates.catchblock" name="catchblock">// + ${todo} Auto-generated catch block + ${exception_var}.printStackTrace();</template> + <template autoinsert="true" context="methodbody_context" + deleted="false" description="Code in created method stubs" enabled="true" + id="org.eclipse.jdt.ui.text.codetemplates.methodbody" name="methodbody">// + ${todo} Auto-generated method stub + ${body_statement}</template> + <template autoinsert="true" context="constructorbody_context" + deleted="false" description="Code in created constructor stubs" + enabled="true" id="org.eclipse.jdt.ui.text.codetemplates.constructorbody" + name="constructorbody">${body_statement} + // ${todo} Auto-generated constructor stub</template> + <template autoinsert="true" context="getterbody_context" + deleted="false" description="Code in created getters" enabled="true" + id="org.eclipse.jdt.ui.text.codetemplates.getterbody" name="getterbody">return + ${field};</template> + <template autoinsert="true" context="setterbody_context" + deleted="false" description="Code in created setters" enabled="true" + id="org.eclipse.jdt.ui.text.codetemplates.setterbody" name="setterbody">${field} + = ${param};</template> +</templates>
\ No newline at end of file diff --git a/app-c/appc/.code_styling/appc-formatter-preferences.xml b/app-c/appc/.code_styling/appc-formatter-preferences.xml new file mode 100644 index 000000000..fd82d8bfd --- /dev/null +++ b/app-c/appc/.code_styling/appc-formatter-preferences.xml @@ -0,0 +1,295 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<profiles version="12"> +<profile kind="CodeFormatterProfile" name="APPC Code Format" version="12"> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/> +<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="4"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="48"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="0"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="20"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/> +<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120"/> +<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="20"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="20"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="20"/> +<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="18"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="20"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/> +<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/> +<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="20"/> +<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="20"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="18"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="20"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="20"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/> +<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="20"/> +<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="20"/> +<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="20"/> +<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/> +<setting id="org.eclipse.jdt.core.compiler.source" value="1.8"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="4"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="0"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/> +<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="20"/> +<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="18"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/> +<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="20"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="20"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/> +<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.8"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/> +<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/> +<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/> +<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/> +<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/> +</profile> +</profiles> diff --git a/app-c/appc/.gitignore b/app-c/appc/.gitignore new file mode 100644 index 000000000..48c346cca --- /dev/null +++ b/app-c/appc/.gitignore @@ -0,0 +1,29 @@ +# Target dirs in all projects +**/target/* + +# Added for Intellij IDEA IDE +**/.idea/* +*.iml + +# Generated models and features +**/bin/* + +# MANIFEST.MF is updated on every clean install +**/src/main/resources/META-INF/ + +# Karaf Assembly +#/appc-adapters/appc-*-adapter/appc-*-adapter-installer/src/assembly/* + + +.project + +*.prefs +.classpath +**/.classpath +/target/ +logs/ +debug-logs/ +/.settings/ +**/*.iml +/.idea/ +/bin/ diff --git a/app-c/appc/README.md b/app-c/appc/README.md new file mode 100644 index 000000000..66039b19a --- /dev/null +++ b/app-c/appc/README.md @@ -0,0 +1,26 @@ +## Introduction +* Run 'mvn clean install' on this project in order to build and compile all artifacts contained in it. +* The action above will produce a .zip file under the installer directory of each bundle, which can be installed during Docker Instantiation (Please see master README for more information on this). + +## Handling YANG Models +* After running 'mvn clean install', this will generate some code from the yang models. +* Modify the yang model file under the model project. +* Follow the comments in the generated provider class to wire your new provider into the generated +code. +* Modify the generated provider model to respond to and handle the yang model. Depending on what +you added to your model you may need to inherit additional interfaces or make other changes to +the provider model. + +## Structure of a ODL Karaf Feature in APP-C +* model + - Provides the yang model for your application. This is your primary northbound interface. +* provider + - This is where the JAVA code is implemented. This part will define what the Karaf Feature will accomplish and how it will respond to a yang model. +* features + - Defines the contents of a Karaf Feature. If you add dependencies on third-party bundles, then you will need to + modify the features.xml to list out the dependencies. +* installer + - Bundles all of the jars and third party dependencies (minus ODL dependencies) into a single + .zip file with the necessary configuration files in order to install the Karaf Feature by means of calling the Karaf Client (which will ultimately run "feature:install <FEATURE_NAME>") in order to install the feature. + + diff --git a/app-c/appc/appc-adapters/.gitignore b/app-c/appc/appc-adapters/.gitignore new file mode 100644 index 000000000..02b972cc7 --- /dev/null +++ b/app-c/appc/appc-adapters/.gitignore @@ -0,0 +1,7 @@ +target/ +META-INF/MANIFEST.MF +logs/ +/bin/ +/.settings/ +/classes/ +**/*.iml diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/.gitignore b/app-c/appc/appc-adapters/appc-chef-adapter/.gitignore new file mode 100644 index 000000000..d027396de --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/.gitignore @@ -0,0 +1 @@ +/.settings/ diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/.gitignore b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/.gitignore new file mode 100644 index 000000000..755cdc373 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/.gitignore @@ -0,0 +1,3 @@ +/bin/ +/target/ +/.settings/ diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/pom.xml b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/pom.xml new file mode 100644 index 000000000..00f59e4c9 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/pom.xml @@ -0,0 +1,228 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-chef-adapter</artifactId> + <version>1.0.0</version> + </parent> + + <artifactId>appc-chef-adapter-bundle</artifactId> + <packaging>bundle</packaging> + <name>chef Adapter - bundle</name> + + <dependencies> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + <!-- http://mvnrepository.com/artifact/commons-logging/commons-logging --> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>1.2</version> + </dependency> + <!-- http://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore --> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore</artifactId> + <version>4.4.4</version> + </dependency> + + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>4.5.1</version> + </dependency> + <dependency> + <groupId>org.bouncycastle</groupId> + <artifactId>bcpkix-jdk15on</artifactId> + <version>1.47</version> + </dependency> + <dependency> + <groupId>org.bouncycastle</groupId> + <artifactId>bcprov-jdk15on</artifactId> + <version>1.47</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + <classifier>jar-with-dependencies</classifier> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>javax</groupId> + <artifactId>javaee-api</artifactId> + <version>7.0</version> + </dependency> +<!-- <dependency> + <groupId>jce</groupId> + <artifactId>jce</artifactId> + <version>1_2-do</version> + <scope>compile</scope> + </dependency> --> + + <dependency> + <groupId>com.att.cdp</groupId> + <artifactId>cdp-pal-common</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>com.att.cdp</groupId> + <artifactId>cdp-pal-openstack</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>javax.ws.rs</groupId> + <artifactId>javax.ws.rs-api</artifactId> + </dependency> + + <!-- Jersey support needed for OpenStack connector and API version logic --> + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-client</artifactId> + </dependency> + + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-json</artifactId> + </dependency> + + <dependency> + <groupId>javax.xml.bind</groupId> + <artifactId>jaxb-api</artifactId> + <version>2.1</version> + </dependency> + + <dependency> + <groupId>javax.xml</groupId> + <artifactId>jaxp-api</artifactId> + <version>1.4.2</version> + </dependency> + + <!-- Needed to run test cases --> + <dependency> + <groupId>org.glassfish.jersey.core</groupId> + <artifactId>jersey-common</artifactId> + <version>2.9.1</version> + </dependency> + + <dependency> + <groupId>org.codehaus.jackson</groupId> + <artifactId>jackson-jaxrs</artifactId> + <version>1.9.12</version> + </dependency> + + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>4.5.1</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>compile</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>equinoxSDK381</groupId> + <artifactId>org.eclipse.osgi</artifactId> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + </dependency> + + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + <version>5.1.31</version> + <type>jar</type> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>com.vmware</groupId> + <artifactId>vijava</artifactId> + <version>5.1</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>xerces</groupId> + <artifactId>xerces</artifactId> + <version>2.4.0</version> + <scope>provided</scope> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>appc-chef-adapter</Bundle-SymbolicName> + <Bundle-Activator>org.openecomp.appc.adapter.chef.ChefActivator</Bundle-Activator> + <Export-Package>org.openecomp.appc.adapter.chef</Export-Package> + <Import-Package>org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.bind.*,javax.naming.*</Import-Package> + <Embed-Dependency>*;scope=compile|runtime;artifactId=!sli-common|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + + <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/ChefActivator.java b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/ChefActivator.java new file mode 100644 index 000000000..2def2382b --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/ChefActivator.java @@ -0,0 +1,143 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.chef; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.chef.impl.ChefAdapterImpl; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.i18n.Msg; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +/** + * This activator is used to initialize and terminate the connection pool to one or more providers. + * <p> + * The CDP abstraction layer supports multiple types of providers, with each provider supporting multiple tenants. The + * "connection" to a specific tenant on a specific provider is represented by a "context" object. These context objects + * are authenticated to a specific tenant on the provider, but can be reused from one request to another. Contexts are + * slow to set up and are resource intensive, so they are cached. However, the contexts for a specific tenant on a + * specific provider must be cached separately. + * </p> + * <p> + * Activation of the bundle creates an empty cache which is organized first by provider type, then by tenant name, with + * the contents being an empty pool of contexts for that provider/tenant combination. The pool is created on first use, + * and retained for as long as the bundle is active. + * </p> + * <p> + * When the bundle is deactivated, the cache is torn down with all contexts being closed. + * </p> + */ +public class ChefActivator implements BundleActivator { + + /** + * The bundle registration + */ + private ServiceRegistration registration = null; + + /** + * The reference to the actual implementation object that implements the services + */ + private ChefAdapter adapter; + + /** + * The logger to be used + */ + // private static final Logger LOG = LoggerFactory.getLogger(ChefActivator.class); + private static final EELFLogger logger = EELFManager.getInstance().getLogger(ChefActivator.class); + + /** + * The configuration object used to configure this bundle + */ + private Configuration configuration; + + /** + * Called when this bundle is started so the Framework can perform the bundle-specific activities necessary to start + * this bundle. This method can be used to register services or to allocate any resources that this bundle needs. + * <p> + * This method must complete and return to its caller in a timely manner. + * </p> + * + * @param context + * The execution context of the bundle being started. + * @throws java.lang.Exception + * If this method throws an exception, this bundle is marked as stopped and the Framework will remove + * this bundle's listeners, unregister all services registered by this bundle, and release all services + * used by this bundle. + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + logger.info("Starting bundle " + getName()); + + configuration = ConfigurationFactory.getConfiguration(); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.COMPONENT_INITIALIZING, appName, "chef adapter"); + adapter = new ChefAdapterImpl(configuration.getProperties()); + if (registration == null) { + logger.info(Msg.REGISTERING_SERVICE, appName, adapter.getAdapterName(), + ChefAdapter.class.getSimpleName()); + registration = context.registerService(ChefAdapter.class, adapter, null); + } + + logger.info(Msg.COMPONENT_INITIALIZED, appName, "CHEF adapter"); + } + + /** + * Called when this bundle is stopped so the Framework can perform the bundle-specific activities necessary to stop + * the bundle. In general, this method should undo the work that the BundleActivator.start method started. There + * should be no active threads that were started by this bundle when this bundle returns. A stopped bundle must not + * call any Framework objects. + * <p> + * This method must complete and return to its caller in a timely manner. + * </p> + * + * @param context + * The execution context of the bundle being stopped. + * @throws java.lang.Exception + * If this method throws an exception, the bundle is still marked as stopped, and the Framework will + * remove the bundle's listeners, unregister all services registered by the bundle, and release all + * services used by the bundle. * + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + logger.info("Stopping bundle " + getName()); + + if (registration != null) { + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.COMPONENT_TERMINATING, appName, "CHEF adapter"); + logger.info(Msg.UNREGISTERING_SERVICE, appName, adapter.getAdapterName()); + registration.unregister(); + registration = null; + logger.info(Msg.COMPONENT_TERMINATED, appName, "CHEF adapter"); + } + } + + public String getName() { + return "APPC IaaS adapter"; + } + +} diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/ChefAdapter.java b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/ChefAdapter.java new file mode 100644 index 000000000..907ded5d2 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/ChefAdapter.java @@ -0,0 +1,203 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.chef; + +import java.util.Map; + +import org.openecomp.appc.exceptions.APPCException; +import com.att.cdp.zones.model.Server; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + +/** + * This interface defines the operations that the provider adapter exposes. + * <p> + * This interface defines static constant property values that can be used to configure the adapter. These constants are + * prefixed with the name PROPERTY_ to indicate that they are configuration properties. These properties are read from + * the configuration file for the adapter and are used to define the providers, identity service URLs, and other + * information needed by the adapter to interface with an IaaS provider. + * </p> + */ +public interface ChefAdapter extends SvcLogicJavaPlugin { + + /** + * The type of provider to be accessed to locate and operate on a virtual machine instance. This is used to load the + * correct provider support through the CDP IaaS abstraction layer and can be OpenStackProvider, BareMetalProvider, + * or any other supported provider type. + */ + static final String PROPERTY_PROVIDER_TYPE = "org.openecomp.appc.provider.type"; + + /** + * The adapter maintains a cache of providers organized by the name of the provider, not its type. This is + * equivalent to the system or installation name. All regions within the same installation are assumed to be the + * same type. + */ + static final String PROPERTY_PROVIDER_NAME = "org.openecomp.appc.provider.name"; + + /** + * The fully-qualified URL of the instance to be manipulated as it is known to the provider. + */ + static final String PROPERTY_INSTANCE_URL = "org.openecomp.appc.instance.url"; + + /** + * The fully-qualified URL of the instance to be manipulated as it is known to the provider. + */ + static final String PROPERTY_IDENTITY_URL = "org.openecomp.appc.identity.url"; + + /** + * This method is used to restart an existing virtual machine given the fully qualified URL of the machine. + * <p> + * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters + * passed to the method are passed as properties in a map. This method expects the following properties to be + * defined: + * <dl> + * <dt>org.openecomp.appc.provider.type</dt> + * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS + * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported + * provider types are legal.</dd> + * <dt>org.openecomp.appc.instance.url</dt> + * <dd>The fully qualified URL of the instance to be restarted, as it is known to the provider (i.e., the self-link + * URL of the server)</dd> + * </dl> + * </p> + * + * @param properties + * A map of name-value pairs that supply the parameters needed by this method. The properties needed are + * defined above. + * @param context + * The service logic context of the graph being executed. + * @return The <code>Server</code> object that represents the VM being restarted. The returned server object can be + * inspected for the final state of the server once the restart has been completed. The method does not + * return until the restart has either completed or has failed. + * @throws APPCException + * If the server cannot be restarted for some reason + */ + // Server restartServer(Map<String, String> properties, SvcLogicContext context) throws APPCException; + + /** + * This method is used to stop the indicated server + * <p> + * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters + * passed to the method are passed as properties in a map. This method expects the following properties to be + * defined: + * <dl> + * <dt>org.openecomp.appc.provider.type</dt> + * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS + * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported + * provider types are legal.</dd> + * <dt>org.openecomp.appc.instance.url</dt> + * <dd>The fully qualified URL of the instance to be stopped, as it is known to the provider (i.e., the self-link + * URL of the server)</dd> + * </dl> + * </p> + * + * @param properties + * A map of name-value pairs that supply the parameters needed by this method. The properties needed are + * defined above. + * @param context + * The service logic context of the graph being executed. + * @return The <code>Server</code> object that represents the VM being stopped. The returned server object can be + * inspected for the final state of the server once the stop has been completed. The method does not return + * until the stop has either completed or has failed. + * @throws APPCException + * If the server cannot be stopped for some reason + */ + //Server stopServer(Map<String, String> properties, SvcLogicContext context) throws APPCException; + + /** + * This method is used to start the indicated server + * <p> + * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters + * passed to the method are passed as properties in a map. This method expects the following properties to be + * defined: + * <dl> + * <dt>org.openecomp.appc.provider.type</dt> + * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS + * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported + * provider types are legal.</dd> + * <dt>org.openecomp.appc.instance.url</dt> + * <dd>The fully qualified URL of the instance to be started, as it is known to the provider (i.e., the self-link + * URL of the server)</dd> + * </dl> + * </p> + * + * @param properties + * A map of name-value pairs that supply the parameters needed by this method. The properties needed are + * defined above. + * @param context + * The service logic context of the graph being executed. + * @return The <code>Server</code> object that represents the VM being started. The returned server object can be + * inspected for the final state of the server once the start has been completed. The method does not return + * until the start has either completed or has failed. + * @throws APPCException + * If the server cannot be started for some reason + */ + // Server startServer(Map<String, String> properties, SvcLogicContext context) throws APPCException; + + /** + * This method is used to rebuild the indicated server + * <p> + * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters + * passed to the method are passed as properties in a map. This method expects the following properties to be + * defined: + * <dl> + * <dt>org.openecomp.appc.provider.type</dt> + * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS + * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported + * provider types are legal.</dd> + * <dt>org.openecomp.appc.instance.url</dt> + * <dd>The fully qualified URL of the instance to be rebuilt, as it is known to the provider (i.e., the self-link + * URL of the server)</dd> + * </dl> + * </p> + * + * @param properties + * A map of name-value pairs that supply the parameters needed by this method. The properties needed are + * defined above. + * @param context + * The service logic context of the graph being executed. + * @return The <code>Server</code> object that represents the VM being rebuilt. The returned server object can be + * inspected for the final state of the server once the rebuild has been completed. The method does not + * return until the rebuild has either completed or has failed. + * @throws APPCException + * If the server cannot be rebuilt for some reason + */ + // Server rebuildServer(Map<String, String> properties, SvcLogicContext context) throws APPCException; + + /** + * Returns the symbolic name of the adapter + * + * @return The adapter name + */ + String getAdapterName(); + + // Server evacuateServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + //Server migrateServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + void trigger(Map<String, String> params, SvcLogicContext ctx) ; + + void chefGet(Map<String, String> params, SvcLogicContext ctx) ; + + void chefPut(Map<String, String> params, SvcLogicContext ctx) ; + +} diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefapi/ApiMethod.java b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefapi/ApiMethod.java new file mode 100644 index 000000000..d2a0eb26f --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefapi/ApiMethod.java @@ -0,0 +1,185 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.chef.chefapi; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +import org.apache.http.*; +import org.apache.http.client.*; +import org.apache.http.client.methods.*; +import org.apache.http.impl.client.*; +import org.apache.http.util.EntityUtils; +import org.openecomp.appc.adapter.chef.chefclient.Utils; + +import javax.net.ssl.SSLContext; +import java.io.File; +import org.apache.http.HttpEntity; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.ssl.SSLContexts; + +public class ApiMethod { + private HttpClient client = null; + protected HttpRequestBase method = null; + protected HttpResponse response = null; + protected String reqBody = ""; + protected String userId = ""; + protected String pemPath = ""; + protected String chefPath = ""; + protected String organizations = ""; + protected int resCode=0; + protected String responseBody=""; + private String methodName = "GET"; + public String test = ""; + private int returnCode; +// final String KEY_STORE_PATH = "/tmp/chef/trusted_certs/mykeystore.jks"; +// final String KEY_STORE_PASSWORD = "changeit"; + + public ApiMethod(String methodName) { +/* try { + SSLContext sslcontext = SSLContexts.custom() + .loadTrustMaterial(new File(KEY_STORE_PATH), KEY_STORE_PASSWORD.toCharArray(), + new TrustSelfSignedStrategy()) + .build(); + SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( + sslcontext, + new String[] { "TLSv1" }, + null, + SSLConnectionSocketFactory.getDefaultHostnameVerifier()); + client = HttpClients.custom() + .setSSLSocketFactory(sslsf) + .build(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }*/ + client=HttpClients.createDefault(); + this.methodName = methodName; + } + + public ApiMethod execute() { + String hashedPath = Utils.sha1AndBase64("/organizations/"+organizations+chefPath); + String hashedBody = Utils.sha1AndBase64(reqBody); + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + sdf.setTimeZone(TimeZone.getTimeZone("UTC")); + String timeStamp = sdf.format(new Date()); + timeStamp = timeStamp.replace(" ", "T"); + timeStamp = timeStamp + "Z"; + + StringBuilder sb = new StringBuilder(); + sb.append("Method:").append(methodName).append("\n"); + sb.append("Hashed Path:").append(hashedPath).append("\n"); + sb.append("X-Ops-Content-Hash:").append(hashedBody).append("\n"); + sb.append("X-Ops-Timestamp:").append(timeStamp).append("\n"); + sb.append("X-Ops-UserId:").append(userId); + test = test + "sb " + sb + "\n"; + + String auth_String = Utils.signWithRSA(sb.toString(), pemPath); + String[] auth_headers = Utils.splitAs60(auth_String); + + method.addHeader("Content-type", "application/json"); + method.addHeader("X-Ops-Timestamp", timeStamp); + method.addHeader("X-Ops-Userid", userId); + method.addHeader("X-Chef-Version", "12.4.1"); + method.addHeader("Accept", "application/json"); + method.addHeader("X-Ops-Content-Hash", hashedBody); + method.addHeader("X-Ops-Sign", "version=1.0"); + + for (int i = 0; i < auth_headers.length; i++) { + method.addHeader("X-Ops-Authorization-" + (i + 1), auth_headers[i]); + } + /* + * test=test+this.method.getMethod()+"\n"; Header[] + * RHS=this.method.getHeaders(); for (int i = 0; i < RHS.length; i++) { + * test=test+RHS[i]+"\n"; } test=test+this.reqBody+"\n"; + */ + try{ + response = client.execute(method); + resCode = response.getStatusLine().getStatusCode(); + HttpEntity entity1 = response.getEntity(); + responseBody = EntityUtils.toString(entity1);} + catch(Exception ex){ + resCode=500; + responseBody=ex.getMessage(); + } + return this; + } + + public void setHeaders(Header[] headers) { + for (Header header : headers) { + this.method.addHeader(header); + } + } + + public String getResponseBodyAsString() { + return responseBody; + } + + public int getReturnCode() { + return resCode; + } + + public String getReqBody() { + return reqBody; + } + + public void setReqBody(String body) { + this.reqBody = body; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getPemPath() { + return pemPath; + } + + public void setPemPath(String pemPath) { + this.pemPath = pemPath; + } + + public String getChefPath() { + return chefPath; + } + + public void setChefPath(String chefPath) { + this.chefPath = chefPath; + } + + public String getOrganizations() { + return organizations; + } + + public void setOrganizations(String organizations) { + this.organizations = organizations; + } +} diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefapi/Get.java b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefapi/Get.java new file mode 100644 index 000000000..add65f92e --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefapi/Get.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.chef.chefapi; + +import org.apache.http.client.methods.HttpGet; + +public class Get extends ApiMethod{ + + public Get(HttpGet method) { + super("GET"); + this.method = method; + } + +} diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefapi/Put.java b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefapi/Put.java new file mode 100644 index 000000000..597289809 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefapi/Put.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.chef.chefapi; + +import org.apache.http.client.methods.*; +import org.apache.http.entity.StringEntity; + +public class Put extends ApiMethod{ + + public Put(HttpRequestBase method) { + super("PUT"); + this.method = method; + } + + public ApiMethod body(String body){ + this.reqBody = body; + StringEntity params =new StringEntity (body,"UTF-8"); + params.setContentType("application/json"); + HttpPut put = (HttpPut) method; + put.setEntity(params); + return this; + } + +} diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefclient/ChefApiClient.java b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefclient/ChefApiClient.java new file mode 100644 index 000000000..f3cc44bb2 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefclient/ChefApiClient.java @@ -0,0 +1,91 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.chef.chefclient; +import org.apache.http.client.methods.*; +import org.openecomp.appc.adapter.chef.chefapi.*; + +public class ChefApiClient { + private String endpoint; + private String userId; + private String pemPath; + private String organizations; + + + + + /** + * + * @param userId user name correspond to the pem key + * @param pemPath path of the auth key + * @param endpoint chef api server address + */ + public ChefApiClient(String userId, String pemPath, String endpoint,String organizations){ + this.userId = userId; + this.pemPath = pemPath; + this.endpoint = endpoint; + this.organizations=organizations; + } + + /** + * + * @param path in the endpoint. e.g /clients + * @return + */ + public Get get(String path){ + Get get = new Get(new HttpGet(endpoint+path)); + get.setPemPath(pemPath); + get.setUserId(userId); + get.setOrganizations(organizations); + get.setChefPath(path); + return get; + } + + public Put put(String path){ + Put put = new Put(new HttpPut(endpoint+path)); + put.setPemPath(pemPath); + put.setUserId(userId); + put.setOrganizations(organizations); + put.setChefPath(path); + return put; + } +/* public Post post(String path){ + Post post = new Post(new PostMethod(endpoint+path)); + post.setPemPath(pemPath); + post.setUserId(userId); + return post; + } + + public Delete delete(String path){ + Delete del = new Delete(new DeleteMethod(endpoint+path)); + del.setPemPath(pemPath); + del.setUserId(userId); + return del; + } + + +*/ +/* public Header[] buildHeaders(){ + + return null; + } +*/ +} diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefclient/Utils.java b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefclient/Utils.java new file mode 100644 index 000000000..d814762f8 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefclient/Utils.java @@ -0,0 +1,105 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.chef.chefclient; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.KeyPair; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.Security; +import java.security.Signature; +import java.security.SignatureException; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openssl.PEMReader; +import org.bouncycastle.util.encoders.Base64; + +public class Utils { + private Utils(){} + + public static String sha1AndBase64(String inStr) { + MessageDigest md = null; + String outStr = null; + byte[] outbty = null; + try { + md = MessageDigest.getInstance("SHA-1"); + byte[] digest = md.digest(inStr.getBytes()); + outbty = Base64.encode(digest); + } catch (NoSuchAlgorithmException nsae) { + nsae.printStackTrace(); + } + return new String(outbty); + } + + public static String signWithRSA(String inStr, String pemPath) { + byte[] outStr = null; + BufferedReader br = null; + try { + br = new BufferedReader(new FileReader(pemPath)); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + Security.addProvider(new BouncyCastleProvider()); + try { + + KeyPair kp = (KeyPair) new PEMReader(br).readObject(); + PrivateKey privateKey = kp.getPrivate(); + Signature instance = Signature.getInstance("RSA"); + instance.initSign(privateKey); + instance.update(inStr.getBytes()); + + byte[] signature = instance.sign(); + outStr = Base64.encode(signature); + String tmp = new String(outStr); + } catch (InvalidKeyException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (SignatureException e) { + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return new String(outStr); + } + + public static String[] splitAs60(String inStr) { + int count = inStr.length() / 60; + String[] out = new String[count + 1]; + + for (int i = 0; i < count; i++) { + String tmp = inStr.substring(i * 60, i * 60 + 60); + out[i] = tmp; + } + if (inStr.length() > count * 60) { + String tmp = inStr.substring(count * 60, inStr.length()); + out[count] = tmp; + } + return out; + } + +} diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/impl/ChefAdapterImpl.java b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/impl/ChefAdapterImpl.java new file mode 100644 index 000000000..39447bb70 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/impl/ChefAdapterImpl.java @@ -0,0 +1,470 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.chef.impl; + +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.regex.Pattern; + +import org.glassfish.grizzly.http.util.HttpStatus; +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.chef.ChefAdapter; +import org.openecomp.appc.adapter.chef.chefapi.*; +import org.openecomp.appc.adapter.chef.chefclient.*; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.exceptions.UnknownProviderException; +import org.openecomp.appc.i18n.Msg; +import org.openecomp.appc.pool.Pool; +import org.openecomp.appc.pool.PoolExtensionException; +import org.openecomp.appc.util.StructuredPropertyHelper; +import org.openecomp.appc.util.StructuredPropertyHelper.Node; +import com.att.cdp.exceptions.ContextConnectionException; +import com.att.cdp.exceptions.ResourceNotFoundException; +import com.att.cdp.exceptions.TimeoutException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.pal.util.StringHelper; +import com.att.cdp.zones.ComputeService; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.ImageService; +import com.att.cdp.zones.Provider; +import com.att.cdp.zones.model.Image; +import com.att.cdp.zones.model.Server; +import com.att.cdp.zones.model.ServerBootSource; +import com.att.cdp.zones.model.Server.Status; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.slf4j.MDC; + +import java.net.InetAddress; +import java.util.Locale; +import java.util.UUID; + +import org.apache.http.*; +import org.apache.http.client.*; +import org.apache.http.client.methods.*; +import org.apache.http.impl.client.*; +import org.apache.http.util.EntityUtils; + +import static com.att.eelf.configuration.Configuration.*; + +import java.io.IOException; + +import java.net.InetAddress; +/** + * This class implements the {@link ChefAdapter} interface. This interface + * defines the behaviors that our service provides. + */ +public class ChefAdapterImpl implements ChefAdapter { + + /** + * The constant used to define the adapter name in the mapped diagnostic + * context + */ + + //chef server Initialize variable + public String clientName=""; + public String clientPrivatekey=""; + public String chefserver=""; + public String serverAddress=""; + public String organizations=""; + @SuppressWarnings("nls") + public static final String MDC_ADAPTER = "adapter"; + + /** + * The constant used to define the service name in the mapped diagnostic + * context + */ + @SuppressWarnings("nls") + public static final String MDC_SERVICE = "service"; + + /** + * The constant for the status code for a failed outcome + */ + @SuppressWarnings("nls") + public static final String OUTCOME_FAILURE = "failure"; + + /** + * The constant for the status code for a successful outcome + */ + @SuppressWarnings("nls") + public static final String OUTCOME_SUCCESS = "success"; + + /** + * A constant for the property token "provider" used in the structured + * property specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER = "provider"; + + /** + * A constant for the property token "identity" used in the structured + * property specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_IDENTITY = "identity"; + + /** + * A constant for the property token "name" used in the structured property + * specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_NAME = "name"; + + /** + * A constant for the property token "tenant" used in the structured + * property specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_TENANT = "tenant"; + + /** + * A constant for the property token "tenant name" used in the structured + * property specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_TENANT_NAME = "name"; + + /** + * A constant for the property token "password" used in the structured + * property specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_TENANT_PASSWORD = "password"; // NOSONAR + + /** + * A constant for the property token "userid" used in the structured + * property specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_TENANT_USERID = "userid"; + + /** + * A constant for the property token "type" used in the structured property + * specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_TYPE = "type"; + + /** + * The name of the service to restart a server + */ + @SuppressWarnings("nls") + public static final String PING_SERVICE = "pingServer"; + + /** + * The logger to be used + */ + private static final EELFLogger logger = EELFManager.getInstance().getLogger(ChefAdapterImpl.class); + + /** + * The constant for a left parenthesis + */ + private static final char LPAREN = '('; + + /** + * The constant for a new line control code + */ + private static final char NL = '\n'; + + /** + * The constant for a single quote + */ + private static final char QUOTE = '\''; + + /** + * The constant for a right parenthesis + */ + private static final char RPAREN = ')'; + + /** + * The constant for a space + */ + private static final char SPACE = ' '; + + /** + * A reference to the adapter configuration object. + */ + private Configuration configuration; + + /** + * A cache of providers that are predefined. + */ + // private Map<String /* provider name */, ProviderCache> providerCache; + + /** + * This default constructor is used as a work around because the activator + * wasnt getting called + */ + public ChefAdapterImpl() { + initialize(); + + } + + /** + * This constructor is used primarily in the test cases to bypass + * initialization of the adapter for isolated, disconnected testing + * + * @param initialize + * True if the adapter is to be initialized, can false if not + */ + public ChefAdapterImpl(boolean initialize) { + configuration = ConfigurationFactory.getConfiguration(); + if (initialize) { + initialize(); + + } + } + + /** + * @param props + * not used + */ + public ChefAdapterImpl(Properties props) { + initialize(); + + } + + public ChefAdapterImpl(String key) { + initialize(key); + + } + + /** + * Returns the symbolic name of the adapter + * + * @return The adapter name + * @see org.openecomp.appc.adapter.chef.ChefAdapter#getAdapterName() + */ + @Override + public String getAdapterName() { + return configuration.getProperty(Constants.PROPERTY_ADAPTER_NAME); + } + + private void X__________________________________X() { + } + + /** + * @see org.openecomp.appc.adapter.chef.ChefAdapter#evacuateServer(java.util.Map, + * org.openecomp.sdnc.sli.SvcLogicContext) + */ + + private void X___________________________________X() { + } + + /** + * @see org.openecomp.appc.adapter.chef.ProviderAdapter#rebuildServer(java.util.Map, + * org.openecomp.sdnc.sli.SvcLogicContext) + */ + + /** + * Send GET request to chef server + */ + + @SuppressWarnings("nls") + @Override + public void chefGet(Map<String, String> params, SvcLogicContext ctx) { + logger.info("chef get method"); + String chefAction= params.get("org.openecomp.appc.instance.chefAction"); + // logger.info(vm_url); + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + //should load pem from somewhere else + ChefApiClient cac = new ChefApiClient(clientName,clientPrivatekey,chefserver,organizations); + // need pass path into it + //"/nodes" + ApiMethod am = cac.get(chefAction); + am.execute(); + int code = am.getReturnCode(); + String message = am.getResponseBodyAsString(); + logger.info(code + " " + message); + chefServerResult(rc,Integer.toString(code),message); +/* if (code == 200) { + doSuccess(rc); + } else { + String errorcode=code+" "; + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, errorcode); + }*/ + + } + + /** + * Send PUT request to chef server + */ + + @SuppressWarnings("nls") + @Override + public void chefPut(Map<String, String> params, SvcLogicContext ctx) { + + //String tVmIp = params.get("org.openecomp.appc.instance.ip"); + //logger.info(tVmIp); + logger.info("chef PUT method"); + logger.info(clientName+" "+clientPrivatekey+" "+chefserver+" "+organizations); + //String CHEF_NODE_STR= params.get("org.openecomp.appc.instance.chefRequestBody"); + String chefAction= params.get("org.openecomp.appc.instance.chefAction"); + String runList= params.get("org.openecomp.appc.instance.runList"); + String attributes= params.get("org.openecomp.appc.instance.attributes"); + logger.info(attributes); + //attributes="\"reconfig-test\":{\"secret\":\"newpass2\"}"; + String CHEF_NODE_STR = "{\"json_class\":\"Chef::Node\",\"default\":{},\"chef_type\":\"node\",\"run_list\":[\""+runList+"\"],\"override\":{},\"automatic\":{},\"normal\":{"+attributes+"},\"name\":\"testnode\",\"chef_environment\":\"_default\"}"; + //String CHEF_NODE_STR = "{\"json_class\":\"Chef::Node\"}"; + // logger.info(vm_url); + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + //should load pem from somewhere else + ChefApiClient cac = new ChefApiClient(clientName,clientPrivatekey,chefserver,organizations); + + // need pass path into it + //"/nodes/testnode" + ApiMethod am = cac.put(chefAction).body(CHEF_NODE_STR); + am.execute(); + int code = am.getReturnCode(); + String message = am.getResponseBodyAsString(); + logger.info(code + " " + message); + chefServerResult(rc,Integer.toString(code),message); +/* if (code == 200) { + logger.info("chef PUT method success"); + doSuccess(rc); + } else { + String errorcode=code+" "; + logger.info("chef PUT method failure"); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, errorcode); + }*/ + + } + + + + /** + * Trigger target vm run chef + */ + + @SuppressWarnings("nls") + @Override + public void trigger(Map<String, String> params, SvcLogicContext ctx) { + logger.info("Run trigger method"); + String tVmIp = params.get("org.openecomp.appc.instance.ip"); + //String tUrl = "http://" + tVmIp; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + try { + HttpGet httpGet = new HttpGet(tVmIp); + HttpClient httpClient = HttpClients.createDefault(); + HttpResponse response = null; + response = httpClient.execute(httpGet); + int responseCode=response.getStatusLine().getStatusCode(); + HttpEntity entity = response.getEntity(); + String responseOutput=EntityUtils.toString(entity); + chefClientResult(rc,Integer.toString(responseCode),responseOutput); + doSuccess(rc); + } catch (Exception ex) { + doFailure(rc, 500 , ex.toString()); + } + } + + + + + @SuppressWarnings("static-method") + private void doFailure(RequestContext rc, int code, String message) { + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + String msg = (message == null) ? Integer.toString(code) : message; + if (msg.contains("\n")) { + msg = msg.substring(msg.indexOf("\n")); + } + + String status; + try { + status = Integer.toString(code); + } catch (Exception e) { + status = "500"; + } + svcLogic.setAttribute("org.openecomp.appc.chefAgent.code", status); + svcLogic.setAttribute("org.openecomp.appc.chefAgent.message", msg); + } + + /** + * @param rc + * The request context that manages the state and recovery of the + * request for the life of its processing. + */ + + @SuppressWarnings("static-method") + private void doSuccess(RequestContext rc) { + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + svcLogic.setAttribute("org.openecomp.appc.chefAgent.code", "200"); + } + + + @SuppressWarnings("static-method") + private void chefServerResult(RequestContext rc, String code ,String message) { + String msg = (message == null) ? " " : message; + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + svcLogic.setStatus(OUTCOME_SUCCESS); + svcLogic.setAttribute("org.openecomp.appc.chefServerResult.code", code); + svcLogic.setAttribute("org.openecomp.appc.chefServerResult.message", message); + } + + @SuppressWarnings("static-method") + private void chefClientResult(RequestContext rc, String code ,String message) { + String msg = (message == null) ? " " : message; + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + svcLogic.setStatus(OUTCOME_SUCCESS); + svcLogic.setAttribute("org.openecomp.appc.chefClientResult.code", code); + svcLogic.setAttribute("org.openecomp.appc.chefClientResult.message", message); + } + + /** + * initialize the provider adapter by building the context cache + */ + private void initialize() { + configuration = ConfigurationFactory.getConfiguration(); + //need to fetch data from appc configurator or form some file in the appc vms + clientName="testnode"; + clientPrivatekey="/etc/chef/client.pem"; + serverAddress="http://example.com"; + organizations="test"; + chefserver=serverAddress+"/organizations/"+organizations; + logger.info("Initialize Chef Adapter"); + } + + private void initialize(String key) { + configuration = ConfigurationFactory.getConfiguration(); + //need to fetch data from appc configurator or form some file in the appc vms + clientName="testnode"; + clientPrivatekey=key; + serverAddress="http://example.com"; + organizations="test"; + chefserver=serverAddress+"/organizations/"+organizations; + logger.info("Initialize Chef Adapter"); + } + +} diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/impl/RequestContext.java b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/impl/RequestContext.java new file mode 100644 index 000000000..b651ad0cf --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/impl/RequestContext.java @@ -0,0 +1,249 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.chef.impl; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.sdnc.sli.SvcLogicContext; + +/** + * This class is used to track and maintain recovery and time-to-live information for a request as it is being + * processed. + */ +public class RequestContext { + /** + * The number of seconds of wait time between successive attempts to connect to the provider. This is used to + * recover from provider outages or failures. It is not used to recover from logical errors, such as an invalid + * request, server not found, etc. + */ + private Integer retryDelay; + + /** + * The number of times we will attempt to connect to the provider. This is used to recover from provider outages or + * failures. It is not used to recover from logical errors, such as an invalid request, server not found, etc. + */ + private Integer retryLimit; + + /** + * The total time, in milliseconds, that the provider can have to process this request. If the accumulated time + * exceeds the time to live, then the request is failed with a timeout exception, regardless of the state of the + * provider. Note that the caller may supply this as a value in seconds, in which case it must be converted to + * milliseconds for the request context. + */ + private Long timeToLive; + + /** + * The accumulated time, in milliseconds, that has been used so far to process the request. This is compared to the + * time to live each time it is updated. If the accumulated time exceeds the time to live, then the request is + * failed with a timeout exception, regardless of the state of the provider. + */ + private long accumulatedTime; + + /** + * The total number of retries attempted so far + */ + private int attempt; + + /** + * The time when the stopwatch was started + */ + private long startTime = -1; + + /** + * The service logic (DG) context from the SLI + */ + private SvcLogicContext svcLogicContext; + + /** + * The configuration + */ + private Configuration configuration = ConfigurationFactory.getConfiguration(); + + /** + * Set to true whenever the retry limit has been exceeded, reset to false when reset() is called. + */ + private boolean retryFailed; + + /** + * Creates the request context + * + * @param context + * The service logic (SLI) context associated with the current DG + */ + public RequestContext(SvcLogicContext context) { + setSvcLogicContext(context); + } + + /** + * @return The retry delay, in seconds. If zero, then no retry is to be performed + */ + public int getRetryDelay() { + if (retryDelay == null) { + int value = configuration.getIntegerProperty(Constants.PROPERTY_RETRY_DELAY); + retryDelay = Integer.valueOf(value); + } + + return retryDelay.intValue(); + } + + /** + * This method is a helper that allows the caller to delay for the retry interval time and not have to handle the + * thread interruption, timer handling, etc. + */ + public void delay() { + long time = getRetryDelay() * 1000L; + long future = System.currentTimeMillis() + time; + if (time != 0) { + while (System.currentTimeMillis() < future && time > 0) { + try { + Thread.sleep(time); + } catch (InterruptedException e) { + /* + * This is rare, but it can happen if another thread interrupts us while we are sleeping. In that + * case, the thread is resumed before the delay time has actually expired, so re-calculate the + * amount of delay time needed and reenter the sleep until we get to the future time. + */ + time = future - System.currentTimeMillis(); + } + } + } + } + + /** + * @return The number of retries that are allowed per connection + */ + public int getRetryLimit() { + if (retryLimit == null) { + int value = configuration.getIntegerProperty(Constants.PROPERTY_RETRY_LIMIT); + retryLimit = Integer.valueOf(value); + } + + return retryLimit.intValue(); + } + + /** + * Check and count the connection attempt. + * + * @return True if the connection should be attempted. False indicates that the number of retries has been exhausted + * and it should NOT be attempted. + */ + public boolean attempt() { + if (retryFailed || attempt >= getRetryLimit()) { + retryFailed = true; + return false; + } + attempt++; + + return true; + } + + /** + * @return The number of retry attempts so far + */ + public int getAttempts() { + return attempt; + } + + /** + * @return True if the retry limit has been exceeded, false otherwise + */ + public boolean isFailed() { + return retryFailed; + } + + /** + * This method both checks the time to live to see if it has been exceeded and accumulates the total time used so + * far. + * <p> + * Each time this method is called it accumulates the total duration since the last time it was called to the total + * time accumulator. It then checks the total time to the time to live and if greater, it returns false. As long as + * the total time used is less than or equal to the time to live limit, the method returns true. It is important to + * call this method at the very beginning of the process so that all parts of the process are tracked. + * </p> + * + * @return True if the total time to live has not been exceeded. False indicates that the total time to live has + * been exceeded and no further processing should be performed. + */ + public boolean isAlive() { + long now = System.currentTimeMillis(); + if (startTime == -1) { + startTime = now; + return true; + } + accumulatedTime += (now - startTime); + startTime = now; + if (accumulatedTime > timeToLive) { + return false; + } + return true; + } + + /** + * @return The total amount of time used, in milliseconds. + */ + public long getTotalDuration() { + return accumulatedTime; + } + + /** + * This method is called to reset the retry counters. It has no effect on the time to live accumulator. + */ + public void reset() { + attempt = 0; + } + + /** + * Sets the time to live to the value, expressed in seconds + * + * @param time + * The time to live, in seconds + */ + public void setTimeToLiveSeconds(int time) { + setTimeToLiveMS(time * 1000L); + } + + /** + * Sets the time to live to the value, expressed in milliseconds + * + * @param time + * The time to live, in milliseconds + */ + public void setTimeToLiveMS(long time) { + this.timeToLive = time; + } + + /** + * @return The service logic context associated with this request + */ + public SvcLogicContext getSvcLogicContext() { + return svcLogicContext; + } + + /** + * @param svcLogicContext + * The service logic context to be associated with this request + */ + public void setSvcLogicContext(SvcLogicContext svcLogicContext) { + this.svcLogicContext = svcLogicContext; + } +} diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/impl/RequestFailedException.java b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/impl/RequestFailedException.java new file mode 100644 index 000000000..047eb8b1f --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/impl/RequestFailedException.java @@ -0,0 +1,243 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + +package org.openecomp.appc.adapter.chef.impl; + +import org.glassfish.grizzly.http.util.HttpStatus; +import com.att.cdp.zones.model.Server; + +/** + * This class is used to capture the exact cause and point of failure for the processing of a request. It is then used + * to encode the reason for the failure, status code, and anything else that needs to be captured and reported for + * diagnostic purposes. + */ +public class RequestFailedException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * The operation that was being requested or performed at the time of the failure. + */ + private String operation; + + /** + * A message that details the reason for the failure + */ + private String reason; + + /** + * The server that was being operated upon + */ + private Server server; + + /** + * The id of the server being operated upon if the server object is not available (such as the server was not found) + */ + private String serverId; + + /** + * The most appropriate Http Status code that reflects the error + */ + private HttpStatus status; + + /** + * + */ + public RequestFailedException() { + // intentionally empty + } + + /** + * @param message + * The error message + */ + public RequestFailedException(String message) { + super(message); + } + + /** + * Construct the request failed exception with the operation being performed, reason for the failure, http status + * code that is most appropriate, and the server we were processing. + * + * @param operation + * The operation being performed + * @param reason + * The reason that the operation was failed + * @param status + * The http status code that is most appropriate + * @param server + * The server that we were processing + */ + @SuppressWarnings("nls") + public RequestFailedException(String operation, String reason, HttpStatus status, Server server) { + super(operation + ":" + reason); + this.operation = operation; + this.reason = reason; + this.status = status; + this.server = server; + if (server != null) { + this.serverId = server.getId(); + } + } + + /** + * Construct the request failed exception with the operation being performed, reason for the failure, http status + * code that is most appropriate, and the server we were processing. + * + * @param ex + * The exception that we are wrapping + * @param operation + * The operation being performed + * @param reason + * The reason that the operation was failed + * @param status + * The http status code that is most appropriate + * @param server + * The server that we were processing + */ + @SuppressWarnings("nls") + public RequestFailedException(Throwable ex, String operation, String reason, HttpStatus status, Server server) { + super(operation + ":" + reason, ex); + this.operation = operation; + this.reason = reason; + this.status = status; + this.server = server; + if (server != null) { + this.serverId = server.getId(); + } + } + + /** + * @param message + * The error message + * @param cause + * A nested exception + */ + public RequestFailedException(String message, Throwable cause) { + super(message, cause); + } + + /** + * @param message + * The error message + * @param cause + * A nested exception + * @param enableSuppression + * whether or not suppression is enabled or disabled + * @param writableStackTrace + * whether or not the stack trace should be writable + */ + public RequestFailedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + /** + * @param cause + * the cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or unknown.) + */ + public RequestFailedException(Throwable cause) { + super(cause); + } + + /** + * @return The operation being performed + */ + public String getOperation() { + return operation; + } + + /** + * @return The reason for the failure + */ + public String getReason() { + return reason; + } + + /** + * @return The server being operated upon + */ + public Server getServer() { + return server; + } + + /** + * @return The id of the server being operated upon + */ + public String getServerId() { + return serverId; + } + + /** + * @return The status code from the operation + */ + public HttpStatus getStatus() { + return status; + } + + /** + * @param operation + * The operation being performed + */ + public void setOperation(String operation) { + this.operation = operation; + } + + /** + * @param reason + * The reason for the failure + */ + public void setReason(String reason) { + this.reason = reason; + } + + /** + * @param server + * The server being operated upon + */ + public void setServer(Server server) { + this.server = server; + if (server != null) { + setServerId(server.getId()); + } + } + + /** + * @param serverId + * The id of the server being operated upon + */ + public void setServerId(String serverId) { + this.serverId = serverId; + } + + /** + * @param status + * The status of the request + */ + public void setStatus(HttpStatus status) { + this.status = status; + } + +} diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/resources/client.pem b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/resources/client.pem new file mode 100644 index 000000000..1a7b1bc69 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/resources/client.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAr3R64/1Z99kPfW9WV88/Pwxf/23ySf2ud1N1tmIj1gZXzzLa +km92IB+MKuKwHYsB3vUVt7FXYLKC3iac4f/QsNy2ViTdvhBNcHhcDOL/xeaVmBUy +V5X5/XqYJnlY+A2C4MQ97lgiaBVg7sE7s7nfO2J57mOLRInSPXFRoBlWIiaLWA6A +TEnQBBf1gjdYo2O2iHmDJG4fpMCrhpuyoIbXs56czzAxu8ky5AAF+Z4AiZOWs2P9 +bVaG5ekLIuD0iXBzWF/oNlJ8LDxrdPLMwoMrqQ+P2fZpKROx11bXYp2InLIRoYKU +g9oZbKcnLtKYUmcgD0GfOiC9XgbZ98EaaeSRdwIDAQABAoIBAGq8pKogDWRvAzJe +0hsXNDWp1JiyjSwgDMwA1OKAL6bbMv4UxM1Cy4zdREsuns9KKng1huG6HBryXhTB +Tr1Z/94oVzBuuwsOJd4fCni4e7sr/KOJeZe44F0pAHifZ9V3esA8AiUGLuA86Tw2 +B5jdoYUh8mVo32dxpJnGX07TOwgIgqlIxDUcDt0b7hYyTZpRJyf2y3tCfvzD7IiU +XCHe7dg99gaJivrAOSZXRc8N+7oTWfjhfjIlZAUuzZgwQtzMVkNhV1ezXtdRIyBa +yiYhDD4Ksh4UXRHDoxYLor4mpMOVCqozs3WEW6ZSWG/n1lGSPH/PQvDLM+bNGNzz +PHkCicECgYEA3dGTZN1Dd4MaJHGp/D4lGUW8g9HO+WRMp8zXa/6pzhGWaD9SnN9v +7fxxkypCaLBYXDIWO4DAMtLJBgmbu2azRtMFdsjks6f8utTxweCFRyMy1Bv71X2h +/+AlflTgnnV3uUGNaUa69dnMwIqvgyd9puU/Tfw8XGUWG0Z5hl7h9yECgYEAyn3s +4neVEpCgxK18bhGPljw/NoR+c7NWu5UIXcj3k9t5z5ToqS5wtOCRUVXG5XjU+tHg +1KgYxULLwhhnjLfFDvxqIACK+ei+lFf5N+1EDYiPOV74XfahPMiq818ihYV7wtV8 +YPFeFU7kmwJr8nPymN1KyWRGric12aQpKmPLLZcCgYEAlmxYEw+FgBd08//ssXUH +PYMwGwh93lvpK+XatI7HYkpFAD7o7B8NzYrjDlSbIllsImGI+CMQs6aD0kdTx5sW +ulHCI9KKXVbvKVfc9ogmeZ5iCrtLZXTEFjxP0MMIbAzm+sd8eUcQ5EYl9vBVo5B1 +Qme2LVF/MX0Pp8F8CeZwQGECgYEAonVNbJTMgUyP77vQrO5h6QMFJFRAr8setvjm +8XefSn03yZeK4tFjk3rom/zZypmbJnDklTkYRotEtsCls3xtGYziCDLnTYGyBYpf +ZMNzafg6EKllUt3glsfYf9G//KgPl014sL514Vqehs72lFr6NDK3IcTWADttNORE +MsJF7JkCgYEAukPXhEO+0BBHNf/tBS4DhzVUn9t4js7vLsui+OpYTXkvnwLV/JRV +uyFRaqwrnuZn9gSdy77fSt49XlQHO4YTUz3+zeqrnpun58pR6lCmlAIRgJF8Ge98 +gHku/iQZjjeahwRkR6s5fNoZboYipkq4iNXWdTTy3uuLTK3Vy9MgG4M= +-----END RSA PRIVATE KEY----- diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..3d4f9b373 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,93 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# +# Default properties for the APP-C Provider Adapter +# +# ------------------------------------------------------------------------------------------------- +# +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + +appc.application.name=APPC + +# +# Define the message resource bundle name to be loaded +org.openecomp.appc.resources=org/openecomp/appc/i18n/MessageResources +# +# The name of the adapter. +org.openecomp.appc.provider.adaptor.name=org.openecomp.appc.appc_provider_adapter +# +# Set up the logging environment +# +org.openecomp.appc.logging.file=org/openecomp/appc/logback.xml +org.openecomp.appc.logging.path=${user.home};etc;../etc +org.openecomp.appc.logger=org.openecomp.appc +org.openecomp.appc.security.logger=org.openecomp.appc.security +# +# The minimum and maximum provider/tenant context pool sizes. Min=1 means that as soon +# as the provider/tenant is referenced a Context is opened and added to the pool. Max=0 +# means that the upper bound on the pool is unbounded. +org.openecomp.appc.provider.min.pool=1 +org.openecomp.appc.provider.max.pool=0 + +# +# The following properties are used to configure the retry logic for connection to the +# IaaS provider(s). The retry delay property is the amount of time, in seconds, the +# application waits between retry attempts. The retry limit is the number of retries +# that are allowed before the request is failed. +org.openecomp.appc.provider.retry.delay = 30 +org.openecomp.appc.provider.retry.limit = 10 + +# +# The trusted hosts list for SSL access when a certificate is not provided. +# +provider.trusted.hosts=* +# +# The amount of time, in seconds, to wait for a server state change (start->stop, stop->start, etc). +# If the server does not change state to a valid state within the alloted time, the operation +# fails. +org.openecomp.appc.server.state.change.timeout=300 +# +# The amount of time to wait, in seconds, between subsequent polls to the OpenStack provider +# to refresh the status of a resource we are waiting on. +# +org.openecomp.appc.openstack.poll.interval=20 +# +# The connection information to connect to the provider we are using. These properties +# are "structured" properties, in that the name is a compound name, where the nodes +# of the name can be ordered (1, 2, 3, ...). All of the properties with the same ordinal +# position are defining the same entity. For example, provider1.type and provider1.name +# are defining the same provider, whereas provider2.name and provider2.type are defining +# the values for a different provider. Any number of providers can be defined in this +# way. +# +# Don't change these 2 right now since they are hard coded in the DG +#provider1.type=appc +#provider1.name=appc + +#These you can change +#provider1.identity=appc +#provider1.tenant1.name=appc +#provider1.tenant1.userid=appc +#provider1.tenant1.password=appc diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/openecomp/appc/adapter/chef/impl/TestChefAdapterImpl.java b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/openecomp/appc/adapter/chef/impl/TestChefAdapterImpl.java new file mode 100644 index 000000000..da11eba4f --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/openecomp/appc/adapter/chef/impl/TestChefAdapterImpl.java @@ -0,0 +1,119 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.chef.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.chef.ChefAdapter; +import org.openecomp.appc.adapter.chef.impl.ChefAdapterImpl; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.exceptions.UnknownProviderException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.zones.ComputeService; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.ContextFactory; +import com.att.cdp.zones.model.Server; +import com.att.cdp.zones.model.Server.Status; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.slf4j.MDC; + +@Ignore +public class TestChefAdapterImpl { + + + private ChefAdapterImpl adapter; + + @SuppressWarnings("nls") + @BeforeClass + public static void once() throws NoSuchFieldException, SecurityException, NoSuchMethodException { + + } + + @Before + public void setup() throws IllegalArgumentException, IllegalAccessException { + + adapter = new ChefAdapterImpl(System.getProperty("user.dir")+"/src/main/resources/client.pem"); + } + + @Test + public void testChefGet() throws IOException, IllegalStateException, IllegalArgumentException, + ZoneException, APPCException { + + Map<String, String> params = new HashMap<>(); + params.put("org.openecomp.appc.instance.chefAction", "/nodes"); + + + SvcLogicContext svcContext = new SvcLogicContext(); + adapter.chefGet(params, svcContext); + String status=svcContext.getAttribute("org.openecomp.appc.chefServerResult.code"); + assertEquals("200",status); + + } + + @Test + public void testChefPut() throws IOException, IllegalStateException, IllegalArgumentException, + ZoneException, APPCException { + + Map<String, String> params = new HashMap<>(); + params.put("org.openecomp.appc.instance.chefAction", "/nodes/testnode"); + params.put("org.openecomp.appc.instance.runList", "recipe[commandtest]"); + params.put("org.openecomp.appc.instance.attributes", ""); + SvcLogicContext svcContext = new SvcLogicContext(); + adapter.chefPut(params, svcContext); + String status=svcContext.getAttribute("org.openecomp.appc.chefServerResult.code"); + assertEquals("200",status); + + } + + @Test + public void testTrigger() throws IOException, IllegalStateException, IllegalArgumentException, + ZoneException, APPCException { + + Map<String, String> params = new HashMap<>(); + params.put("org.openecomp.appc.instance.ip", "http://example.com/test"); + SvcLogicContext svcContext = new SvcLogicContext(); + adapter.trigger(params, svcContext); + String status=svcContext.getAttribute("org.openecomp.appc.chefAgent.code"); + assertEquals("200",status); + + } + + +} diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/openecomp/appc/adapter/chef/impl/client.pem b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/openecomp/appc/adapter/chef/impl/client.pem new file mode 100644 index 000000000..1a7b1bc69 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/openecomp/appc/adapter/chef/impl/client.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAr3R64/1Z99kPfW9WV88/Pwxf/23ySf2ud1N1tmIj1gZXzzLa +km92IB+MKuKwHYsB3vUVt7FXYLKC3iac4f/QsNy2ViTdvhBNcHhcDOL/xeaVmBUy +V5X5/XqYJnlY+A2C4MQ97lgiaBVg7sE7s7nfO2J57mOLRInSPXFRoBlWIiaLWA6A +TEnQBBf1gjdYo2O2iHmDJG4fpMCrhpuyoIbXs56czzAxu8ky5AAF+Z4AiZOWs2P9 +bVaG5ekLIuD0iXBzWF/oNlJ8LDxrdPLMwoMrqQ+P2fZpKROx11bXYp2InLIRoYKU +g9oZbKcnLtKYUmcgD0GfOiC9XgbZ98EaaeSRdwIDAQABAoIBAGq8pKogDWRvAzJe +0hsXNDWp1JiyjSwgDMwA1OKAL6bbMv4UxM1Cy4zdREsuns9KKng1huG6HBryXhTB +Tr1Z/94oVzBuuwsOJd4fCni4e7sr/KOJeZe44F0pAHifZ9V3esA8AiUGLuA86Tw2 +B5jdoYUh8mVo32dxpJnGX07TOwgIgqlIxDUcDt0b7hYyTZpRJyf2y3tCfvzD7IiU +XCHe7dg99gaJivrAOSZXRc8N+7oTWfjhfjIlZAUuzZgwQtzMVkNhV1ezXtdRIyBa +yiYhDD4Ksh4UXRHDoxYLor4mpMOVCqozs3WEW6ZSWG/n1lGSPH/PQvDLM+bNGNzz +PHkCicECgYEA3dGTZN1Dd4MaJHGp/D4lGUW8g9HO+WRMp8zXa/6pzhGWaD9SnN9v +7fxxkypCaLBYXDIWO4DAMtLJBgmbu2azRtMFdsjks6f8utTxweCFRyMy1Bv71X2h +/+AlflTgnnV3uUGNaUa69dnMwIqvgyd9puU/Tfw8XGUWG0Z5hl7h9yECgYEAyn3s +4neVEpCgxK18bhGPljw/NoR+c7NWu5UIXcj3k9t5z5ToqS5wtOCRUVXG5XjU+tHg +1KgYxULLwhhnjLfFDvxqIACK+ei+lFf5N+1EDYiPOV74XfahPMiq818ihYV7wtV8 +YPFeFU7kmwJr8nPymN1KyWRGric12aQpKmPLLZcCgYEAlmxYEw+FgBd08//ssXUH +PYMwGwh93lvpK+XatI7HYkpFAD7o7B8NzYrjDlSbIllsImGI+CMQs6aD0kdTx5sW +ulHCI9KKXVbvKVfc9ogmeZ5iCrtLZXTEFjxP0MMIbAzm+sd8eUcQ5EYl9vBVo5B1 +Qme2LVF/MX0Pp8F8CeZwQGECgYEAonVNbJTMgUyP77vQrO5h6QMFJFRAr8setvjm +8XefSn03yZeK4tFjk3rom/zZypmbJnDklTkYRotEtsCls3xtGYziCDLnTYGyBYpf +ZMNzafg6EKllUt3glsfYf9G//KgPl014sL514Vqehs72lFr6NDK3IcTWADttNORE +MsJF7JkCgYEAukPXhEO+0BBHNf/tBS4DhzVUn9t4js7vLsui+OpYTXkvnwLV/JRV +uyFRaqwrnuZn9gSdy77fSt49XlQHO4YTUz3+zeqrnpun58pR6lCmlAIRgJF8Ge98 +gHku/iQZjjeahwRkR6s5fNoZboYipkq4iNXWdTTy3uuLTK3Vy9MgG4M= +-----END RSA PRIVATE KEY----- diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/openecomp/appc/test/ExecutorHarness.java b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/openecomp/appc/test/ExecutorHarness.java new file mode 100644 index 000000000..fba794670 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/openecomp/appc/test/ExecutorHarness.java @@ -0,0 +1,179 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + +package org.openecomp.appc.test; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.openecomp.appc.test.InterceptLogger; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + +/** + * This class is used as a test harness to wrap the call to an executor node. + */ + +public class ExecutorHarness { + + /** + * The executor to be tested + */ + private SvcLogicJavaPlugin executor; + + /** + * The collection of all exec methods found on the class + */ + private Map<String, Method> methods; + + /** + * The field of the class being tested that contains the reference to the logger to be used. This is modified to + * point to our interception logger for the test. + */ + private Field contextLogger; + + /** + * The interception logger that buffers all messages logged and allows us to look at them as part of the test case. + */ + private InterceptLogger logger; + + /** + * Create the harness and initialize it + * + * @throws SecurityException + * If a security manager, s, is present and any of the following conditions is met: + * <ul> + * <li>invocation of s.checkMemberAccess(this, Member.DECLARED) denies access to the declared field</li> + * <li>the caller's class loader is not the same as or an ancestor of the class loader for the current + * class and invocation of s.checkPackageAccess() denies access to the package of this class</li> + * </ul> + * @throws NoSuchFieldException + * if a field with the specified name is not found. + * @throws IllegalAccessException + * if this Field object is enforcing Java language access control and the underlying field is either + * inaccessible or final. + * @throws IllegalArgumentException + * if the specified object is not an instance of the class or interface declaring the underlying field + * (or a subclass or implementor thereof), or if an unwrapping conversion fails. + */ + @SuppressWarnings("nls") + public ExecutorHarness() throws NoSuchFieldException, SecurityException, IllegalArgumentException, + IllegalAccessException { + methods = new HashMap<>(); + new SvcLogicContext(); + + Class<?> contextClass = SvcLogicContext.class; + contextLogger = contextClass.getDeclaredField("LOG"); + contextLogger.setAccessible(true); + logger = new InterceptLogger(); + contextLogger.set(null, logger); + } + + /** + * Convenience constructor + * + * @param executor + * The executor to be tested by the harness + * @throws SecurityException + * If a security manager, s, is present and any of the following conditions is met: + * <ul> + * <li>invocation of s.checkMemberAccess(this, Member.DECLARED) denies access to the declared field</li> + * <li>the caller's class loader is not the same as or an ancestor of the class loader for the current + * class and invocation of s.checkPackageAccess() denies access to the package of this class</li> + * </ul> + * @throws NoSuchFieldException + * if a field with the specified name is not found. + * @throws IllegalAccessException + * if this Field object is enforcing Java language access control and the underlying field is either + * inaccessible or final. + * @throws IllegalArgumentException + * if the specified object is not an instance of the class or interface declaring the underlying field + * (or a subclass or implementor thereof), or if an unwrapping conversion fails. + */ + public ExecutorHarness(SvcLogicJavaPlugin executor) throws NoSuchFieldException, SecurityException, + IllegalArgumentException, IllegalAccessException { + this(); + setExecutor(executor); + } + + /** + * @param executor + * The java plugin class to be executed + */ + public void setExecutor(SvcLogicJavaPlugin executor) { + this.executor = executor; + scanExecutor(); + } + + /** + * @return The java plugin class to be executed + */ + public SvcLogicJavaPlugin getExecutor() { + return executor; + } + + /** + * @return The set of all methods that meet the signature requirements + */ + public List<String> getExecMethodNames() { + List<String> names = new ArrayList<>(); + names.addAll(methods.keySet()); + return names; + } + + /** + * Returns an indication if the named method is a valid executor method that could be called from a DG execute node + * + * @param methodName + * The method name to be validated + * @return True if the method name meets the signature requirements, false if the method either does not exist or + * does not meet the requirements. + */ + public boolean isExecMethod(String methodName) { + return methods.containsKey(methodName); + } + + /** + * This method scans the executor class hierarchy to locate all methods that match the required signature of the + * executor and records these methods in a map. + */ + private void scanExecutor() { + methods.clear(); + Class<?> executorClass = executor.getClass(); + Method[] publicMethods = executorClass.getMethods(); + for (Method method : publicMethods) { + if (method.getReturnType().equals(Void.class)) { + Class<?>[] paramTypes = method.getParameterTypes(); + if (paramTypes.length == 2) { + if (Map.class.isAssignableFrom(paramTypes[0]) + && SvcLogicContext.class.isAssignableFrom(paramTypes[1])) { + methods.put(method.getName(), method); + } + } + } + } + } +} diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/openecomp/appc/test/InterceptLogger.java b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/openecomp/appc/test/InterceptLogger.java new file mode 100644 index 000000000..912ea5ceb --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/java/org/openecomp/appc/test/InterceptLogger.java @@ -0,0 +1,451 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + +package org.openecomp.appc.test; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Marker; + +import ch.qos.logback.classic.Level; + +/** + * This class is used as an intercept logger that can be used in testing to intercept and record all messages that are + * logged, thus allowing a junit test case to examine the log output and make assertions. + */ +public class InterceptLogger implements org.slf4j.Logger { + + /** + * This inner class represents an intercepted log event + */ + public class LogRecord { + private Level level; + private String message; + private long timestamp; + private Throwable t; + + public LogRecord(Level level, String message) { + setLevel(level); + setTimestamp(System.currentTimeMillis()); + setMessage(message); + } + + public LogRecord(Level level, String message, Throwable t) { + this(level, message); + setThrowable(t); + } + + /** + * @return the value of level + */ + public Level getLevel() { + return level; + } + + /** + * @return the value of message + */ + public String getMessage() { + return message; + } + + /** + * @return the value of timestamp + */ + public long getTimestamp() { + return timestamp; + } + + /** + * @param level + * the value for level + */ + public void setLevel(Level level) { + this.level = level; + } + + /** + * @param message + * the value for message + */ + public void setMessage(String message) { + this.message = message; + } + + /** + * @param timestamp + * the value for timestamp + */ + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + /** + * @return the value of t + */ + public Throwable getThrowable() { + return t; + } + + /** + * @param t + * the value for t + */ + public void setThrowable(Throwable t) { + this.t = t; + } + + } + + /** + * The list of all intercepted log events + */ + private List<LogRecord> events; + + /** + * Create the intercept logger + */ + public InterceptLogger() { + events = new ArrayList<LogRecord>(1000); + } + + /** + * @return Returns all intercepted log events + */ + public List<LogRecord> getLogRecords() { + return events; + } + + /** + * Clears all log events + */ + public void clear() { + events.clear(); + } + + @Override + public void debug(Marker marker, String msg) { + debug(msg); + } + + @Override + public void debug(Marker marker, String format, Object arg) { + debug(MessageFormat.format(format, arg)); + } + + @Override + public void debug(Marker marker, String format, Object... arguments) { + debug(MessageFormat.format(format, arguments)); + } + + @Override + public void debug(Marker marker, String format, Object arg1, Object arg2) { + debug(MessageFormat.format(format, arg1, arg2)); + } + + @Override + public void debug(Marker marker, String msg, Throwable t) { + debug(msg, t); + } + + @Override + public void debug(String msg) { + events.add(new LogRecord(Level.DEBUG, msg)); + } + + @Override + public void debug(String format, Object arg) { + events.add(new LogRecord(Level.DEBUG, MessageFormat.format(format, arg))); + } + + @Override + public void debug(String format, Object... arguments) { + events.add(new LogRecord(Level.DEBUG, MessageFormat.format(format, arguments))); + } + + @Override + public void debug(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.DEBUG, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void debug(String msg, Throwable t) { + events.add(new LogRecord(Level.DEBUG, msg, t)); + } + + @Override + public void error(Marker marker, String msg) { + error(msg); + } + + @Override + public void error(Marker marker, String format, Object arg) { + error(format, arg); + } + + @Override + public void error(Marker marker, String format, Object... arguments) { + error(format, arguments); + } + + @Override + public void error(Marker marker, String format, Object arg1, Object arg2) { + error(format, arg1, arg2); + } + + @Override + public void error(Marker marker, String msg, Throwable t) { + events.add(new LogRecord(Level.ERROR, msg, t)); + } + + @Override + public void error(String msg) { + events.add(new LogRecord(Level.ERROR, msg)); + } + + @Override + public void error(String format, Object arg) { + events.add(new LogRecord(Level.ERROR, MessageFormat.format(format, arg))); + } + + @Override + public void error(String format, Object... arguments) { + events.add(new LogRecord(Level.ERROR, MessageFormat.format(format, arguments))); + } + + @Override + public void error(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.ERROR, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void error(String msg, Throwable t) { + events.add(new LogRecord(Level.ERROR, msg, t)); + } + + @Override + public String getName() { + return null; + } + + @Override + public void info(Marker marker, String msg) { + info(msg); + } + + @Override + public void info(Marker marker, String format, Object arg) { + info(format, arg); + } + + @Override + public void info(Marker marker, String format, Object... arguments) { + info(format, arguments); + } + + @Override + public void info(Marker marker, String format, Object arg1, Object arg2) { + info(format, arg1, arg2); + } + + @Override + public void info(Marker marker, String msg, Throwable t) { + events.add(new LogRecord(Level.INFO, msg, t)); + } + + @Override + public void info(String msg) { + events.add(new LogRecord(Level.INFO, msg)); + } + + @Override + public void info(String format, Object arg) { + events.add(new LogRecord(Level.INFO, MessageFormat.format(format, arg))); + } + + @Override + public void info(String format, Object... arguments) { + events.add(new LogRecord(Level.INFO, MessageFormat.format(format, arguments))); + } + + @Override + public void info(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.INFO, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void info(String msg, Throwable t) { + events.add(new LogRecord(Level.INFO, msg, t)); + } + + @Override + public boolean isDebugEnabled() { + return true; + } + + @Override + public boolean isDebugEnabled(Marker marker) { + return true; + } + + @Override + public boolean isErrorEnabled() { + return true; + } + + @Override + public boolean isErrorEnabled(Marker marker) { + return true; + } + + @Override + public boolean isInfoEnabled() { + return true; + } + + @Override + public boolean isInfoEnabled(Marker marker) { + return true; + } + + @Override + public boolean isTraceEnabled() { + return true; + } + + @Override + public boolean isTraceEnabled(Marker marker) { + return true; + } + + @Override + public boolean isWarnEnabled() { + return true; + } + + @Override + public boolean isWarnEnabled(Marker marker) { + return true; + } + + @Override + public void trace(Marker marker, String msg) { + trace(msg); + } + + @Override + public void trace(Marker marker, String format, Object arg) { + trace(format, arg); + } + + @Override + public void trace(Marker marker, String format, Object... argArray) { + trace(format, argArray); + } + + @Override + public void trace(Marker marker, String format, Object arg1, Object arg2) { + trace(format, arg1, arg2); + } + + @Override + public void trace(Marker marker, String msg, Throwable t) { + trace(msg, t); + } + + @Override + public void trace(String msg) { + events.add(new LogRecord(Level.TRACE, msg)); + } + + @Override + public void trace(String format, Object arg) { + events.add(new LogRecord(Level.TRACE, MessageFormat.format(format, arg))); + } + + @Override + public void trace(String format, Object... arguments) { + events.add(new LogRecord(Level.TRACE, MessageFormat.format(format, arguments))); + } + + @Override + public void trace(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.TRACE, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void trace(String msg, Throwable t) { + events.add(new LogRecord(Level.TRACE, msg, t)); + } + + @Override + public void warn(Marker marker, String msg) { + warn(msg); + } + + @Override + public void warn(Marker marker, String format, Object arg) { + warn(format, arg); + } + + @Override + public void warn(Marker marker, String format, Object... arguments) { + warn(format, arguments); + } + + @Override + public void warn(Marker marker, String format, Object arg1, Object arg2) { + warn(format, arg1, arg2); + } + + @Override + public void warn(Marker marker, String msg, Throwable t) { + events.add(new LogRecord(Level.WARN, msg, t)); + } + + @Override + public void warn(String msg) { + events.add(new LogRecord(Level.WARN, msg)); + } + + @Override + public void warn(String format, Object arg) { + events.add(new LogRecord(Level.WARN, MessageFormat.format(format, arg))); + } + + @Override + public void warn(String format, Object... arguments) { + events.add(new LogRecord(Level.WARN, MessageFormat.format(format, arguments))); + } + + @Override + public void warn(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.WARN, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void warn(String msg, Throwable t) { + events.add(new LogRecord(Level.WARN, msg, t)); + } +} diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..5e55d6c59 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/test/resources/org/openecomp/appc/default.properties @@ -0,0 +1,108 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# +# Default properties for the APP-C Provider Adapter +# +# ------------------------------------------------------------------------------------------------- +# +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + +appc.application.name=APPC + +# +# Define the message resource bundle name to be loaded +org.openecomp.appc.resources=org/openecomp/appc/i18n/MessageResources +# +# The name of the adapter. +org.openecomp.appc.provider.adaptor.name=org.openecomp.appc.appc_provider_adapter +# +# Set up the logging environment +# +org.openecomp.appc.logging.file=org/openecomp/appc/logback.xml +org.openecomp.appc.logging.path=${user.home};etc;../etc +org.openecomp.appc.logger=org.openecomp.appc +org.openecomp.appc.security.logger=org.openecomp.appc.security +# +# The minimum and maximum provider/tenant context pool sizes. Min=1 means that as soon +# as the provider/tenant is referenced a Context is opened and added to the pool. Max=0 +# means that the upper bound on the pool is unbounded. +org.openecomp.appc.provider.min.pool=1 +org.openecomp.appc.provider.max.pool=0 + +# +# The following properties are used to configure the retry logic for connection to the +# IaaS provider(s). The retry delay property is the amount of time, in seconds, the +# application waits between retry attempts. The retry limit is the number of retries +# that are allowed before the request is failed. +org.openecomp.appc.provider.retry.delay = 30 +org.openecomp.appc.provider.retry.limit = 10 + +# +# The trusted hosts list for SSL access when a certificate is not provided. +# +provider.trusted.hosts=* +# +# The amount of time, in seconds, to wait for a server state change (start->stop, stop->start, etc). +# If the server does not change state to a valid state within the alloted time, the operation +# fails. +org.openecomp.appc.server.state.change.timeout=300 +# +# The amount of time to wait, in seconds, between subsequent polls to the OpenStack provider +# to refresh the status of a resource we are waiting on. +# +org.openecomp.appc.openstack.poll.interval=20 +# +# The connection information to connect to the provider we are using. These properties +# are "structured" properties, in that the name is a compound name, where the nodes +# of the name can be ordered (1, 2, 3, ...). All of the properties with the same ordinal +# position are defining the same entity. For example, provider1.type and provider1.name +# are defining the same provider, whereas provider2.name and provider2.type are defining +# the values for a different provider. Any number of providers can be defined in this +# way. +# + +# Don't change these 2 right now since they are hard coded in the DG +#provider1.type=appc +#provider1.name=appc + +#These you can change +#provider1.identity=appc +#provider1.tenant1.name=appc +#provider1.tenant1.userid=appc +#provider1.tenant1.password=appc + +# After a change to the provider make sure to recheck these values with an api call to provider1.identity/tokens +test.expected-regions=1 +test.expected-endpoints=1 + +#Your OpenStack IP +#test.ip=192.168.1.2 +# Your OpenStack Platform's Keystone Port (default is 5000) +#test.port=5000 +#test.tenantid=abcde12345fghijk6789lmnopq123rst +#test.vmid=abc12345-1234-5678-890a-abcdefg12345 +# Port 8774 below is default port for OpenStack's Nova API Service +#test.url=http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345 + diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-features/.gitignore b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-features/.gitignore new file mode 100644 index 000000000..615a76bbc --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-features/.gitignore @@ -0,0 +1,4 @@ +/target/ +/bin/ +/classes/ +/.settings/ diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-features/pom.xml b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-features/pom.xml new file mode 100644 index 000000000..62033e256 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-features/pom.xml @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-chef-adapter</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>appc-chef-adapter-features</artifactId> + <name>Chef Adaptor - Features</name> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-chef-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>features-mdsal</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </dependency> + + <!-- dependency for opendaylight-karaf-empty for use by testing --> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>opendaylight-karaf-empty</artifactId> + <type>zip</type> + </dependency> + +<!-- <dependency> --> +<!-- Required for launching the feature tests --> +<!-- <groupId>org.opendaylight.yangtools</groupId> --> +<!-- <artifactId>features-test</artifactId> --> +<!-- <scope>test</scope> --> +<!-- </dependency> --> + + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>features-yangtools</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <!-- launches the feature test, which validates that your karaf feature + can be installed inside of a karaf container. It doesn't validate that your + functionality works correctly, just that you have all of the dependent bundles + defined correctly. --> + <!-- <plugin> --> + <!-- <groupId>org.apache.maven.plugins</groupId> --> + <!-- <artifactId>maven-surefire-plugin</artifactId> --> + <!-- <version>2.16</version> --> + <!-- <configuration> --> + <!-- <systemPropertyVariables> --> + <!-- <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId> --> + <!-- <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId> --> + <!-- <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version> --> + <!-- </systemPropertyVariables> --> + <!-- <dependenciesToScan> --> + <!-- <dependency>org.opendaylight.yangtools:features-test</dependency> --> + <!-- </dependenciesToScan> --> + <!-- </configuration> --> + <!-- </plugin> --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-features/src/main/resources/features.xml b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-features/src/main/resources/features.xml new file mode 100644 index 000000000..6ae5fc736 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-features/src/main/resources/features.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="appc-chef-adapter-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + +<!-- <repository>mvn:org.opendaylight.mdsal/features-mdsal/${odl.mdsal.version}/xml/features</repository> --> + <repository>mvn:org.opendaylight.mdsal/features-mdsal/${features-mdsal.version}/xml/features</repository> + + <feature name='appc-chef-adapter' description="appc-chef-adapter" version='${project.version}'> + <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> + <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> + <feature>sdnc-sli</feature> + <bundle>mvn:org.openecomp.appc/appc-chef-adapter-bundle/${project.version}</bundle> + </feature> + +</features> diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-installer/.gitignore b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-installer/.gitignore new file mode 100644 index 000000000..731eb433c --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-installer/.gitignore @@ -0,0 +1,2 @@ +/target/ +/.settings/ diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-installer/pom.xml b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-installer/pom.xml new file mode 100644 index 000000000..ccecd4f99 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-installer/pom.xml @@ -0,0 +1,126 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-chef-adapter</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>appc-chef-adapter-installer</artifactId> + <name>Chef Adapter - Karaf Installer</name> + <packaging>pom</packaging> + <properties> + <application.name>appc-chef-adapter</application.name> + <features.boot>appc-chef-adapter</features.boot> + <features.repositories>mvn:org.openecomp.appc/appc-chef-adapter-features/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-chef-adapter-features</artifactId> + <classifier>features</classifier> + <type>xml</type> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-chef-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>false</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>true</attach> + <finalName>${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <excludeGroupIds>org.opendaylight</excludeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals> + <!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-installer/src/assembly/assemble_installer_zip.xml b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..9fbaad8c5 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>adapter</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..1ac5a82bc --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,47 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>adapter</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + +</assembly> diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-installer/src/main/resources/scripts/install-feature.sh b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..1d769fada --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/appc-chef-adapter-installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,40 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +#!/bin/bash + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -n -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot} diff --git a/app-c/appc/appc-adapters/appc-chef-adapter/pom.xml b/app-c/appc/appc-adapters/appc-chef-adapter/pom.xml new file mode 100644 index 000000000..d8e58e7d8 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-chef-adapter/pom.xml @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-adapters</artifactId> + <version>1.0.0</version> + </parent> + + <artifactId>appc-chef-adapter</artifactId> + <name>chef Adaptor</name> + <description>Abstraction to connect to and utilize the services of cloud providers such as OpenStack or VMWare.</description> + <packaging>pom</packaging> + + <reporting> + <plugins> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <additionalDependencies> + <additionalDependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4</artifactId> + <version>${antlr.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4-runtime</artifactId> + <version>4.3</version> + </additionalDependency> + </additionalDependencies> + </configuration> + <reportSets> + <reportSet> + <reports> + <report>javadoc-no-fork</report> + <report>test-javadoc-no-fork</report> + </reports> + </reportSet> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jxr-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-changelog-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>dual-report</id> + <configuration> + <type>range</type> + <range>30</range> + </configuration> + <reports> + <report>changelog</report> + <report>file-activity</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>taglist-maven-plugin</artifactId> + <version>2.4</version> + </plugin> + </plugins> + </reporting> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-chef-adapter-features</artifactId> + <classifier>features</classifier> + <type>xml</type> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-chef-adapter-provider</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + </dependencyManagement> + + <modules> + <module>appc-chef-adapter-bundle</module> + <module>appc-chef-adapter-features</module> + <module>appc-chef-adapter-installer</module> + </modules> +</project> diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/pom.xml b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/pom.xml new file mode 100644 index 000000000..8f0a2ec2f --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/pom.xml @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dmaap-adapter</artifactId> + <version>1.0.0</version> + </parent> + + <artifactId>appc-dmaap-adapter-bundle</artifactId> + <packaging>bundle</packaging> + <name>DMaaP Adapter - bundle</name> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-metric-bundle</artifactId> + <version>1.0.0</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <classifier>jar-with-dependencies</classifier> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>equinoxSDK381</groupId> + <artifactId>org.eclipse.osgi</artifactId> + </dependency> + + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + </dependency> + + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-core</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-annotations</artifactId> + </dependency> + + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-mockito</artifactId> + <version>1.6.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-core</artifactId> + </dependency> + <dependency> + <groupId>org.objenesis</groupId> + <artifactId>objenesis</artifactId> + <version>2.2</version> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-all</artifactId> + </dependency> + + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-junit4</artifactId> + <version>1.6.2</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + <exclusion> + <artifactId>slf4j-simple</artifactId> + <groupId>org.slf4j</groupId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>compile</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + <!-- DMaaP Client --> +<!-- <dependency> --> +<!-- <groupId>com.att.nsa</groupId> --> +<!-- <artifactId>dmaapClient</artifactId> --> +<!-- <version>${dmaap.client.version}</version> --> +<!-- </dependency> --> + + <dependency> + <groupId>org.json</groupId> + <artifactId>json</artifactId> + </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + </dependency> + </dependencies> + + + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>org.openecomp.appc.adapter.dmaap</Bundle-SymbolicName> + <Bundle-Activator>org.openecomp.appc.adapter.dmaap.AppcDmaapAdapterActivator</Bundle-Activator> + <Export-Package>org.openecomp.appc.adapter.dmaap.*</Export-Package> + <Export-Serice>org.openecomp.appc.adapter.dmaap.EventSender</Export-Serice> + <Import-Package>org.openecomp.appc.metricservice.*,com.att.nsa.*,org.openecomp.sdnc.sli.*,org.osgi.framework.*,!org.osgi.service.event.*,org.osgi.service.*,org.osgi.util.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.*,javax.naming.*,javax.crypto.*, com.sun.jersey.spi.container.servlet,org.eclipse.jetty.servlets</Import-Package> + <Embed-Dependency>*;scope=compile|runtime;artifactId=!appc-metric-bundle|sli-common|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis|pax-*</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Bundle-Blueprint>OSGI-INF/blueprint/blueprint.xml</Bundle-Blueprint> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/AppcDmaapAdapterActivator.java b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/AppcDmaapAdapterActivator.java new file mode 100644 index 000000000..98b8aa158 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/AppcDmaapAdapterActivator.java @@ -0,0 +1,113 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.dmaap; + +import org.openecomp.appc.configuration.ConfigurationFactory; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +import java.util.Properties; + +/** + * This activator is used to initialize and terminate the connection pool to one or more providers. + * <p> + * The CDP abstraction layer supports multiple types of providers, with each provider supporting multiple tenants. The + * "connection" to a specific tenant on a specific provider is represented by a "context" object. These context objects + * are authenticated to a specific tenant on the provider, but can be reused from one request to another. Contexts are + * slow to set up and are resource intensive, so they are cached. However, the contexts for a specific tenant on a + * specific provider must be cached separately. + * </p> + * <p> + * Activation of the bundle creates an empty cache which is organized first by provider type, then by tenant name, with + * the contents being an empty pool of contexts for that provider/tenant combination. The pool is created on first use, + * and retained for as long as the bundle is active. + * </p> + * <p> + * When the bundle is deactivated, the cache is torn down with all contexts being closed. + * </p> + */ +public class AppcDmaapAdapterActivator implements BundleActivator { + private ServiceRegistration registration = null; + + /** + * The logger to be used + */ + private static final EELFLogger LOG = EELFManager.getInstance().getLogger(AppcDmaapAdapterActivator.class); + + /** + * Called when this bundle is started so the Framework can perform the bundle-specific activities necessary to start + * this bundle. This method can be used to register services or to allocate any resources that this bundle needs. + * <p> + * This method must complete and return to its caller in a timely manner. + * </p> + * + * @param bundleContext + * The execution context of the bundle being started. + * @throws java.lang.Exception + * If this method throws an exception, this bundle is marked as stopped and the Framework will remove + * this bundle's listeners, unregister all services registered by this bundle, and release all services + * used by this bundle. + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(final BundleContext bundleContext) throws Exception { + LOG.info("Starting Bundle " + getName()); + + /* if (registration == null) { + Properties properties = ConfigurationFactory.getConfiguration().getProperties(); + registration = bundleContext.registerService(EventSender.class, new EventSenderImpl(properties), null); + }*/ + } + + /** + * Called when this bundle is stopped so the Framework can perform the bundle-specific activities necessary to stop + * the bundle. In general, this method should undo the work that the BundleActivator.start method started. There + * should be no active threads that were started by this bundle when this bundle returns. A stopped bundle must not + * call any Framework objects. + * <p> + * This method must complete and return to its caller in a timely manner. + * </p> + * + * @param ctx + * The execution context of the bundle being stopped. + * @throws java.lang.Exception + * If this method throws an exception, the bundle is still marked as stopped, and the Framework will + * remove the bundle's listeners, unregister all services registered by the bundle, and release all + * services used by the bundle. * + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext ctx) throws Exception { + /*if (this.registration != null) { + this.registration.unregister(); + }*/ + LOG.info("Stopped Bundle " + getName()); + } + + public String getName() { + return "DMaaP Adapter"; + } + +} diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/CallableConsumer.java b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/CallableConsumer.java new file mode 100644 index 000000000..7c282911d --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/CallableConsumer.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.dmaap; + +import java.util.List; +import java.util.concurrent.Callable; + +public class CallableConsumer implements Callable<List<String>> { + + private Consumer consumer; + + private int timeout = 15000; + private int limit = 1000; + + public CallableConsumer(Consumer c) { + this.consumer = c; + } + + public CallableConsumer(Consumer c, int waitMs, int fetchSize) { + this.consumer = c; + this.timeout = waitMs; + this.limit = fetchSize; + } + + @Override + public List<String> call() { + return consumer.fetch(timeout, limit); + } + + /** + * The maximum amount of time to keep a connection alive. Currently is set to waitMs + 10s + * + * @return An integer representing the maximum amount of time to keep this thread alive + */ + public int getMaxLife() { + return 10000 + timeout; + } + +} diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/CommonHttpClient.java b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/CommonHttpClient.java new file mode 100644 index 000000000..654ec6f7f --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/CommonHttpClient.java @@ -0,0 +1,105 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.dmaap; + +import java.net.URI; + +import org.apache.commons.codec.binary.Base64; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.config.RequestConfig.Builder; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; + +public class CommonHttpClient { + + public static final int HTTPS_PORT = 3905; + + private String AUTH_STR; + + protected void setBasicAuth(String username, String password) { + if (username != null && password != null) { + String plain = String.format("%s:%s", username, password); + AUTH_STR = Base64.encodeBase64String(plain.getBytes()); + } else { + AUTH_STR = null; + } + } + + public HttpGet getReq(URI uri, int timeoutMs) throws Exception { + HttpGet out = (uri == null) ? new HttpGet() : new HttpGet(uri); + if (AUTH_STR != null) { + out.setHeader("Authorization", String.format("Basic %s", AUTH_STR)); + } + out.setConfig(getConfig(timeoutMs)); + return out; + } + + public HttpPost postReq(String url) throws Exception { + HttpPost out = (url == null) ? new HttpPost() : new HttpPost(url); + if (AUTH_STR != null) { + out.setHeader("Authorization", String.format("Basic %s", AUTH_STR)); + } + out.setConfig(getConfig(0)); + return out; + } + + private RequestConfig getConfig(int timeoutMs) { + Builder builder = RequestConfig.custom(); + builder.setSocketTimeout(timeoutMs + 5000); + return builder.build(); + } + + public CloseableHttpClient getClient() { + return getClient(false); + } + + public CloseableHttpClient getClient(boolean useHttps) { + return HttpClientBuilder.create().build(); + } + + public String formatHostString(String host) { + return formatHostString(host, host.contains(String.valueOf(HTTPS_PORT))); + } + + public String formatHostString(String host, boolean useHttps) { + // Trim trailing slash + String out = host.endsWith("/") ? host.substring(0, host.length() - 1) : host; + + boolean hasProto = out.startsWith("http"); + boolean hasPort = out.contains(":"); + + // Add protocol + if (!hasProto) { + out = String.format("%s%s", (useHttps) ? "https://" : "http://", out); + } + + // Add port + if (!hasPort) { + out = String.format("%s:%d", out, (useHttps) ? 3905 : 3904); + } + + return out; + + } +} diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/Consumer.java b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/Consumer.java new file mode 100644 index 000000000..32034e5fb --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/Consumer.java @@ -0,0 +1,68 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.dmaap; + +import java.util.List; + +public interface Consumer { + + /** + * Gets a batch of messages from the topic. Defaults to 1000 messages with 15s wait for messages if empty. + * + * @return A list of strings representing the messages pulled from the topic. + */ + public List<String> fetch(); + + /** + * Gets a batch of messages from the topic. + * + * @param waitMs + * The amount of time to wait in milliseconds if the topic is empty for data to be written. Should be no + * less than 15000ms to prevent too many requests + * @param limit + * The amount of messages to fetch + * @return A list of strings representing the messages pulled from the topic. + */ + public List<String> fetch(int waitMs, int limit); + + /** + * Updates the api credentials for making authenticated requests + * + * @param apiKey + * The public key to authenticate with + * @param apiSecret + * The secret key to authenticate with + */ + public void updateCredentials(String apiKey, String apiSecret); + + // TODO - Implement once Cambria allows you to set outside of constructor + // public void setFilter(String filter); + + /** + * Creates a dmaap client using a https connection + * + * @param yes + * True if https should be used, false otherwise + */ + public void useHttps(boolean yes); + +} diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/DmaapConsumer.java b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/DmaapConsumer.java new file mode 100644 index 000000000..6e16d896b --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/DmaapConsumer.java @@ -0,0 +1,163 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.dmaap; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import org.apache.http.HttpEntity; +import org.apache.http.NameValuePair; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.json.JSONArray; + +public class DmaapConsumer extends CommonHttpClient implements Consumer { + + private static final EELFLogger LOG = EELFManager.getInstance().getLogger(DmaapConsumer.class); + + // Default values + private static final int DEFAULT_TIMEOUT_MS = 15000; + private static final int DEFAULT_LIMIT = 1000; + private static final String HTTPS_PORT = ":3905"; + private static final String URL_TEMPLATE = "%s/events/%s/%s/%s"; + + private List<String> urls; + private String filter; + + private boolean useHttps = false; + + public DmaapConsumer(Collection<String> hosts, String topicName, String consumerName, String consumerId) { + this(hosts, topicName, consumerName, consumerId, null); + } + + public DmaapConsumer(Collection<String> hosts, String topicName, String consumerName, String consumerId, + String filter) { + this(hosts, topicName, consumerName, consumerId, filter, null, null); + } + + public DmaapConsumer(Collection<String> hosts, String topicName, String consumerName, String consumerId, + String filter, String user, String password) { + urls = new ArrayList<String>(); + for (String host : hosts) { + urls.add(String.format(URL_TEMPLATE, formatHostString(host), topicName, consumerName, consumerId)); + } + this.filter = filter; + updateCredentials(user, password); + } + + @Override + public void updateCredentials(String user, String pass) { + LOG.debug(String.format("Setting auth to %s for %s", user, this.toString())); + this.setBasicAuth(user, pass); + } + + @Override + public List<String> fetch(int waitMs, int limit) { + LOG.debug(String.format("Fetching up to %d records with %dms wait on %s", limit, waitMs, this.toString())); + List<String> out = new ArrayList<String>(); + try { + List<NameValuePair> urlParams = new ArrayList<NameValuePair>(); + urlParams.add(new BasicNameValuePair("timeout", String.valueOf(waitMs))); + urlParams.add(new BasicNameValuePair("limit", String.valueOf(limit))); + if (filter != null) { + urlParams.add(new BasicNameValuePair("filter", filter)); + } + + URIBuilder builder = new URIBuilder(urls.get(0)); + builder.setParameters(urlParams); + + URI uri = builder.build(); + LOG.info(String.format("GET %s", uri)); + HttpGet request = getReq(uri, waitMs); + CloseableHttpResponse response = getClient().execute(request); + + int httpStatus = response.getStatusLine().getStatusCode(); + HttpEntity entity = response.getEntity(); + String body = (entity != null) ? EntityUtils.toString(entity) : null; + + LOG.debug(String.format("Request to %s completed with status %d and a body size of %s", uri, httpStatus, + (body != null ? body.length() : "null"))); + + response.close(); + if (httpStatus == 200 && body != null) { + JSONArray json = new JSONArray(body); + LOG.info(String.format("Got %d messages from DMaaP", json.length())); + for (int i = 0; i < json.length(); i++) { + out.add(json.getString(i)); + } + } else { + LOG.error(String.format("Did not get 200 from DMaaP. Got %d - %s", httpStatus, body)); + sleep(waitMs); + } + } catch (Exception e) { + if (urls.size() > 1) { + String failedUrl = urls.remove(0); + urls.add(failedUrl); + LOG.debug(String.format("Moving host %s to the end of the pool. New primary host is %s", failedUrl, + urls.get(0))); + } + LOG.error(String.format("Got exception while querying DMaaP. Message: %s", e.getMessage()), e); + sleep(waitMs); + } + + return out; + } + + @Override + public List<String> fetch() { + return fetch(DEFAULT_TIMEOUT_MS, DEFAULT_LIMIT); + } + + @Override + public String toString() { + String hostStr = (urls == null && !urls.isEmpty()) ? "N/A" : urls.get(0); + return String.format("Consumer listening to [%s]", hostStr); + } + + @Override + public void useHttps(boolean yes) { + useHttps = yes; + } + + private void sleep(int ms) { + LOG.info(String.format("Sleeping for %ds after failed request", ms / 1000)); + try { + Thread.sleep(ms); + } catch (InterruptedException e1) { + LOG.error("Interrupted while sleeping"); + } + } + + public void close(){ + //not used yet + } + +} diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/DmaapDestination.java b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/DmaapDestination.java new file mode 100644 index 000000000..efbe194ba --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/DmaapDestination.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.dmaap; + +public enum DmaapDestination { + DCAE +} diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/DmaapProducer.java b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/DmaapProducer.java new file mode 100644 index 000000000..6845177b1 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/DmaapProducer.java @@ -0,0 +1,133 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.dmaap; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; + +public class DmaapProducer extends CommonHttpClient implements Producer { + + private static final EELFLogger LOG = EELFManager.getInstance().getLogger(DmaapProducer.class); + + private static final String CONTENT_TYPE = "application/cambria"; + private static final String URL_TEMPLATE = "%s/events/%s"; + + private List<String> hosts; + private Set<String> topics; + + private boolean useHttps = false; + + public DmaapProducer(Collection<String> urls, String topicName) { + hosts = new ArrayList<String>(); + topics = new HashSet<String>(); + topics.add(topicName); + + for (String host : urls) { + hosts.add(formatHostString(host)); + } + } + + public DmaapProducer(Collection<String> urls, Set<String> topicNames) { + hosts = new ArrayList<String>(); + topics = topicNames; + + for (String host : urls) { + hosts.add(formatHostString(host)); + } + } + + @Override + public void updateCredentials(String user, String pass) { + LOG.debug(String.format("Setting auth to %s for %s", user, this.toString())); + this.setBasicAuth(user, pass); + } + + @Override + public boolean post(String partition, String data) { + int sent = 0; + try { + HttpPost request = postReq(null); + request.setHeader("Content-Type", CONTENT_TYPE); + request.setEntity(new StringEntity(bodyLine(partition, data))); + + for (String topic : topics) { + String uriStr = String.format(URL_TEMPLATE, hosts.get(0), topic); + try { + request.setURI(new URI(uriStr)); + CloseableHttpResponse response = getClient().execute(request); + if (response.getStatusLine().getStatusCode() == 200) { + sent++; + } + response.close(); + } catch (Exception sendEx) { + LOG.error(String.format("Failed to send message to %s. Reason: %s", uriStr, sendEx.getMessage()), + sendEx); + if (hosts.size() > 1) { + String failedUrl = hosts.remove(0); + hosts.add(failedUrl); + LOG.debug(String.format("Moving host %s to the end of the pool. New primary host is %s", + failedUrl, hosts.get(0))); + } + } + } + } catch (Exception buildEx) { + LOG.error( + String.format("Failed to build request with string [%s]. Message not sent to any topic. Reason: %s", + data, buildEx.getMessage()), + buildEx); + } + return sent == topics.size(); + } + + @Override + public void useHttps(boolean yes) { + useHttps = yes; + } + + /** + * Format the body for the application/cambria content type with no partitioning. + * + * @param msg + * The message body to format + * @return A string in the application/cambria content type + */ + private String bodyLine(String partition, String msg) { + String p = (partition == null) ? "" : partition; + String m = (msg == null) ? "" : msg; + return String.format("%d.%d.%s%s", p.length(), m.length(), p, m); + } + + public void close(){ + //not used yet + } +} diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/EventSender.java b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/EventSender.java new file mode 100644 index 000000000..7d4a7c090 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/EventSender.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.dmaap; + +import java.util.Map; + +import org.openecomp.appc.adapter.dmaap.event.EventMessage; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + + +public interface EventSender extends SvcLogicJavaPlugin{ + boolean sendEvent(DmaapDestination destination, EventMessage msg); + boolean sendEvent(DmaapDestination destination, Map<String, String> params, SvcLogicContext ctx) throws APPCException; +} diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/Manager.java b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/Manager.java new file mode 100644 index 000000000..183e618ba --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/Manager.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.dmaap; + +import java.util.Set; + +public interface Manager { + + /** + * Updates the api credentials for making authenticated requests + * + * @param apiKey + * The public key to authenticate with + * @param apiSecret + * The secret key to authenticate with + */ + public void updateCredentials(String apiKey, String apiSecret); + + /** + * Return a set of strings representing topics that the user can see + * + * @return A set of strings with topic names or an empty set if no topics are visible + */ + public Set<String> getTopics(); + +} diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/Producer.java b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/Producer.java new file mode 100644 index 000000000..f19c516be --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/Producer.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.dmaap; + +public interface Producer { + + public boolean post(String partition, String data); + + /** + * Updates the api credentials for making authenticated requests + * + * @param apiKey + * The public key to authenticate with + * @param apiSecret + * The secret key to authenticate with + */ + public void updateCredentials(String apiKey, String apiSecret); + + /** + * Creates a dmaap client using a https connection + * + * @param yes + * True if https should be used, false otherwise + */ + public void useHttps(boolean yes); + +} diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/event/EventHeader.java b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/event/EventHeader.java new file mode 100644 index 000000000..dd951fe37 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/event/EventHeader.java @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.dmaap.event; + +import com.fasterxml.jackson.annotation.JsonProperty; + + +public class EventHeader { + + @JsonProperty("eventTime") + private final String eventTime; + + @JsonProperty("apiVer") + private final String apiVer; + + @JsonProperty("eventId") + private final String eventId; + + public EventHeader(String eventTime, String apiVer, String eventId) { + this.eventTime = eventTime; + this.apiVer = apiVer; + this.eventId = eventId; + } + + public String getEventTime() { + return eventTime; + } + + public String getApiVer() { + return apiVer; + } + + public String getEventId() { + return eventId; + } + + @Override + public String toString() { + return "EventHeader{" + + "eventTime='" + eventTime + '\'' + + ", apiVer='" + apiVer + '\'' + + ", eventId='" + eventId + '\'' + + '}'; + } +} diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/event/EventMessage.java b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/event/EventMessage.java new file mode 100644 index 000000000..af5cff2f9 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/event/EventMessage.java @@ -0,0 +1,99 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.dmaap.event; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion; + +import java.io.IOException; +import java.io.Serializable; + +/* + { + "EventHeader": { + "eventTime": "2016-03-15T10:59:33.79Z", + "apiVer": "1.01", + "EventId": "<ECOMP_EVENT_ID>", + }, + "EventStatus": { + "code": "NNN", + "reason": "A reason" + } + } +*/ + + + + +@JsonSerialize(include = Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class EventMessage implements Serializable { + + private static final long serialVersionUID = 1L; + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + @JsonProperty("eventHeader") + private EventHeader eventHeader; + @JsonProperty("eventStatus") + private EventStatus eventStatus; + + public EventMessage(EventHeader eventHeader, EventStatus eventStatus) { + this.eventHeader = eventHeader; + this.eventStatus = eventStatus; + } + + public EventHeader getEventHeader() { + return eventHeader; + } + + public void setEventHeader(EventHeader eventHeader) { + this.eventHeader = eventHeader; + } + + public EventStatus getEventStatus() { + return eventStatus; + } + + public void setEventStatus(EventStatus eventStatus) { + this.eventStatus = eventStatus; + } + + public String toJson() { + try { + return OBJECT_MAPPER.writeValueAsString(this); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public String toString() { + return "EventMessage{" + + "eventHeader=" + eventHeader + + ", eventStatus=" + eventStatus + + '}'; + } +} diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/event/EventStatus.java b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/event/EventStatus.java new file mode 100644 index 000000000..f5d7a59d4 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/event/EventStatus.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.dmaap.event; + +import com.fasterxml.jackson.annotation.JsonProperty; + + +public class EventStatus { + + @JsonProperty("code") + private final Integer code; + + @JsonProperty("reason") + private final String reason; + + public EventStatus(Integer code, String aReason) { + this.code = code; + reason = aReason; + } + + + public Integer getCode() { + return code; + } + + public String getReason() { + return reason; + } + + @Override + public String toString() { + return "EventStatus{" + + "code=" + code + + ", reason='" + reason + '\'' + + '}'; + } +} diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/impl/EventSenderImpl.java b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/impl/EventSenderImpl.java new file mode 100644 index 000000000..0f7d40f5b --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/impl/EventSenderImpl.java @@ -0,0 +1,143 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.dmaap.impl; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +import org.openecomp.appc.adapter.dmaap.EventSender; +import org.openecomp.appc.adapter.dmaap.Producer; +import org.openecomp.appc.adapter.dmaap.DmaapDestination; +import org.openecomp.appc.adapter.dmaap.event.EventHeader; +import org.openecomp.appc.adapter.dmaap.event.EventMessage; +import org.openecomp.appc.adapter.dmaap.event.EventStatus; +import org.openecomp.appc.adapter.dmaap.DmaapProducer; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.SvcLogicContext; + + +public class EventSenderImpl implements EventSender +{ + private static final EELFLogger LOG = EELFManager.getInstance().getLogger(EventSenderImpl.class); + public static final String EVENT_TOPIC_WRITE = "event.topic.write"; + public static final String EVENT_CLIENT_KEY = "event.client.key"; + public static final String EVENT_CLIENT_SECRET = "event.client.secret"; + public static final String EVENT_POOL_MEMBERS = "event.pool.members"; + + private static Configuration configuration = ConfigurationFactory.getConfiguration(); + + private Map<String,Producer> producerMap = new ConcurrentHashMap<>(); + + public Map<String, Producer> getProducerMap() { + return producerMap; + } + + public void setProducerMap(Map<String, Producer> producerMap) { + this.producerMap = producerMap; + } + + public EventSenderImpl(){ + + } + + public void initialize(){ + Properties properties = configuration.getProperties(); + String writeTopic; + String apiKey; + String apiSecret; + final List<String> pool = new ArrayList<>(); + + for(DmaapDestination destination:DmaapDestination.values()){ + writeTopic = properties.getProperty(destination + "." + EVENT_TOPIC_WRITE); + apiKey = properties.getProperty(destination + "." + EVENT_CLIENT_KEY); + apiSecret = properties.getProperty(destination + "." + EVENT_CLIENT_SECRET); + String hostNames = properties.getProperty(destination + "." + EVENT_POOL_MEMBERS); + + if (hostNames != null && !hostNames.isEmpty()) { + LOG.debug(String.format("hostNames = %s, taken from property: %s", hostNames, destination + "." + EVENT_POOL_MEMBERS)); + Collections.addAll(pool, hostNames.split(",")); + } + + LOG.debug(String.format("pool = %s, taken from property: %s", pool, destination + "." + EVENT_POOL_MEMBERS)); + LOG.debug(String.format("writeTopic = %s, taken from property: %s", writeTopic, destination + "." + EVENT_TOPIC_WRITE)); + LOG.debug(String.format("apiKey = %s, taken from property: %s", apiKey, destination + "." + EVENT_CLIENT_KEY)); + Producer producer = new DmaapProducer(pool, writeTopic); + + if (apiKey != null && apiSecret != null) { + producer.updateCredentials(apiKey, apiSecret); + } + + for (String url : pool) { + if (url.contains("3905") || url.contains("https")) { + LOG.debug("Producer should use HTTPS"); + producer.useHttps(true); + break; + } + } + producerMap.put(destination.toString(),producer); + } + + } + + @Override + public boolean sendEvent(DmaapDestination destination,EventMessage msg) { + String jsonStr = msg.toJson(); + String id = msg.getEventHeader().getEventId(); + LOG.info(String.format("Posting Message [%s - %s]", id, jsonStr)); + Producer producer = producerMap.get(destination.toString()); + return producer.post(id, jsonStr); + } + + @Override + public boolean sendEvent(DmaapDestination destination,Map<String, String> params, SvcLogicContext ctx) throws APPCException { + + if (params == null) { + String message = "Parameters map is empty (null)"; + LOG.error(message); + throw new APPCException(message); + } + String eventTime = new Date(System.currentTimeMillis()).toString(); + String apiVer = params.get("apiVer"); + String eventId = params.get("eventId"); + String reason = params.get("reason"); + String entityId=params.get("entityId"); + if(entityId!=null){ + reason=reason+"("+entityId+")"; + } + Integer code = Integer.getInteger(params.get("code"), 500); + + if (eventTime == null || apiVer == null || eventId == null || reason == null) { + String message = String.format("Missing input parameters: %s", params); + LOG.error(message); + throw new APPCException(message); + } + EventMessage dmaapEventMessage = new EventMessage( + new EventHeader(eventTime, apiVer, eventId), + new EventStatus(code, reason)); + + return sendEvent(destination,dmaapEventMessage); + } +} diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..a8caf666f --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + <bean id="eventSenderBean" class="org.openecomp.appc.adapter.dmaap.impl.EventSenderImpl" + init-method="initialize" scope="singleton"> + </bean> + + <service id="eventSenderService" interface="org.openecomp.appc.adapter.dmaap.EventSender" ref="eventSenderBean" /> + +</blueprint> diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..5ac029b85 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,25 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# ${user.home} usually goes to /root if instantiation uses the appc-docker approach + +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/dmaap/TestAppcDmaapAdapterActivator.java b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/dmaap/TestAppcDmaapAdapterActivator.java new file mode 100644 index 000000000..e97014198 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/dmaap/TestAppcDmaapAdapterActivator.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.dmaap; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import org.junit.Test; +import org.openecomp.appc.adapter.dmaap.AppcDmaapAdapterActivator; + +public class TestAppcDmaapAdapterActivator { + + // TODO commented out to allow build to pass, need to analyze and fix +// @Test + public void coverage() { + // This does nothing since the activator does nothing + AppcDmaapAdapterActivator appc = new AppcDmaapAdapterActivator(); + try { + appc.start(null); + appc.stop(null); + + } catch (Exception e) { + fail("Got exception when starting stopping. " + e.getMessage()); + } + assertNotNull(appc.getName()); + } + +} diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/resources/DCAEResponse.txt b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/resources/DCAEResponse.txt new file mode 100644 index 000000000..0d7ea2afa --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/resources/DCAEResponse.txt @@ -0,0 +1,18 @@ +{ +"requestTime": "0000-00-00 14:31:19.653787", +"policyVersion": "13", +"VMName": "123", +"from": "test", +"msgOid": ".1.3.6.1.4.1.193.183.4.1.3.5.1.4", +"trapID": "1234567", +"requestClient": "test", +"message": "Abnormal condition detected", +"time": "123567890", +"policyName": "RESTART", +"trapIDOID": ".1.3.6.1.4.1.193.183.4.1.3.5.1.3", +"request": "Restart", +"OPS_CL_timer": "15", +"nOID": ".1.3.6.1.4.1.193.183.4.2.0.4", +"AgentAddress": "192.168.1.2", +"vmOID": ".1.3.6.1.4.1.193.183.4.1.2.1", +}
\ No newline at end of file diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..3692c92aa --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/resources/org/openecomp/appc/default.properties @@ -0,0 +1,36 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +org.openecomp.appc.bootstrap.file=test.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + +# Properties commented out below are provided in appc.properties +#poolMembers=<DMAAP_IP>:3904 +#event.pool.members=<DMAAP_IP>:3904 + +topic.read=APPC-CL +topic.read.timeout=5 +topic.write=APPC-CL +event.topic.write=APPC-CL +client.name=APPC-CLIENT-DMAAP-ADAPTER-TEST +client.name.id=0 + +metric.enabled=false; diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/resources/test.properties b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/resources/test.properties new file mode 100644 index 000000000..1cadceee8 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/resources/test.properties @@ -0,0 +1,35 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# Properties commented out below are provided in appc.properties +#poolMembers=<DMAAP_IP>:3904 +#event.pool.members=<DMAAP_IP>:3904 + +topic.read=APPC-TEST2 +topic.read.timeout=5 +topic.write=APPC-TEST2 +event.topic.write=APPC-TEST2 +client.name=APPC-CLIENT-DMAAP-ADAPTER-TEST +client.name.id=0 +#client.key=fakeKey +#client.secret=fakeSecret +#event.client.key=fakeKey +#event.client.secret=fakeSecret diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-features/pom.xml b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-features/pom.xml new file mode 100644 index 000000000..042b96d16 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-features/pom.xml @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-dmaap-adapter</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>appc-dmaap-adapter-features</artifactId> + <name>DMaaP Adapter - Features</name> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dmaap-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>features-mdsal</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </dependency> + + <!-- dependency for opendaylight-karaf-empty for use by testing --> +<!-- <dependency> --> +<!-- <groupId>org.opendaylight.controller</groupId> --> +<!-- <artifactId>opendaylight-karaf-empty</artifactId> --> +<!-- <type>zip</type> --> +<!-- </dependency> --> + +<!-- <dependency> --> + <!-- Required for launching the feature tests --> +<!-- <groupId>org.opendaylight.yangtools</groupId> --> +<!-- <artifactId>features-test</artifactId> --> +<!-- <scope>test</scope> --> +<!-- </dependency> --> + + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>features-yangtools</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <!-- launches the feature test, which validates that your karaf feature + can be installed inside of a karaf container. It doesn't validate that your + functionality works correctly, just that you have all of the dependent bundles + defined correctly. --> + <!-- <plugin> --> + <!-- <groupId>org.apache.maven.plugins</groupId> --> + <!-- <artifactId>maven-surefire-plugin</artifactId> --> + <!-- <version>2.16</version> --> + <!-- <configuration> --> + <!-- <systemPropertyVariables> --> + <!-- <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId> --> + <!-- <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId> --> + <!-- <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version> --> + <!-- </systemPropertyVariables> --> + <!-- <dependenciesToScan> --> + <!-- <dependency>org.opendaylight.yangtools:features-test</dependency> --> + <!-- </dependenciesToScan> --> + <!-- </configuration> --> + <!-- </plugin> --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-features/src/main/resources/features.xml b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-features/src/main/resources/features.xml new file mode 100644 index 000000000..33b9ee3a7 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-features/src/main/resources/features.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="appc-dmaap-adapter-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + +<!-- <repository>mvn:org.opendaylight.mdsal/features-mdsal/${odl.mdsal.version}/xml/features</repository> --> + <repository>mvn:org.opendaylight.mdsal/features-mdsal/${features-mdsal.version}/xml/features</repository> + + <feature name='appc-dmaap-adapter' description="appc-dmaap-adapter" version='${project.version}'> + <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> +<!-- <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> --> + <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> +<!-- <feature version="${sdnctl.sli.version}">sdnc-sli</feature> --> + <bundle>mvn:org.openecomp.appc/appc-dmaap-adapter-bundle/${project.version}</bundle> + + </feature> + +</features> diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/.gitignore b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/.gitignore new file mode 100644 index 000000000..731eb433c --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/.gitignore @@ -0,0 +1,2 @@ +/target/ +/.settings/ diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/pom.xml b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/pom.xml new file mode 100644 index 000000000..8faef202f --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-dmaap-adapter</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>appc-dmaap-adapter-installer</artifactId> + <name>dMaaP Adapter - Karaf Installer</name> + <packaging>pom</packaging> + + <properties> + <application.name>appc-dmaap-adapter</application.name> + <features.boot>appc-dmaap-adapter</features.boot> + <features.repositories>mvn:org.openecomp.appc/appc-dmaap-adapter-features/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dmaap-adapter-features</artifactId> + <version>${project.version}</version> + <classifier>features</classifier> + <type>xml</type> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dmaap-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>false</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>true</attach> + <finalName>${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <excludeGroupIds>org.opendaylight</excludeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals> + <!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/src/assembly/assemble_installer_zip.xml b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..9fbaad8c5 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>adapter</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..1ac5a82bc --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,47 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>adapter</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + +</assembly> diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/src/main/resources/scripts/install-feature.sh b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..1d769fada --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,40 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +#!/bin/bash + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -n -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot} diff --git a/app-c/appc/appc-adapters/appc-dmaap-adapter/pom.xml b/app-c/appc/appc-adapters/appc-dmaap-adapter/pom.xml new file mode 100644 index 000000000..8979e354e --- /dev/null +++ b/app-c/appc/appc-adapters/appc-dmaap-adapter/pom.xml @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-adapters</artifactId> + <version>1.0.0</version> + </parent> + + <artifactId>appc-dmaap-adapter</artifactId> + <name>DMaaP Adapter</name> + <description>Adapter to read and write messages on the Universal Event Broker (Cambria).</description> + <packaging>pom</packaging> + + <reporting> + <plugins> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <additionalDependencies> + <additionalDependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4</artifactId> + <version>${antlr.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4-runtime</artifactId> + <version>4.3</version> + </additionalDependency> + </additionalDependencies> + </configuration> + <reportSets> + <reportSet> + <reports> + <report>javadoc-no-fork</report> + <report>test-javadoc-no-fork</report> + </reports> + </reportSet> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jxr-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-changelog-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>dual-report</id> + <configuration> + <type>range</type> + <range>30</range> + </configuration> + <reports> + <report>changelog</report> + <report>file-activity</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>taglist-maven-plugin</artifactId> + <version>2.4</version> + </plugin> + </plugins> + </reporting> + + <modules> + <module>appc-dmaap-adapter-bundle</module> + <module>appc-dmaap-adapter-features</module> + <module>appc-dmaap-adapter-installer</module> + </modules> +</project> diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/.gitignore b/app-c/appc/appc-adapters/appc-iaas-adapter/.gitignore new file mode 100644 index 000000000..d027396de --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/.gitignore @@ -0,0 +1 @@ +/.settings/ diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/.gitignore b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/.gitignore new file mode 100644 index 000000000..b33175423 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/.gitignore @@ -0,0 +1,4 @@ +/bin/ +/target/ +/.settings/ +/build/ diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/pom.xml b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/pom.xml new file mode 100644 index 000000000..967c34858 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/pom.xml @@ -0,0 +1,222 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-iaas-adapter</artifactId> + <version>1.0.0</version> + </parent> + + <artifactId>appc-iaas-adapter-bundle</artifactId> + <packaging>bundle</packaging> + <name>IaaS Adapter - bundle</name> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + <classifier>jar-with-dependencies</classifier> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>javax</groupId> + <artifactId>javaee-api</artifactId> + <version>7.0</version> + </dependency> + + <dependency> + <groupId>com.att.cdp</groupId> + <artifactId>cdp-pal-common</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>com.att.cdp</groupId> + <artifactId>cdp-pal-openstack</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>javax.ws.rs</groupId> + <artifactId>javax.ws.rs-api</artifactId> + </dependency> + + <!-- Jersey support needed for OpenStack connector and API version logic --> + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-client</artifactId> + </dependency> + + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-json</artifactId> + </dependency> + + <dependency> + <groupId>javax.xml.bind</groupId> + <artifactId>jaxb-api</artifactId> + <version>2.1</version> + </dependency> + + <dependency> + <groupId>javax.xml</groupId> + <artifactId>jaxp-api</artifactId> + <version>1.4.2</version> + </dependency> + + <!-- Needed to run test cases --> + <dependency> + <groupId>org.glassfish.jersey.core</groupId> + <artifactId>jersey-common</artifactId> + <version>2.9.1</version> + </dependency> + + <dependency> + <groupId>org.codehaus.jackson</groupId> + <artifactId>jackson-jaxrs</artifactId> + <version>1.9.12</version> + </dependency> + + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>4.5.1</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>compile</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>equinoxSDK381</groupId> + <artifactId>org.eclipse.osgi</artifactId> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + </dependency> + + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + <version>5.1.31</version> + <type>jar</type> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>com.vmware</groupId> + <artifactId>vijava</artifactId> + <version>5.1</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>xerces</groupId> + <artifactId>xerces</artifactId> + <version>2.4.0</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore</artifactId> + <version>${apache.httpcomponents.version}</version> + </dependency> + + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>1.2</version> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>appc-iaas-adapter</Bundle-SymbolicName> + <Bundle-Activator>org.openecomp.appc.adapter.iaas.AppcProviderAdapterActivator</Bundle-Activator> + <Export-Package>org.openecomp.appc.adapter.iaas</Export-Package> + <Import-Package>org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.bind.*,javax.naming.*</Import-Package> + <Embed-Dependency>*;scope=compile|runtime;artifactId=!sli-common|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + + <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation> + </configuration> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>NonSlowTests</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <excludedGroups>org.openecomp.appc.adapter.iaas.impl.TestProviderAdapterImpl</excludedGroups> + </configuration> + </plugin> + </plugins> + </build> + </profile> + </profiles> +</project> diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/AppcProviderAdapterActivator.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/AppcProviderAdapterActivator.java new file mode 100644 index 000000000..fa60c67a9 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/AppcProviderAdapterActivator.java @@ -0,0 +1,143 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.iaas; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.impl.ProviderAdapterImpl; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.i18n.Msg; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +/** + * This activator is used to initialize and terminate the connection pool to one or more providers. + * <p> + * The CDP abstraction layer supports multiple types of providers, with each provider supporting multiple tenants. The + * "connection" to a specific tenant on a specific provider is represented by a "context" object. These context objects + * are authenticated to a specific tenant on the provider, but can be reused from one request to another. Contexts are + * slow to set up and are resource intensive, so they are cached. However, the contexts for a specific tenant on a + * specific provider must be cached separately. + * </p> + * <p> + * Activation of the bundle creates an empty cache which is organized first by provider type, then by tenant name, with + * the contents being an empty pool of contexts for that provider/tenant combination. The pool is created on first use, + * and retained for as long as the bundle is active. + * </p> + * <p> + * When the bundle is deactivated, the cache is torn down with all contexts being closed. + * </p> + */ +public class AppcProviderAdapterActivator implements BundleActivator { + + /** + * The bundle registration + */ + private ServiceRegistration registration = null; + + /** + * The reference to the actual implementation object that implements the services + */ + private ProviderAdapter adapter; + + /** + * The logger to be used + */ + // private static final Logger LOG = LoggerFactory.getLogger(AppcProviderAdapterActivator.class); + private static final EELFLogger logger = EELFManager.getInstance().getLogger(AppcProviderAdapterActivator.class); + + /** + * The configuration object used to configure this bundle + */ + private Configuration configuration; + + /** + * Called when this bundle is started so the Framework can perform the bundle-specific activities necessary to start + * this bundle. This method can be used to register services or to allocate any resources that this bundle needs. + * <p> + * This method must complete and return to its caller in a timely manner. + * </p> + * + * @param context + * The execution context of the bundle being started. + * @throws java.lang.Exception + * If this method throws an exception, this bundle is marked as stopped and the Framework will remove + * this bundle's listeners, unregister all services registered by this bundle, and release all services + * used by this bundle. + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + logger.info("Starting bundle " + getName()); + + configuration = ConfigurationFactory.getConfiguration(); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.COMPONENT_INITIALIZING, appName, "IAAS adapter"); + adapter = new ProviderAdapterImpl(configuration.getProperties()); + if (registration == null) { + logger.info(Msg.REGISTERING_SERVICE, appName, adapter.getAdapterName(), + ProviderAdapter.class.getSimpleName()); + registration = context.registerService(ProviderAdapter.class, adapter, null); + } + + logger.info(Msg.COMPONENT_INITIALIZED, appName, "IAAS adapter"); + } + + /** + * Called when this bundle is stopped so the Framework can perform the bundle-specific activities necessary to stop + * the bundle. In general, this method should undo the work that the BundleActivator.start method started. There + * should be no active threads that were started by this bundle when this bundle returns. A stopped bundle must not + * call any Framework objects. + * <p> + * This method must complete and return to its caller in a timely manner. + * </p> + * + * @param context + * The execution context of the bundle being stopped. + * @throws java.lang.Exception + * If this method throws an exception, the bundle is still marked as stopped, and the Framework will + * remove the bundle's listeners, unregister all services registered by the bundle, and release all + * services used by the bundle. * + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + logger.info("Stopping bundle " + getName()); + + if (registration != null) { + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.COMPONENT_TERMINATING, appName, "IAAS adapter"); + logger.info(Msg.UNREGISTERING_SERVICE, appName, adapter.getAdapterName()); + registration.unregister(); + registration = null; + logger.info(Msg.COMPONENT_TERMINATED, appName, "IAAS adapter"); + } + } + + public String getName() { + return "APPC IaaS adapter"; + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/ProviderAdapter.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/ProviderAdapter.java new file mode 100644 index 000000000..f7a8b30ed --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/ProviderAdapter.java @@ -0,0 +1,294 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.iaas; + +import java.util.Map; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.exceptions.UnknownProviderException; +import com.att.cdp.zones.model.Image; +import com.att.cdp.zones.model.Server; +import com.att.cdp.zones.model.Stack; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + +/** + * This interface defines the operations that the provider adapter exposes. + * <p> + * This interface defines static constant property values that can be used to configure the adapter. These constants are + * prefixed with the name PROPERTY_ to indicate that they are configuration properties. These properties are read from + * the configuration file for the adapter and are used to define the providers, identity service URLs, and other + * information needed by the adapter to interface with an IaaS provider. + * </p> + */ +public interface ProviderAdapter extends SvcLogicJavaPlugin { + + /** + * The type of provider to be accessed to locate and operate on a virtual machine instance. This is used to load the + * correct provider support through the CDP IaaS abstraction layer and can be OpenStackProvider, BareMetalProvider, + * or any other supported provider type. + */ + static final String PROPERTY_PROVIDER_TYPE = "org.openecomp.appc.provider.type"; + + /** + * The adapter maintains a cache of providers organized by the name of the provider, not its type. This is + * equivalent to the system or installation name. All regions within the same installation are assumed to be the + * same type. + */ + static final String PROPERTY_PROVIDER_NAME = "org.openecomp.appc.provider.name"; + + /** + * The fully-qualified URL of the instance to be manipulated as it is known to the provider. + */ + static final String PROPERTY_INSTANCE_URL = "org.openecomp.appc.instance.url"; + + /** + * The fully-qualified URL of the instance to be manipulated as it is known to the provider. + */ + static final String PROPERTY_IDENTITY_URL = "org.openecomp.appc.identity.url"; + /** + * heat stack id to perform operation on stack + */ + static final String PROPERTY_STACK_ID = "org.openecomp.appc.stack.id"; + + static final String PROPERTY_SNAPSHOT_ID = "snapshot.id"; + + static final String PROPERTY_INPUT_SNAPSHOT_ID = "org.openecomp.appc.snapshot.id"; + + static final String DG_OUTPUT_PARAM_NAMESPACE = "output."; + + /** + * This method is used to restart an existing virtual machine given the fully qualified URL of the machine. + * <p> + * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters + * passed to the method are passed as properties in a map. This method expects the following properties to be + * defined: + * <dl> + * <dt>org.openecomp.appc.provider.type</dt> + * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS + * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported + * provider types are legal.</dd> + * <dt>org.openecomp.appc.instance.url</dt> + * <dd>The fully qualified URL of the instance to be restarted, as it is known to the provider (i.e., the self-link + * URL of the server)</dd> + * </dl> + * </p> + * + * @param properties + * A map of name-value pairs that supply the parameters needed by this method. The properties needed are + * defined above. + * @param context + * The service logic context of the graph being executed. + * @return The <code>Server</code> object that represents the VM being restarted. The returned server object can be + * inspected for the final state of the server once the restart has been completed. The method does not + * return until the restart has either completed or has failed. + * @throws APPCException + * If the server cannot be restarted for some reason + */ + Server restartServer(Map<String, String> properties, SvcLogicContext context) throws APPCException; + + /** + * This method is used to stop the indicated server + * <p> + * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters + * passed to the method are passed as properties in a map. This method expects the following properties to be + * defined: + * <dl> + * <dt>org.openecomp.appc.provider.type</dt> + * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS + * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported + * provider types are legal.</dd> + * <dt>org.openecomp.appc.instance.url</dt> + * <dd>The fully qualified URL of the instance to be stopped, as it is known to the provider (i.e., the self-link + * URL of the server)</dd> + * </dl> + * </p> + * + * @param properties + * A map of name-value pairs that supply the parameters needed by this method. The properties needed are + * defined above. + * @param context + * The service logic context of the graph being executed. + * @return The <code>Server</code> object that represents the VM being stopped. The returned server object can be + * inspected for the final state of the server once the stop has been completed. The method does not return + * until the stop has either completed or has failed. + * @throws APPCException + * If the server cannot be stopped for some reason + */ + Server stopServer(Map<String, String> properties, SvcLogicContext context) throws APPCException; + + /** + * This method is used to start the indicated server + * <p> + * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters + * passed to the method are passed as properties in a map. This method expects the following properties to be + * defined: + * <dl> + * <dt>org.openecomp.appc.provider.type</dt> + * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS + * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported + * provider types are legal.</dd> + * <dt>org.openecomp.appc.instance.url</dt> + * <dd>The fully qualified URL of the instance to be started, as it is known to the provider (i.e., the self-link + * URL of the server)</dd> + * </dl> + * </p> + * + * @param properties + * A map of name-value pairs that supply the parameters needed by this method. The properties needed are + * defined above. + * @param context + * The service logic context of the graph being executed. + * @return The <code>Server</code> object that represents the VM being started. The returned server object can be + * inspected for the final state of the server once the start has been completed. The method does not return + * until the start has either completed or has failed. + * @throws APPCException + * If the server cannot be started for some reason + */ + Server startServer(Map<String, String> properties, SvcLogicContext context) throws APPCException; + + /** + * This method is used to rebuild the indicated server + * <p> + * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters + * passed to the method are passed as properties in a map. This method expects the following properties to be + * defined: + * <dl> + * <dt>org.openecomp.appc.provider.type</dt> + * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS + * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported + * provider types are legal.</dd> + * <dt>org.openecomp.appc.instance.url</dt> + * <dd>The fully qualified URL of the instance to be rebuilt, as it is known to the provider (i.e., the self-link + * URL of the server)</dd> + * </dl> + * </p> + * + * @param properties + * A map of name-value pairs that supply the parameters needed by this method. The properties needed are + * defined above. + * @param context + * The service logic context of the graph being executed. + * @return The <code>Server</code> object that represents the VM being rebuilt. The returned server object can be + * inspected for the final state of the server once the rebuild has been completed. The method does not + * return until the rebuild has either completed or has failed. + * @throws APPCException + * If the server cannot be rebuilt for some reason + */ + Server rebuildServer(Map<String, String> properties, SvcLogicContext context) throws APPCException; + + /** + * This method is used to terminate the indicated server + * <p> + * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters + * passed to the method are passed as properties in a map. This method expects the following properties to be + * defined: + * <dl> + * <dt>org.openecomp.appc.provider.type</dt> + * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS + * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported + * provider types are legal.</dd> + * <dt>org.openecomp.appc.instance.url</dt> + * <dd>The fully qualified URL of the instance to be terminate, as it is known to the provider (i.e., the self-link + * URL of the server)</dd> + * </dl> + * </p> + * + * @param properties + * A map of name-value pairs that supply the parameters needed by this method. The properties needed are + * defined above. + * @param context + * The service logic context of the graph being executed. + * @return The <code>Server</code> object that represents the VM being rebuilt. The returned server object can be + * inspected for the final state of the server once the rebuild has been completed. The method does not + * return until the rebuild has either completed or has failed. + * @throws APPCException + * If the server cannot be terminate for some reason + */ + Server terminateServer(Map<String, String> properties, SvcLogicContext context) throws APPCException; + + /** + * Returns the symbolic name of the adapter + * + * @return The adapter name + */ + String getAdapterName(); + + Server evacuateServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + Server migrateServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + Server vmStatuschecker(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + Stack terminateStack(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + Stack snapshotStack(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + Stack restoreStack(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + /** + * This method is used to do the lookup of the indicated server + * <p> + * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters + * passed to the method are passed as properties in a map. This method expects the following properties to be + * defined: + * <dl> + * <dt>org.openecomp.appc.provider.type</dt> + * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS + * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported + * provider types are legal.</dd> + * <dt>org.openecomp.appc.instance.url</dt> + * <dd>The fully qualified URL of the instance to be lookup, as it is known to the provider (i.e., the self-link URL + * of the server)</dd> + * </dl> + * </p> + * + * @param properties + * A map of name-value pairs that supply the parameters needed by this method. The properties needed are + * defined above. + * @param context + * The service logic context of the graph being executed. + * @return The <code>Server</code> object that represents the VM being rebuilt. The returned server object can be + * inspected for the final state of the server once the rebuild has been completed. The method does not + * return until the rebuild has either completed or has failed. + * @throws APPCException + * If the server cannot be found for some reason + */ + Server lookupServer(Map<String, String> properties, SvcLogicContext context) throws APPCException; + + /** + * The + * + * @param params + * A map of name-value pairs that supply the parameters needed by this method. The properties needed are + * defined above. + * @param ctx + * The service logic context of the graph being executed. + * @return The <code>Image</code> object that represents the VM being restarted. The returned server object can be + * inspected for the final state of the server once the restart has been completed. The method does not + * return until the restart has either completed or has failed. + * @throws APPCException + * If the server cannot be restarted for some reason + */ + Image createSnapshot(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/IdentityURL.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/IdentityURL.java new file mode 100644 index 000000000..e9391fcb8 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/IdentityURL.java @@ -0,0 +1,120 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.iaas.impl; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * This class is used to parse the VM URL returned from OpenStack and extract all of the constituent parts. + */ +public class IdentityURL { + /** + * The regular expression pattern used to parse the URL. Capturing groups are used to identify and extract the + * various component parts of the URL. + */ + private static Pattern pattern = Pattern.compile("(\\p{Alnum}+)://([^/:]+)(?::([0-9]+))?/(v[0-9\\.]+)/?"); + + /** + * The URL scheme or protocol, such as HTTP or HTTPS + */ + private String scheme; + + /** + * The host name or ip address + */ + private String host; + + /** + * The port number, or null if no port is defined + */ + private String port; + + /** + * The version of the service + */ + private String version; + + /** + * A private default constructor prevents instantiation by any method other than the factory method + * + * @see #parseURL(String) + */ + private IdentityURL() { + + } + + /** + * This static method is used to parse the provided server URL string and return a parse results object (VMURL) + * which represents the state of the parse. + * + * @param serverUrl + * The server URL to be parsed + * @return The VMURL parse results object, or null if the URL was not valid or null. + */ + public static IdentityURL parseURL(String serverUrl) { + IdentityURL obj = null; + if (serverUrl != null) { + Matcher matcher = pattern.matcher(serverUrl.trim()); + if (matcher.matches()) { + obj = new IdentityURL(); + obj.scheme = matcher.group(1); + obj.host = matcher.group(2); + obj.port = matcher.group(3); + obj.version = matcher.group(4); + } + } + + return obj; + } + + /** + * @return The URL scheme + */ + public String getScheme() { + return scheme; + } + + /** + * @return The URL host + */ + public String getHost() { + return host; + } + + /** + * @return The URL port, or null if no port was defined + */ + public String getPort() { + return port; + } + + public String getVersion() { + return version; + } + + @Override + public String toString() { + return String.format("%s://%s:%s/%s", scheme, host, port, version); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/ProviderAdapterImpl.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/ProviderAdapterImpl.java new file mode 100644 index 000000000..b1bba0918 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/ProviderAdapterImpl.java @@ -0,0 +1,2723 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.iaas.impl; + +import com.woorea.openstack.base.client.OpenStackBaseException; +import com.woorea.openstack.heat.Heat; +import org.glassfish.grizzly.http.util.HttpStatus; +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.ProviderAdapter; +import org.openecomp.appc.adapter.openstack.heat.SnapshotResource; +import org.openecomp.appc.adapter.openstack.heat.StackResource; +import org.openecomp.appc.adapter.openstack.heat.model.CreateSnapshotParams; +import org.openecomp.appc.adapter.openstack.heat.model.Snapshot; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.exceptions.UnknownProviderException; +import org.openecomp.appc.i18n.Msg; +import org.openecomp.appc.pool.Pool; +import org.openecomp.appc.pool.PoolExtensionException; +import org.openecomp.appc.util.StructuredPropertyHelper; +import org.openecomp.appc.util.StructuredPropertyHelper.Node; +import com.att.cdp.exceptions.*; +import com.att.cdp.openstack.OpenStackContext; +import com.att.cdp.openstack.connectors.HeatConnector; +import com.att.cdp.openstack.util.ExceptionMapper; +import com.att.cdp.pal.util.StringHelper; +import com.att.cdp.zones.*; +import com.att.cdp.zones.model.Image; +import com.att.cdp.zones.model.Server; +import com.att.cdp.zones.model.ServerBootSource; +import com.att.cdp.zones.model.Stack; +import com.att.cdp.zones.model.Server.Status; +import com.att.cdp.zones.spi.AbstractService; +import com.att.cdp.zones.spi.RequestState; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.slf4j.MDC; + +import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME; + +import java.io.IOException; +import java.net.URI; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.regex.Pattern; + +/** + * This class implements the {@link ProviderAdapter} interface. This interface defines the behaviors that our service + * provides. + */ +@SuppressWarnings("javadoc") +public class ProviderAdapterImpl implements ProviderAdapter { + + /** + * The name of the adapter + */ + @SuppressWarnings("nls") + private static final String ADAPTER_NAME = "Appc IaaS Adapter"; + + /** + * The username and password to use for dynamically created connections + */ + private static String DEFAULT_USER; + private static String DEFAULT_PASS; + + /** + * The constant used to define the adapter name in the mapped diagnostic context + */ + @SuppressWarnings("nls") + private static final String MDC_ADAPTER = "adapter"; + + /** + * The constant used to define the service name in the mapped diagnostic context + */ + @SuppressWarnings("nls") + static final String MDC_SERVICE = "service"; + + /** + * The constant for the status code for a failed outcome + */ + @SuppressWarnings("nls") + private static final String OUTCOME_FAILURE = "failure"; + + /** + * The constant for the status code for a successful outcome + */ + @SuppressWarnings("nls") + private static final String OUTCOME_SUCCESS = "success"; + + /** + * A constant for the property token "provider" used in the structured property specifications + */ + @SuppressWarnings("nls") + private static final String PROPERTY_PROVIDER = "provider"; + + /** + * A constant for the property token "identity" used in the structured property specifications + */ + @SuppressWarnings("nls") + private static final String PROPERTY_PROVIDER_IDENTITY = "identity"; + + /** + * A constant for the property token "tenant" used in the structured property specifications + */ + @SuppressWarnings("nls") + private static final String PROPERTY_PROVIDER_TENANT = "tenant"; + + /** + * A constant for the property token "tenant name" used in the structured property specifications + */ + @SuppressWarnings("nls") + private static final String PROPERTY_PROVIDER_TENANT_NAME = "name"; + + /** + * A constant for the property token "password" used in the structured property specifications + */ + @SuppressWarnings("nls") + private static final String PROPERTY_PROVIDER_TENANT_PASSWORD = "password"; // NOSONAR + + /** + * A constant for the property token "userid" used in the structured property specifications + */ + @SuppressWarnings("nls") + private static final String PROPERTY_PROVIDER_TENANT_USERID = "userid"; + + /** + * A constant for the property token "type" used in the structured property specifications + */ + @SuppressWarnings("nls") + private static final String PROPERTY_PROVIDER_TYPE = "type"; + + /** + * The name of the service to evacuate a server + */ + @SuppressWarnings("nls") + private static final String EVACUATE_SERVICE = "evacuateServer"; + + /** + * The name of the service to migrate a server + */ + @SuppressWarnings("nls") + private static final String MIGRATE_SERVICE = "migrateServer"; + + /** + * The name of the service to rebuild a server + */ + @SuppressWarnings("nls") + private static final String REBUILD_SERVICE = "rebuildServer"; + + /** + * The name of the service to restart a server + */ + @SuppressWarnings("nls") + private static final String RESTART_SERVICE = "restartServer"; + + /** + * The name of the service to check status of a server + */ + @SuppressWarnings("nls") + private static final String VMSTATUSCHECK_SERVICE = "vmStatuschecker"; + + + /** + * The name of the service to restart a server + */ + @SuppressWarnings("nls") + private static final String SNAPSHOT_SERVICE = "createSnapshot"; + + /** + * The name of the service to terminate a stack + */ + @SuppressWarnings("nls") + private static final String TERMINATE_STACK = "terminateStack"; + + /** + * The name of the service to snapshot a stack + */ + @SuppressWarnings("nls") + private static final String SNAPSHOT_STACK = "snapshotStack"; + + /** + * The name of a service to start a server + */ + @SuppressWarnings("nls") + private static final String START_SERVICE = "startServer"; + + /** + * The name of the service to stop a server + */ + @SuppressWarnings("nls") + private static final String STOP_SERVICE = "stopServer"; + + /** + * The name of the service to stop a server + */ + @SuppressWarnings("nls") + private static final String TERMINATE_SERVICE = "terminateServer"; + + /** + * The name of the service to lookup a server + */ + @SuppressWarnings("nls") + private static final String LOOKUP_SERVICE = "lookupServer"; + + /** + * The logger to be used + */ + private static final EELFLogger logger = EELFManager.getInstance().getLogger(ProviderAdapterImpl.class); + + private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; + + /** + * The constant for a left parenthesis + */ + private static final char LPAREN = '('; + + /** + * The constant for a new line control code + */ + private static final char NL = '\n'; + + /** + * The constant for a single quote + */ + private static final char QUOTE = '\''; + + /** + * The constant for a right parenthesis + */ + private static final char RPAREN = ')'; + + /** + * The constant for a space + */ + private static final char SPACE = ' '; + + /** + * A reference to the adapter configuration object. + */ + private Configuration configuration; + + /** + * A cache of providers that are predefined. + */ + private Map<String /* provider name */, ProviderCache> providerCache; + + /** + * A list of valid initial VM statuses for a migrate operations + */ + private static final Collection<Status> migratableStatuses = Arrays.asList(Status.READY, Status.RUNNING, Status.SUSPENDED); + + /** + * This default constructor is used as a work around because the activator wasnt getting called + */ + @SuppressWarnings("all") + public ProviderAdapterImpl() { + initialize(); + + } + + /** + * This constructor is used primarily in the test cases to bypass initialization of the adapter for isolated, + * disconnected testing + * + * @param initialize + * True if the adapter is to be initialized, can false if not + */ + @SuppressWarnings("all") + public ProviderAdapterImpl(boolean initialize) { + configuration = ConfigurationFactory.getConfiguration(); + if (initialize) { + initialize(); + } + } + + /** + * @param props + * not used + */ + public ProviderAdapterImpl(@SuppressWarnings("unused") Properties props) { + initialize(); + + } + + /** + * Returns the symbolic name of the adapter + * + * @return The adapter name + * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#getAdapterName() + */ + @Override + public String getAdapterName() { + return configuration.getProperty(Constants.PROPERTY_ADAPTER_NAME); + } + + @SuppressWarnings("nls") + @Override + public Image createSnapshot(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + Image snapshot = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + MDC.put(MDC_ADAPTER, ADAPTER_NAME); + MDC.put(MDC_SERVICE, SNAPSHOT_SERVICE); + MDC.put(MDC_SERVICE_NAME, "App-C IaaS Adapter:Snapshot"); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.SNAPSHOTING_SERVER, appName); + String msg; + + try { + validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + debugParameters(params); + debugContext(ctx); + + VMURL vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); + String identStr = (ident == null) ? null : ident.toString(); + + Context context = null; + try { + context = getContext(rc, vm_url, identStr); + if (context != null) { + Server server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + + if (hasImageAccess(rc, context)) { + snapshot = createSnapshot(rc, server); + doSuccess(rc); + } else { + msg = EELFResourceManager.format(Msg.REBUILD_SERVER_FAILED, server.getName(), server.getId(), + "Accessing Image Service Failed"); + logger.error(msg); + doFailure(rc, HttpStatus.FORBIDDEN_403, msg); + } + context.close(); + } + } catch (ResourceNotFoundException e) { + msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + } catch (Throwable t) { + msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + SNAPSHOT_SERVICE, vm_url, context == null ? "Unknown" : context.getTenantName()); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + doFailure(rc, e.getStatus(), e.getMessage()); + } + return snapshot; + } + + private boolean validateVM(RequestContext rc, String appName, String vm_url, VMURL vm) + throws RequestFailedException { + String msg; + if (vm == null) { + msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + return true; + } + validateVMURL(vm); + return false; + } + + private Image createSnapshot(RequestContext rc, Server server) throws ZoneException, RequestFailedException { + Context context = server.getContext(); + Provider provider = context.getProvider(); + ImageService service = context.getImageService(); // Already checked access by this point + + String snapshotName = generateSnapshotName(server.getName()); + + logger.info(String.format("Creating snapshot of server %s (%s) with name %s", server.getName(), server.getId(), + snapshotName)); + + // Request Snapshot + String msg; + while (rc.attempt()) { + try { + server.createSnapshot(snapshotName); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + throw new RequestFailedException("Stop Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + + // Locate snapshot image + Image snapshot = null; + while (rc.attempt()) { + try { + snapshot = service.getImageByName(snapshotName); + if (snapshot != null) { + break; + } + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + throw new RequestFailedException("Stop Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + + // Wait for it to be ready + waitForStateChange(rc, snapshot, Image.Status.ACTIVE); + + return snapshot; + } + + private String generateSnapshotName(String server) { + SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT); + return String.format("Snapshot of %s at %s", server, df.format(new Date())); + } + + /** + * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#evacuateServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) + */ + @SuppressWarnings("nls") + @Override + public Server evacuateServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + Server server = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + MDC.put(MDC_ADAPTER, ADAPTER_NAME); + MDC.put(MDC_SERVICE, EVACUATE_SERVICE); + MDC.put(MDC_SERVICE_NAME, "App-C IaaS Adapter:Evacuate"); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.EVACUATING_SERVER, appName); + String msg; + + try { + validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + String providerName = params.get(ProviderAdapter.PROPERTY_PROVIDER_NAME); + debugParameters(params); + debugContext(ctx); + + VMURL vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + Context context = null; + try { + context = getContext(rc, vm_url, providerName); + if (context != null) { + server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + evacuateServer(rc, server); + server.refreshStatus(); + context.close(); + doSuccess(rc); + } + } catch (ResourceNotFoundException e) { + msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + } catch (Throwable t) { + msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + EVACUATE_SERVICE, vm_url, context == null ? "Unknown" : context.getTenantName()); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + doFailure(rc, e.getStatus(), e.getMessage()); + } + + return server; + } + + /** + * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#migrateServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) + */ + @SuppressWarnings("nls") + @Override + public Server migrateServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + Server server = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + MDC.put(MDC_ADAPTER, ADAPTER_NAME); + MDC.put(MDC_SERVICE, MIGRATE_SERVICE); + MDC.put(MDC_SERVICE_NAME, "App-C IaaS Adapter:Migrate"); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.MIGRATING_SERVER, appName); + String msg; + + try { + validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + debugParameters(params); + debugContext(ctx); + + VMURL vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); + String identStr = (ident == null) ? null : ident.toString(); + + Context context = null; + try { + context = getContext(rc, vm_url, identStr); + if (context != null) { + server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + migrateServer(rc, server); + server.refreshStatus(); + context.close(); + doSuccess(rc); + } + } catch (ResourceNotFoundException e) { + msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + } catch (Throwable t) { + msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + MIGRATE_SERVICE, vm_url, context == null ? "Unknown" : context.getTenantName()); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + doFailure(rc, e.getStatus(), e.getMessage()); + } + + return server; + } + + private void evacuateServer(RequestContext rc, @SuppressWarnings("unused") Server server) throws ZoneException, RequestFailedException { + doFailure(rc, HttpStatus.NOT_IMPLEMENTED_501, "The operation 'EVACUATE' is not yet implemented"); + } + + private void migrateServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { + String msg; + Context ctx = server.getContext(); + ComputeService service = ctx.getComputeService(); + + // Init status will equal final status + Status initialStatus = server.getStatus(); + + if (initialStatus == null) { + throw new ZoneException("Failed to determine server's starting status"); + } + + // We can only migrate certain statuses + if (!migratableStatuses.contains(initialStatus)) { + throw new ZoneException(String.format("Cannot migrate server that is in %s state. Must be in one of [%s]", + initialStatus, migratableStatuses)); + } + + boolean inConfirmPhase = false; + try { + while (rc.attempt()) { + try { + if (!inConfirmPhase) { + // Initial migrate request + service.migrateServer(server.getId()); + // Wait for change to verify resize + waitForStateChange(rc, server, Status.READY); + inConfirmPhase = true; + } + + // Verify resize + service.processResize(server); + // Wait for complete. will go back to init status + waitForStateChange(rc, server, initialStatus); + logger.info("Completed migrate request successfully"); + return; + } catch (ContextConnectionException e) { + msg = getConnectionExceptionMessage(rc, ctx, e); + logger.error(msg, e); + rc.delay(); + } + } + } catch (ZoneException e) { + String phase = inConfirmPhase ? "VERIFY MIGRATE" : "REQUEST MIGRATE"; + msg = EELFResourceManager.format(Msg.MIGRATE_SERVER_FAILED, server.getName(), server.getId(), phase, + e.getMessage()); + generateEvent(rc, false, msg); + logger.error(msg, e); + throw new RequestFailedException("Migrate Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); + } + + } + + /** + * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#rebuildServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) + */ + @SuppressWarnings("nls") + @Override + public Server rebuildServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + Server server = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + MDC.put(MDC_ADAPTER, ADAPTER_NAME); + MDC.put(MDC_SERVICE, REBUILD_SERVICE); + MDC.put(MDC_SERVICE_NAME, "App-C IaaS Adapter:Rebuild"); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.REBUILDING_SERVER, appName); + String msg; + + try { + validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + debugParameters(params); + debugContext(ctx); + + VMURL vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); + String identStr = (ident == null) ? null : ident.toString(); + + Context context = null; + try { + context = getContext(rc, vm_url, identStr); + if (context != null) { + server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + + // Manually checking image service until new PAL release + if (hasImageAccess(rc, context)) { + rebuildServer(rc, server); + doSuccess(rc); + } else { + msg = EELFResourceManager.format(Msg.REBUILD_SERVER_FAILED, server.getName(), server.getId(), + "Accessing Image Service Failed"); + logger.error(msg); + doFailure(rc, HttpStatus.FORBIDDEN_403, msg); + } + context.close(); + } + } catch (ResourceNotFoundException e) { + msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + } catch (Throwable t) { + msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + STOP_SERVICE, vm_url, context == null ? "Unknown" : context.getTenantName()); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + doFailure(rc, e.getStatus(), e.getMessage()); + } + + return server; + } + + /** + * This method is used to restart an existing virtual machine given the fully qualified URL of the machine. + * <p> + * The fully qualified URL contains enough information to locate the appropriate server. The URL is of the form + * <pre> + * [scheme]://[host[:port]] / [path] / [tenant_id] / servers / [vm_id] + * </pre> Where the various parts of the URL can be parsed and extracted and used to locate the appropriate service + * in the provider service catalog. This then allows us to open a context using the CDP abstraction, obtain the + * server by its UUID, and then perform the restart. + * </p> + * + * @throws UnknownProviderException + * If the provider cannot be found + * @throws IllegalArgumentException + * if the expected argument(s) are not defined or are invalid + * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#restartServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) + */ + @SuppressWarnings("nls") + @Override + public Server restartServer(Map<String, String> params, SvcLogicContext ctx) + throws UnknownProviderException, IllegalArgumentException { + Server server = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + MDC.put(MDC_ADAPTER, ADAPTER_NAME); + MDC.put(MDC_SERVICE, RESTART_SERVICE); + MDC.put(MDC_SERVICE_NAME, "App-C IaaS Adapter:Restart"); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.RESTARTING_SERVER, appName); + + try { + validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + debugParameters(params); + debugContext(ctx); + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + + VMURL vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); + String identStr = (ident == null) ? null : ident.toString(); + + Context context = null; + try { + context = getContext(rc, vm_url, identStr); + if (context != null) { + server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + restartServer(rc, server); + context.close(); + doSuccess(rc); + } + } catch (ResourceNotFoundException e) { + String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + } catch (Throwable t) { + String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + RESTART_SERVICE, vm_url, context == null ? "Unknown" : context.getTenantName()); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + doFailure(rc, e.getStatus(), e.getMessage()); + } + + return server; + } + + /* *********************************************************************************/ + /* DEVEN PANCHAL: This method is used to check the status of the VM */ + /**********************************************************************************/ + public Server vmStatuschecker(Map<String, String> params, SvcLogicContext ctx) throws UnknownProviderException, IllegalArgumentException { + Server server = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + MDC.put(MDC_ADAPTER, ADAPTER_NAME); + MDC.put(MDC_SERVICE, VMSTATUSCHECK_SERVICE); + MDC.put(MDC_SERVICE_NAME, "App-C IaaS Adapter: vmstatuscheck"); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + + try { + validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + debugParameters(params); + debugContext(ctx); + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + + VMURL vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); + String identStr = (ident == null) ? null : ident.toString(); + + Context context = null; + try { + context = getContext(rc, vm_url, identStr); + if (context != null) { + server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + + String statusvm; + switch (server.getStatus()) { + case DELETED: + statusvm = "deleted"; + break; + + case RUNNING: + statusvm = "running"; + break; + + case ERROR: + statusvm = "error"; + break; + + case READY: + statusvm = "ready"; + break; + + case PAUSED: + statusvm = "paused"; + break; + + case SUSPENDED: + statusvm = "suspended"; + break; + + case PENDING: + statusvm = "pending"; + break; + + default: + statusvm = "default-unknown state-should never occur"; + break; + } + + + String statusofVM = statusvm; + context.close(); + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + svcLogic.setStatus(OUTCOME_SUCCESS); + svcLogic.setAttribute("org.openecomp.statusofvm", statusofVM); + svcLogic.setAttribute(Constants.STATUS_OF_VM, statusofVM); + svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_CODE, Integer.toString(HttpStatus.OK_200.getStatusCode())); + } + } catch (ResourceNotFoundException e) { + String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + } catch (Throwable t) { + String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + RESTART_SERVICE, vm_url, context == null ? "Unknown" : context.getTenantName()); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + doFailure(rc, e.getStatus(), e.getMessage()); + } + + return server; + } + + /* *********************************************************************************/ + + + /** + * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#startServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) + */ + @SuppressWarnings("nls") + @Override + public Server startServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + Server server = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + MDC.put(MDC_ADAPTER, ADAPTER_NAME); + MDC.put(MDC_SERVICE, START_SERVICE); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.RESTARTING_SERVER, appName); + + try { + validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + debugParameters(params); + debugContext(ctx); + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + String providerName = params.get(ProviderAdapter.PROPERTY_PROVIDER_NAME); + + VMURL vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + Context context = null; + try { + context = getContext(rc, vm_url, providerName); + if (context != null) { + server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + stopServer(rc, server); + server.refreshStatus(); + context.close(); + doSuccess(rc); + } + } catch (ResourceNotFoundException e) { + String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + } catch (Throwable t) { + String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + START_SERVICE, vm_url, context == null ? "Unknown" : context.getTenantName()); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + doFailure(rc, e.getStatus(), e.getMessage()); + } + + return server; + } + + /** + * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#stopServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) + */ + @SuppressWarnings("nls") + @Override + public Server stopServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + Server server = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + MDC.put(MDC_ADAPTER, ADAPTER_NAME); + MDC.put(MDC_SERVICE, STOP_SERVICE); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.STOPPING_SERVER, appName); + + try { + validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + debugParameters(params); + debugContext(ctx); + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + ctx.setAttribute("STOP_STATUS", "SUCCESS"); + + VMURL vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); + String identStr = (ident == null) ? null : ident.toString(); + + Context context = null; + try { + context = getContext(rc, vm_url, identStr); + if (context != null) { + server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + if (server.getStatus().equals(Status.PENDING)) { + throw new RequestFailedException("Server is in pending Status"); + } + stopServer(rc, server); + server.refreshStatus(); + if (server.getStatus().equals(Status.ERROR)) { + throw new RequestFailedException("Server is in ERROR state after operation"); + } + context.close(); + doSuccess(rc); + }else{ + ctx.setAttribute("STOP_STATUS", "SERVER_NOT_FOUND"); + } + } catch (ResourceNotFoundException e) { + String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + ctx.setAttribute("STOP_STATUS", "SERVER_NOT_FOUND"); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + } catch (Throwable t) { + String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + STOP_SERVICE, vm_url, context == null ? "Unknown" : context.getTenantName()); + logger.error(msg, t); + ctx.setAttribute("STOP_STATUS", "ERROR"); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + logger.error(EELFResourceManager.format(Msg.STOP_SERVER_FAILED, appName, "n/a", "n/a", e.getMessage())); + ctx.setAttribute("STOP_STATUS", "ERROR"); + doFailure(rc, e.getStatus(), e.getMessage()); + } + + return server; + } + + /** + * This method is used to validate that the parameters contain all required property names, and that the values are + * non-null and non-empty strings. We are still not ensured that the value is valid, but at least it exists. + * + * @param ctx + * The request context object that manages the request + * @param parameters + * The parameters to be checked + * @param propertyNames + * The list of property names that are required to be present. + * @throws RequestFailedException + * If the parameters are not valid + */ + @SuppressWarnings({ + "nls", "static-method" + }) + private void validateParametersExist(@SuppressWarnings("unused") RequestContext ctx, Map<String, String> parameters, String... propertyNames) + throws RequestFailedException { + boolean success = true; + StringBuilder msg = new StringBuilder(EELFResourceManager.format(Msg.MISSING_REQUIRED_PROPERTIES, MDC.get(MDC_SERVICE))); + msg.append(NL); + for (String propertyName : propertyNames) { + String value = parameters.get(propertyName); + if (value == null || value.trim().length() == 0) { + success = false; + msg.append(QUOTE); + msg.append(propertyName); + msg.append(QUOTE); + msg.append(SPACE); + } + } + + if (!success) { + logger.error(msg.toString()); + throw new RequestFailedException("Check Parameters", msg.toString(), HttpStatus.BAD_REQUEST_400, (Server)null); + } + } + + /** + * This method is used to create a diagnostic dump of the context for the log + * + * @param context + * The context to be dumped + */ + @SuppressWarnings({ + "nls", "static-method" + }) + private void debugContext(SvcLogicContext context) { + Set<String> keys = context.getAttributeKeySet(); + StringBuilder builder = new StringBuilder(); + + builder.append("Service Logic Context: Status "); + builder.append(LPAREN); + builder.append(context.getStatus()); + builder.append(RPAREN); + builder.append(", Attribute count "); + builder.append(LPAREN); + builder.append(keys == null ? "none" : Integer.toString(keys.size())); + builder.append(RPAREN); + if (keys != null && !keys.isEmpty()) { + builder.append(NL); + for (String key : keys) { + String value = context.getAttribute(key); + builder.append("Attribute "); + builder.append(LPAREN); + builder.append(key); + builder.append(RPAREN); + builder.append(", value "); + builder.append(LPAREN); + builder.append(value == null ? "" : value); + builder.append(RPAREN); + builder.append(NL); + } + } + + logger.debug(builder.toString()); + } + + void validateVMURL(VMURL vm) throws RequestFailedException { + String name = "vm-id"; + if (vm == null) { + throw new RequestFailedException(String.format("The value %s cannot be null.", name)); + } + + // Check that its a good uri + // This will probably never get hit bc of an earlier check while parsing + // the string to a VMURL + try { + //noinspection ResultOfMethodCallIgnored + URI.create(vm.toString()); + } catch (Exception e) { + throw new RequestFailedException( + String.format("The value %s is not well formed [%s].", name, vm.toString())); + } + + // Check the tenant and vmid segments + String patternRegex = "([0-9a-f]{8}(-)?[0-9a-f]{4}(-)?[0-9a-f]{4}(-)?[0-9a-f]{4}(-)?[0-9a-f]{12})"; + Pattern pattern = Pattern.compile(patternRegex, Pattern.CASE_INSENSITIVE); + + if (!pattern.matcher(vm.getTenantId()).matches()) { + throw new RequestFailedException( + String.format("The value %s has an invalid tenantId [%s].", name, vm.getTenantId())); + } + if (!pattern.matcher(vm.getServerId()).matches()) { + throw new RequestFailedException( + String.format("The value %s has an invalid serverId [%s].", name, vm.getServerId())); + } + } + + @SuppressWarnings("unused") + private void validateIdentityURL(IdentityURL id) throws RequestFailedException { + String name = "identity-url"; + if (id == null) { + throw new RequestFailedException(String.format("The value %s cannot be null.", name)); + } + + // Check that its a good uri + // This will probably never get hit bc of an earlier check while parsing + // the string to a VMURL + try { + //noinspection ResultOfMethodCallIgnored + URI.create(id.toString()); + } catch (Exception e) { + throw new RequestFailedException( + String.format("The value %s is not well formed [%s].", name, id.toString())); + } + } + + /** + * This method is used to dump the value of the parameters to the log for debugging purposes. + * + * @param parameters + * The parameters to be printed to the log + */ + @SuppressWarnings("static-method") + private void debugParameters(Map<String, String> parameters) { + for (String key : parameters.keySet()) { + logger.debug(Msg.PROPERTY_VALUE, key, parameters.get(key)); + } + } + + /** + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param code + * @param message + */ + @SuppressWarnings("static-method") + private void doFailure(RequestContext rc, HttpStatus code, String message) { + try { + doFailure(rc, code, message, null); + } catch (APPCException ignored) {/* never happens */} + } + + + private void doFailure(RequestContext rc, HttpStatus code, String message, Throwable cause) throws APPCException { + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + String msg = (message == null) ? code.getReasonPhrase() : message; + if (msg.contains("\n")) { + msg = msg.substring(0, msg.indexOf("\n")); + } + String status; + try { + status = Integer.toString(code.getStatusCode()); + } catch (Exception e) { + status = "500"; + } + svcLogic.setStatus(OUTCOME_FAILURE); + svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_CODE, status); + svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE, msg); + svcLogic.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, msg); + + if (null != cause) throw new APPCException(cause); + } + + /** + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + */ + @SuppressWarnings("static-method") + private void doSuccess(RequestContext rc) { + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + svcLogic.setStatus(OUTCOME_SUCCESS); + svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_CODE, Integer.toString(HttpStatus.OK_200.getStatusCode())); + } + + /** + * Generates the event indicating what happened + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param success + * True if the event represents a successful outcome + * @param msg + * The detailed message + */ + private void generateEvent(@SuppressWarnings("unused") RequestContext rc, @SuppressWarnings("unused") boolean success, @SuppressWarnings("unused") String msg) { + // indication to the DG to generate the event? + } + + /** + * This method is a general helper method used to locate a server given its fully-qualified self-link URL on a + * supported provider, regardless of region(s), and to return an opened context that can be used to access that + * server. + * + * @param rc + * The request context that wraps and manages the state of the request + * @param selfLinkURL + * The fully-qualified self-link URL of the server + * @param providerName + * The name of the provider to be searched + * @return The context that can be used to access the server, or null if not found. + */ + @SuppressWarnings("nls") + private Context getContext(RequestContext rc, String selfLinkURL, String providerName) { + VMURL vm = VMURL.parseURL(selfLinkURL); + IdentityURL ident = IdentityURL.parseURL(providerName); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + + if (vm == null) { + String msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, selfLinkURL); + logger.error(msg); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + return null; + } + + /* + * Get the cache of tenants and contexts for the named provider, if one exists + */ + ProviderCache cache = providerCache.get(providerName); + + /* + * If one doesn't exist, try and create it. If we have enough information to create it successfully, add it to + * the cache and continue, otherwise fail the request. + */ + if (cache == null) { + if (ident != null) { + cache = createProviderCache(vm, ident); + } + if (cache != null) { + providerCache.put(cache.getProviderName(), cache); + } else { + String msg = + EELFResourceManager.format(Msg.UNKNOWN_PROVIDER, providerName, providerCache.keySet().toString()); + logger.error(msg); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + return null; + } + } + + if (providerName == null) { + logger + .debug(String.format("Using the default provider cache [%s] since no valid identity url was passed in.", + cache.getIdentityURL())); + } + + // get the tenant cache for the vm + String identityURL = cache.getIdentityURL(); + TenantCache tenantCache = cache.getTenant(vm.getTenantId()); + + if(tenantCache == null){ + //no tenantCache matching tenant, add tenant to the provider cache + tenantCache = cache.addTenant(vm.getTenantId(),null,DEFAULT_USER, DEFAULT_PASS); + + if(tenantCache == null){ + //tenant not found + String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, selfLinkURL); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + return null; + } + } + + //reserve the context + String tenantName = tenantCache.getTenantName(); + String tenantId = tenantCache.getTenantId(); + String region = tenantCache.determineRegion(vm); + + if (region != null) { + Pool<Context> pool = tenantCache.getPools().get(region); + + while (rc.attempt()) { + try { + Context context = pool.reserve(); + + /* + * Insert logic here to test the context for connectivity because we may have gotten one from + * the pool that was previously created. + */ + if (context.isStale()) { + context.relogin(); + } + return context; + } catch (PoolExtensionException e) { + String msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, providerName, identityURL, + tenantName, tenantId, e.getMessage(), Long.toString(rc.getRetryDelay()), + Integer.toString(rc.getAttempts()), Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } catch (Exception e) { + String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e, + e.getClass().getSimpleName(), "find", selfLinkURL, tenantCache.getTenantName()); + + logger.error(msg, e); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + return null; + } + } + + String msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, providerName, identityURL); + logger.error(msg); + doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg); + return null; + } + + + String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, selfLinkURL); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + return null; + } + + /** + * initialize the provider adapter by building the context cache + */ + private void initialize() { + configuration = ConfigurationFactory.getConfiguration(); + + /* + * Initialize the provider cache for all defined providers. The definition of the providers uses a structured + * property set, where the names form a hierarchical name space (dotted notation, such as one.two.three). Each + * name in the name space can also be serialized by appending a sequence number. All nodes at the same level + * with the same serial number are grouped together in the namespace hierarchy. This allows a hierarchical + * multi-valued property to be defined, which can then be used to setup the provider and tenant caches. + * <p> + * For example, the following definitions show how the namespace hierarchy is defined for two providers, with + * two tenants on the first provider and a single tenant for the second provider. <pre> + * provider1.type=OpenStackProvider1 + * provider1.name=OpenStackProviderName1 + * provider1.identity=http://192.168.1.2:5000/v2.0 + * provider1.tenant1.name=MY-TENANT-NAME + * provider1.tenant1.userid=userid + * provider1.tenant1.password=userid@123 + * provider1.tenant2.name=MY-TENANT-NAME + * provider1.tenant2.userid=userid + * provider1.tenant2.password=userid@123 + * provider2.type=OpenStackProvider2 + * provider2.name=OpenStackProviderName2 + * provider2.identity=http://192.168.1.2:5000/v2.0 + * provider2.tenant1.name=MY-TENANT-NAME + * provider2.tenant1.userid=userid + * provider2.tenant1.password=userid@123 + * </pre> + * </p> + */ + providerCache = new HashMap<>(); + Properties properties = configuration.getProperties(); + List<Node> providers = StructuredPropertyHelper.getStructuredProperties(properties, PROPERTY_PROVIDER); + + for (Node provider : providers) { + ProviderCache cache = new ProviderCache(); + List<Node> providerNodes = provider.getChildren(); + for (Node node : providerNodes) { + if (node.getName().equals(PROPERTY_PROVIDER_TYPE)) { + cache.setProviderType(node.getValue()); + } else if (node.getName().equals(PROPERTY_PROVIDER_IDENTITY)) { + cache.setIdentityURL(node.getValue()); + cache.setProviderName(node.getValue()); + } else if (node.getName().startsWith(PROPERTY_PROVIDER_TENANT)) { + String tenantName = null; + String userId = null; + String password = null; + for (Node node2 : node.getChildren()) { + switch (node2.getName()) { + case PROPERTY_PROVIDER_TENANT_NAME: + tenantName = node2.getValue(); + break; + case PROPERTY_PROVIDER_TENANT_USERID: + userId = node2.getValue(); + DEFAULT_USER = node2.getValue(); + break; + case PROPERTY_PROVIDER_TENANT_PASSWORD: + password = node2.getValue(); + DEFAULT_PASS = node2.getValue(); + break; + } + } + + cache.addTenant(null, tenantName, userId, password); + } + } + + /* + * Add the provider to the set of providers cached + */ + if (cache.getIdentityURL() != null && cache.getProviderType() != null) { + providerCache.put(null, cache); + providerCache.put(cache.getIdentityURL(), cache); + } + + /* + * Now, initialize the cache for the loaded provider + */ + cache.initialize(); + } + } + + /** + * This method is called to rebuild the provided server. + * <p> + * If the server was booted from a volume, then the request is failed immediately and no action is taken. Rebuilding + * a VM from a bootable volume, where the bootable volume itself is not rebuilt, serves no purpose. + * </p> + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * @throws ZoneException + * @throws RequestFailedException + */ + @SuppressWarnings("nls") + private void rebuildServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { + + ServerBootSource builtFrom = server.getBootSource(); + String msg; + + // Throw exception for non image/snap boot source + if (ServerBootSource.VOLUME.equals(builtFrom)) { + msg = String.format("Rebuilding is currently not supported for servers built from bootable volumes [%s]", + server.getId()); + generateEvent(rc, false, msg); + logger.error(msg); + throw new RequestFailedException("Rebuild Server", msg, HttpStatus.FORBIDDEN_403, server); + } + /* + * Pending is a bit of a special case. If we find the server is in a pending state, then the provider is in the + * process of changing state of the server. So, lets try to wait a little bit and see if the state settles down + * to one we can deal with. If not, then we have to fail the request. + */ + Context context = server.getContext(); + Provider provider = context.getProvider(); + ComputeService service = context.getComputeService(); + if (server.getStatus().equals(Status.PENDING)) { + waitForStateChange(rc, server, Status.READY, Status.RUNNING, Status.ERROR, Status.SUSPENDED, Status.PAUSED); + } + + /* + * Get the image to use. This is determined by the presence or absence of snapshot images. If any snapshots + * exist, then the latest snapshot is used, otherwise the image used to construct the VM is used. + */ + List<Image> snapshots = server.getSnapshots(); + String imageToUse; + if (snapshots != null && !snapshots.isEmpty()) { + imageToUse = snapshots.get(0).getId(); + } else { + imageToUse = server.getImage(); + ImageService imageService = server.getContext().getImageService(); + try { + while (rc.attempt()) { + try { + /* + * We are just trying to make sure that the image exists. We arent interested in the details at + * this point. + */ + imageService.getImage(imageToUse); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), + imageService.getURL(), context.getTenant().getName(), context.getTenant().getId(), + e.getMessage(), Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } + } catch (ZoneException e) { + msg = EELFResourceManager.format(Msg.IMAGE_NOT_FOUND, imageToUse, "rebuild"); + generateEvent(rc, false, msg); + logger.error(msg); + throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); + } + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + throw new RequestFailedException("Rebuild Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + + /* + * We determine what to do based on the current state of the server + */ + switch (server.getStatus()) { + case DELETED: + // Nothing to do, the server is gone + msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(), + server.getTenantId(), "rebuilt"); + generateEvent(rc, false, msg); + logger.error(msg); + throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); + + case RUNNING: + // Attempt to stop the server, then rebuild it + stopServer(rc, server); + rebuildServer(rc, server, imageToUse); + startServer(rc, server); + generateEvent(rc, true, OUTCOME_SUCCESS); + break; + + case ERROR: + msg = EELFResourceManager.format(Msg.SERVER_ERROR_STATE, server.getName(), server.getId(), + server.getTenantId(), "rebuild"); + generateEvent(rc, false, msg); + logger.error(msg); + throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); + + case READY: + // Attempt to rebuild the server + rebuildServer(rc, server, imageToUse); + startServer(rc, server); + generateEvent(rc, true, OUTCOME_SUCCESS); + break; + + case PAUSED: + // if paused, un-pause it, stop it, and rebuild it + unpauseServer(rc, server); + stopServer(rc, server); + rebuildServer(rc, server, imageToUse); + startServer(rc, server); + generateEvent(rc, true, OUTCOME_SUCCESS); + break; + + case SUSPENDED: + // Attempt to resume the suspended server, stop it, and rebuild it + resumeServer(rc, server); + stopServer(rc, server); + rebuildServer(rc, server, imageToUse); + startServer(rc, server); + generateEvent(rc, true, OUTCOME_SUCCESS); + break; + + default: + // Hmmm, unknown status, should never occur + msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(), + server.getTenantId(), server.getStatus().name()); + generateEvent(rc, false, msg); + logger.error(msg); + throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); + } + } + + /** + * This method handles the case of restarting a server once we have found the server and have obtained the abstract + * representation of the server via the context (i.e., the "Server" object from the CDP-Zones abstraction). + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * The server object representing the server we want to operate on + * @throws ZoneException + */ + @SuppressWarnings("nls") + private void restartServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { + /* + * Pending is a bit of a special case. If we find the server is in a pending state, then the provider is in the + * process of changing state of the server. So, lets try to wait a little bit and see if the state settles down + * to one we can deal with. If not, then we have to fail the request. + */ + String msg; + if (server.getStatus().equals(Status.PENDING)) { + waitForStateChange(rc, server, Status.READY, Status.RUNNING, Status.ERROR, Status.SUSPENDED, Status.PAUSED); + } + + /* + * We determine what to do based on the current state of the server + */ + switch (server.getStatus()) { + case DELETED: + // Nothing to do, the server is gone + msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(), + server.getTenantId(), "restarted"); + generateEvent(rc, false, msg); + logger.error(msg); + break; + + case RUNNING: + // Attempt to stop and start the server + stopServer(rc, server); + startServer(rc, server); + generateEvent(rc, true, OUTCOME_SUCCESS); + break; + + case ERROR: + msg = EELFResourceManager.format(Msg.SERVER_ERROR_STATE, server.getName(), server.getId(), + server.getTenantId(), "rebuild"); + generateEvent(rc, false, msg); + logger.error(msg); + throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); + + case READY: + // Attempt to start the server + startServer(rc, server); + generateEvent(rc, true, OUTCOME_SUCCESS); + break; + + case PAUSED: + // if paused, un-pause it + unpauseServer(rc, server); + generateEvent(rc, true, OUTCOME_SUCCESS); + break; + + case SUSPENDED: + // Attempt to resume the suspended server + resumeServer(rc, server); + generateEvent(rc, true, OUTCOME_SUCCESS); + break; + + default: + // Hmmm, unknown status, should never occur + msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(), + server.getTenantId(), server.getStatus().name()); + generateEvent(rc, false, msg); + logger.error(msg); + break; + } + + } + + /** + * Resume a suspended server and wait for it to enter a running state + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * The server to be resumed + * @throws ZoneException + * @throws RequestFailedException + */ + @SuppressWarnings("nls") + private void resumeServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { + logger.debug(Msg.RESUME_SERVER, server.getId()); + + Context context = server.getContext(); + String msg; + Provider provider = context.getProvider(); + ComputeService service = context.getComputeService(); + while (rc.attempt()) { + try { + server.resume(); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + throw new RequestFailedException("Resume Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + waitForStateChange(rc, server, Status.RUNNING); + } + + /** + * Start the server and wait for it to enter a running state + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * The server to be started + * @throws ZoneException + * @throws RequestFailedException + */ + @SuppressWarnings("nls") + private void startServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { + logger.debug(Msg.START_SERVER, server.getId()); + String msg; + Context context = server.getContext(); + Provider provider = context.getProvider(); + ComputeService service = context.getComputeService(); + while (rc.attempt()) { + try { + server.start(); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + throw new RequestFailedException("Start Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + waitForStateChange(rc, server, Status.RUNNING); + } + + /** + * Stop the specified server and wait for it to stop + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * The server to be stopped + * @throws ZoneException + * @throws RequestFailedException + */ + @SuppressWarnings("nls") + private void stopServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { + logger.debug(Msg.STOP_SERVER, server.getId()); + + String msg; + Context context = server.getContext(); + Provider provider = context.getProvider(); + ComputeService service = context.getComputeService(); + while (rc.attempt()) { + try { + server.stop(); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + throw new RequestFailedException("Stop Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + waitForStateChange(rc, server, Status.READY, Status.ERROR); + } + + /** + * Un-Pause a paused server and wait for it to enter a running state + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * The server to be un-paused + * @throws ZoneException + * @throws RequestFailedException + */ + @SuppressWarnings("nls") + private void unpauseServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { + logger.debug(Msg.UNPAUSE_SERVER, server.getId()); + + String msg; + Context context = server.getContext(); + Provider provider = context.getProvider(); + ComputeService service = context.getComputeService(); + while (rc.attempt()) { + try { + server.unpause(); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + throw new RequestFailedException("Unpause Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + waitForStateChange(rc, server, Status.RUNNING, Status.READY); + } + + /** + * Enter a pool-wait loop checking the server state to see if it has entered one of the desired states or not. + * <p> + * This method checks the state of the server periodically for one of the desired states. When the server enters one + * of the desired states, the method returns a successful indication (true). If the server never enters one of the + * desired states within the allocated timeout period, then the method returns a failed response (false). No + * exceptions are thrown from this method. + * </p> + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * The server to wait on + * @param desiredStates + * A variable list of desired states, any one of which is allowed. + * @throws RequestFailedException + * If the request times out or fails for some reason + */ + @SuppressWarnings("nls") + private void waitForStateChange(RequestContext rc, Server server, Server.Status... desiredStates) + throws RequestFailedException { + int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL); + int timeout = configuration.getIntegerProperty(Constants.PROPERTY_SERVER_STATE_CHANGE_TIMEOUT); + Context context = server.getContext(); + Provider provider = context.getProvider(); + ComputeService service = context.getComputeService(); + String msg; + + long endTime = System.currentTimeMillis() + (timeout * 1000); // + + while (rc.attempt()) { + try { + try { + server.waitForStateChange(pollInterval, timeout, desiredStates); + break; + } catch (TimeoutException e) { + @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") + List<String> list = new ArrayList<>(); + for (Server.Status desiredState : desiredStates) { + list.add(desiredState.name()); + } + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } catch (ZoneException e) { + List<String> list = new ArrayList<>(); + for (Server.Status desiredState : desiredStates) { + list.add(desiredState.name()); + } + String reason = EELFResourceManager.format(Msg.STATE_CHANGE_EXCEPTION, e.getClass().getSimpleName(), + "server", server.getName(), server.getId(), StringHelper.asList(list), server.getStatus().name(), + e.getMessage()); + logger.error(reason); + logger.error(EELFResourceManager.format(e)); + + // Instead of failing we are going to wait and try again. + // Timeout is reduced by delay time + logger.info(String.format("Retrying in %ds", rc.getRetryDelay())); + rc.delay(); + timeout = (int) (endTime - System.currentTimeMillis()) / 1000; + // throw new RequestFailedException(e, operation, reason, + // HttpStatus.BAD_GATEWAY_502, server); + } + } + + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + throw new RequestFailedException("Waiting for State Change", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + } + + /** + * Enter a pool-wait loop checking the server state to see if it has entered one of the desired states or not. + * <p> + * This method checks the state of the server periodically for one of the desired states. When the server enters one + * of the desired states, the method returns a successful indication (true). If the server never enters one of the + * desired states within the allocated timeout period, then the method returns a failed response (false). No + * exceptions are thrown from this method. + * </p> + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param image + * The server to wait on + * @param desiredStates + * A variable list of desired states, any one of which is allowed. + * @throws RequestFailedException + * If the request times out or fails for some reason + * @throws NotLoggedInException + */ + @SuppressWarnings("nls") + private void waitForStateChange(RequestContext rc, Image image, Image.Status... desiredStates) + throws RequestFailedException, NotLoggedInException { + int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL); + int timeout = configuration.getIntegerProperty(Constants.PROPERTY_SERVER_STATE_CHANGE_TIMEOUT); + Context context = image.getContext(); + Provider provider = context.getProvider(); + ImageService service = context.getImageService(); + String msg; + + long endTime = System.currentTimeMillis() + (timeout * 1000); // + + while (rc.attempt()) { + try { + try { + image.waitForStateChange(pollInterval, timeout, desiredStates); + break; + } catch (TimeoutException e) { + @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") + List<String> list = new ArrayList<>(); + for (Image.Status desiredState : desiredStates) { + list.add(desiredState.name()); + } + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } catch (ZoneException e) { + List<String> list = new ArrayList<>(); + for (Image.Status desiredState : desiredStates) { + list.add(desiredState.name()); + } + String reason = EELFResourceManager.format(Msg.STATE_CHANGE_EXCEPTION, e.getClass().getSimpleName(), + "server", image.getName(), image.getId(), StringHelper.asList(list), image.getStatus().name(), + e.getMessage()); + logger.error(reason); + logger.error(EELFResourceManager.format(e)); + + // Instead of failing we are going to wait and try again. + // Timeout is reduced by delay time + logger.info(String.format("Retrying in %ds", rc.getRetryDelay())); + rc.delay(); + timeout = (int) (endTime - System.currentTimeMillis()) / 1000; + // throw new RequestFailedException(e, operation, reason, + // HttpStatus.BAD_GATEWAY_502, server); + } + } + + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + throw new RequestFailedException("Waiting for State Change", msg, HttpStatus.BAD_GATEWAY_502, new Server()); + } + rc.reset(); + } + + /** + * Rebuild the indicated server with the indicated image. This method assumes the server has been determined to be + * in the correct state to do the rebuild. + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * the server to be rebuilt + * @param image + * The image to be used (or snapshot) + * @throws RequestFailedException + * if the server does not change state in the allotted time + */ + @SuppressWarnings("nls") + private void rebuildServer(RequestContext rc, Server server, String image) throws RequestFailedException { + String msg; + Context context = server.getContext(); + Provider provider = context.getProvider(); + ComputeService service = context.getComputeService(); + + try { + while (rc.attempt()) { + try { + server.rebuild(image); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } + + /* + * We need to provide some time for OpenStack to start processing the request. + */ + try { + Thread.sleep(10L * 1000L); + } catch (InterruptedException e) { + logger.trace("Sleep threw interrupted exception, should never occur"); + } + } catch (ZoneException e) { + msg = + EELFResourceManager.format(Msg.REBUILD_SERVER_FAILED, server.getName(), server.getId(), e.getMessage()); + logger.error(msg); + throw new RequestFailedException("Rebuild Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + + /* + * Once we have started the process, now we wait for the final state of stopped. This should be the final state + * (since we started the rebuild with the server stopped). + */ + waitForStateChange(rc, server, Status.READY); + + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + throw new RequestFailedException("Rebuild Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + } + + /** + * Looks up the indicated server using the provided context and returns the server to the caller + * + * @param rc + * The request context + * @param context + * The provider context + * @param id + * The id of the server + * @return The server, or null if there is a problem + * @throws ZoneException + * If the server cannot be found + * @throws RequestFailedException + * If the server cannot be found because we cant connect to the provider + */ + @SuppressWarnings("nls") + private Server lookupServer(RequestContext rc, Context context, String id) + throws ZoneException, RequestFailedException { + ComputeService service = context.getComputeService(); + Server server = null; + String msg; + Provider provider = context.getProvider(); + + while (rc.attempt()) { + try { + server = service.getServer(id); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg); + throw new RequestFailedException("Lookup Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + return server; + } + + private String getConnectionExceptionMessage(RequestContext rc, Context ctx, ContextConnectionException e) + throws ZoneException { + return EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, ctx.getProvider().getName(), + ctx.getComputeService().getURL(), ctx.getTenant().getName(), ctx.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + } + + private ProviderCache createProviderCache(VMURL vm, IdentityURL ident) { + if (vm != null && ident != null) { + ProviderCache cache = new ProviderCache(); + + cache.setIdentityURL(ident.toString()); + cache.setProviderName(ident.toString()); + // cache.setProviderType("OpenStack"); + + TenantCache tenant = cache.addTenant(vm.getTenantId(),null, DEFAULT_USER, DEFAULT_PASS); + + // Make sure we could initialize the the cache otherwise return null + if (tenant != null && tenant.isInitialized()) { + return cache; + } + } + return null; + } + + /** + * This method is used to delete an existing virtual machine given the fully qualified URL of the machine. + * <p> + * The fully qualified URL contains enough information to locate the appropriate server. The URL is of the form + * <pre> + * [scheme]://[host[:port]] / [path] / [tenant_id] / servers / [vm_id] + * </pre> Where the various parts of the URL can be parsed and extracted and used to locate the appropriate service + * in the provider service catalog. This then allows us to open a context using the CDP abstraction, obtain the + * server by its UUID, and then perform the restart. + * </p> + * + * @throws UnknownProviderException + * If the provider cannot be found + * @throws IllegalArgumentException + * if the expected argument(s) are not defined or are invalid + * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#terminateServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) + */ + @SuppressWarnings("nls") + @Override + public Server terminateServer(Map<String, String> params, SvcLogicContext ctx) + throws UnknownProviderException, IllegalArgumentException { + Server server = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + MDC.put(MDC_ADAPTER, ADAPTER_NAME); + MDC.put(MDC_SERVICE, TERMINATE_SERVICE); + MDC.put(MDC_SERVICE_NAME, "App-C IaaS Adapter:Terminate"); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + if (logger.isDebugEnabled()) { + logger.debug("Inside org.openecomp.appc.adapter.iaas.impl.ProviderAdapter.terminateServer"); + } + + try { + validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + debugParameters(params); + debugContext(ctx); + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + ctx.setAttribute("TERMINATE_STATUS", "SUCCESS"); + + VMURL vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); + String identStr = (ident == null) ? null : ident.toString(); + + Context context = null; + try { + context = getContext(rc, vm_url, identStr); + if (context != null) { + server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + logger.info(EELFResourceManager.format(Msg.TERMINATING_SERVER, server.getName())); + terminateServer(rc, server); + logger.info(EELFResourceManager.format(Msg.TERMINATE_SERVER, server.getName())); + context.close(); + doSuccess(rc); + }else{ + ctx.setAttribute("TERMINATE_STATUS", "SERVER_NOT_FOUND"); + } + } catch (ResourceNotFoundException e) { + String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + ctx.setAttribute("TERMINATE_STATUS", "SERVER_NOT_FOUND"); + } catch (Throwable t) { + String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + RESTART_SERVICE, vm_url, context == null ? "Unknown" : context.getTenantName()); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + logger.error(EELFResourceManager.format(Msg.TERMINATE_SERVER_FAILED, appName, "n/a", "n/a", e.getMessage())); + doFailure(rc, e.getStatus(), e.getMessage()); + ctx.setAttribute("TERMINATE_STATUS", "ERROR"); + } + + return server; + } + + /** + * This method handles the case of restarting a server once we have found the server and have obtained the abstract + * representation of the server via the context (i.e., the "Server" object from the CDP-Zones abstraction). + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * The server object representing the server we want to operate on + * @throws ZoneException + */ + @SuppressWarnings("nls") + private void terminateServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { + /* + * Pending is a bit of a special case. If we find the server is in a pending state, then the provider is in the + * process of changing state of the server. So, lets try to wait a little bit and see if the state settles down + * to one we can deal with. If not, then we have to fail the request. + */ + String msg; + if (server.getStatus().equals(Status.PENDING)) { + waitForStateChange(rc, server, Status.READY, Status.RUNNING, Status.ERROR, Status.SUSPENDED, Status.PAUSED); + } + + /* + * We determine what to do based on the current state of the server + */ + switch (server.getStatus()) { + case DELETED: + // Nothing to do, the server is gone + msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(), + server.getTenantId(), "restarted"); + generateEvent(rc, false, msg); + logger.error(msg); + break; + + case RUNNING: + // Attempt to stop and start the server + logger.info("stopping SERVER"); + stopServer(rc, server); + deleteServer(rc, server); + logger.info("after delete SERVER"); + generateEvent(rc, true, OUTCOME_SUCCESS); + break; + + case ERROR: + + case READY: + + case PAUSED: + + case SUSPENDED: + // Attempt to delete the suspended server + deleteServer(rc, server); + generateEvent(rc, true, OUTCOME_SUCCESS); + break; + + default: + // Hmmm, unknown status, should never occur + msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(), + server.getTenantId(), server.getStatus().name()); + generateEvent(rc, false, msg); + logger.error(msg); + break; + } + + } + + /** + * Start the server and wait for it to enter a running state + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * The server to be started + * @throws ZoneException + * @throws RequestFailedException + */ + @SuppressWarnings("nls") + private void deleteServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { + String msg; + Context context = server.getContext(); + Provider provider = context.getProvider(); + ComputeService service = context.getComputeService(); + while (rc.attempt()) { + try { + logger.info("deleting SERVER"); + server.delete(); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + throw new RequestFailedException("Delete Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + } + + private boolean hasImageAccess(@SuppressWarnings("unused") RequestContext rc, Context context) { + logger.info("Checking permissions for image service."); + try { + ImageService service = context.getImageService(); + service.getImageByName("CHECK_IMAGE_ACCESS"); + logger.info("Image service is accessible."); + return true; + } catch (ZoneException e) { + logger.warn("Image service could not be accessed. Some operations may fail.", e); + return false; + } + } + + @SuppressWarnings("nls") + @Override + public Stack terminateStack(Map<String, String> params, SvcLogicContext ctx) throws IllegalArgumentException, APPCException { + Stack stack = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + ctx.setAttribute("TERMINATE_STATUS", "STACK_NOT_FOUND"); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + + try { + + logAndValidate(params, ctx, rc, TERMINATE_STACK, "Terminate Stack", + ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME, + ProviderAdapter.PROPERTY_STACK_ID); + + String stackId = params.get(ProviderAdapter.PROPERTY_STACK_ID); + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + + Context context = resolveContext(rc, params, appName, vm_url); + + try { + if (context != null) { + stack = lookupStack(rc, context, stackId); + logger.debug(Msg.STACK_FOUND, vm_url, context.getTenantName(), stack.getStatus().toString()); + logger.info(EELFResourceManager.format(Msg.TERMINATING_STACK, stack.getName())); + deleteStack(rc, stack); + logger.info(EELFResourceManager.format(Msg.TERMINATE_STACK, stack.getName())); + context.close(); + doSuccess(rc); + }else{ + ctx.setAttribute("TERMINATE_STATUS", "SERVER_NOT_FOUND"); + } + } catch (ResourceNotFoundException e) { + String msg = EELFResourceManager.format(Msg.STACK_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + } catch (Throwable t) { + String msg = EELFResourceManager.format(Msg.STACK_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + TERMINATE_STACK, vm_url, context.getTenantName()); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + logger.error(EELFResourceManager.format(Msg.TERMINATE_STACK_FAILED, appName, "n/a", "n/a")); + doFailure(rc, e.getStatus(), e.getMessage()); + } + return stack; + } + + @Override + public Stack snapshotStack(Map<String, String> params, SvcLogicContext ctx) throws IllegalArgumentException, APPCException { + Stack stack = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + ctx.setAttribute("SNAPSHOT_STATUS", "STACK_NOT_FOUND"); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + + String vm_url = null; + Context context = null; + try { + + logAndValidate(params, ctx, rc, SNAPSHOT_STACK, "Snapshot Stack", + ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME, + ProviderAdapter.PROPERTY_STACK_ID); + + String stackId = params.get(ProviderAdapter.PROPERTY_STACK_ID); + vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + + context = resolveContext(rc, params, appName, vm_url); + + if (context != null) { + stack = lookupStack(rc, context, stackId); + logger.debug(Msg.STACK_FOUND, vm_url, context.getTenantName(), stack.getStatus().toString()); + logger.info(EELFResourceManager.format(Msg.SNAPSHOTING_STACK, stack.getName())); + + Snapshot snapshot = snapshotStack(rc, stack); + + ctx.setAttribute(ProviderAdapter.DG_OUTPUT_PARAM_NAMESPACE + + ProviderAdapter.PROPERTY_SNAPSHOT_ID, snapshot.getId()); + + logger.info(EELFResourceManager.format(Msg.STACK_SNAPSHOTED, stack.getName(), snapshot.getId())); + context.close(); + doSuccess(rc); + } else { + ctx.setAttribute(Constants.DG_ATTRIBUTE_STATUS, "failure"); + } + + } catch (ResourceNotFoundException e) { + String msg = EELFResourceManager.format(Msg.STACK_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg, e); + } catch (RequestFailedException e) { + logger.error(EELFResourceManager.format(Msg.MISSING_PARAMETER_IN_REQUEST, e.getReason(), "snapshotStack")); + doFailure(rc, e.getStatus(), e.getMessage(), e); + } catch (Throwable t) { + String msg = EELFResourceManager.format(Msg.STACK_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + "snapshotStack", vm_url, null == context ? "n/a" : context.getTenantName()); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg, t); + } + return stack; + } + + @Override + public Stack restoreStack(Map<String, String> params, SvcLogicContext ctx) throws IllegalArgumentException, APPCException { + Stack stack = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + ctx.setAttribute("SNAPSHOT_STATUS", "STACK_NOT_FOUND"); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + + String vm_url = null; + Context context = null; + + try { + + logAndValidate(params, ctx, rc, SNAPSHOT_STACK, "Snapshot Stack", + ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME, + ProviderAdapter.PROPERTY_STACK_ID, + ProviderAdapter.PROPERTY_INPUT_SNAPSHOT_ID); + + String stackId = params.get(ProviderAdapter.PROPERTY_STACK_ID); + vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + + String snapshotId = params.get(ProviderAdapter.PROPERTY_INPUT_SNAPSHOT_ID); + + context = resolveContext(rc, params, appName, vm_url); + + if (context != null) { + stack = lookupStack(rc, context, stackId); + logger.debug(Msg.STACK_FOUND, vm_url, context.getTenantName(), stack.getStatus().toString()); + logger.info(EELFResourceManager.format(Msg.RESTORING_STACK, stack.getName(), snapshotId)); + restoreStack(stack, snapshotId); + logger.info(EELFResourceManager.format(Msg.STACK_RESTORED, stack.getName(), snapshotId)); + context.close(); + doSuccess(rc); + } else { + ctx.setAttribute(Constants.DG_ATTRIBUTE_STATUS, "failure"); + } + + } catch (ResourceNotFoundException e) { + String msg = EELFResourceManager.format(Msg.STACK_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg, e); + } catch (RequestFailedException e) { + logger.error(EELFResourceManager.format(Msg.MISSING_PARAMETER_IN_REQUEST, e.getReason(), "restoreStack")); + doFailure(rc, e.getStatus(), e.getMessage(), e); + } catch (Throwable t) { + String msg = EELFResourceManager.format(Msg.STACK_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + "restoreStack", vm_url, null == context ? "n/a" : context.getTenantName()); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg, t); + } + return stack; + } + + private void logAndValidate(Map<String, String> params, SvcLogicContext ctx, RequestContext rc, String methodName, String serviceName, String ... attributes) + throws RequestFailedException { + MDC.put(MDC_ADAPTER, ADAPTER_NAME); + MDC.put(MDC_SERVICE, SNAPSHOT_STACK); + MDC.put(MDC_SERVICE_NAME, String.format("App-C IaaS Adapter:%s", serviceName)); + if (logger.isDebugEnabled()) { + logger.debug(String.format("Inside org.openecomp.appc.adapter.iaas.impl.ProviderAdapter.%s", methodName)); + } + + validateParametersExist(rc, params, attributes); + + debugParameters(params); + debugContext(ctx); + } + + private Context resolveContext(RequestContext rc, Map<String, String> params, String appName, String vm_url) + throws RequestFailedException { + + VMURL vm = VMURL.parseURL(vm_url); + if (vm == null) { + String msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, vm_url); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + logger.error(msg); + return null; + } + validateVMURL(vm); + IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); + String identStr = (ident == null) ? null : ident.toString(); + + return getContext(rc, vm_url, identStr); + + } + + private void deleteStack(RequestContext rc, Stack stack) throws ZoneException, RequestFailedException { + SvcLogicContext ctx = rc.getSvcLogicContext(); + Context context = stack.getContext(); + StackService stackService = context.getStackService(); + logger.debug("Deleting Stack: " + "id:{ " + stack.getId() + "}"); + stackService.deleteStack(stack); + + // wait for the stack deletion + boolean success = waitForStackStatus(rc, stack, Stack.Status.DELETED); + if (success) { + ctx.setAttribute("TERMINATE_STATUS", "SUCCESS"); + } else { + ctx.setAttribute("TERMINATE_STATUS", "ERROR"); + throw new RequestFailedException("Delete Stack failure : " + Msg.STACK_OPERATION_EXCEPTION.toString()); + } + } + + private boolean waitForStackStatus(RequestContext rc, Stack stack, Stack.Status expectedStatus) throws ZoneException, RequestFailedException { + SvcLogicContext ctx = rc.getSvcLogicContext(); + Context context = stack.getContext(); + StackService stackService = context.getStackService(); + + int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL); + int timeout = configuration.getIntegerProperty(Constants.PROPERTY_STACK_STATE_CHANGE_TIMEOUT); + long maxTimeToWait = System.currentTimeMillis() + (long) timeout * 1000; + Stack.Status stackStatus; + while (System.currentTimeMillis() < maxTimeToWait) { + stackStatus = stackService.getStack(stack.getName(), stack.getId()).getStatus(); + logger.debug("Stack status : " + stackStatus.toString()); + if (stackStatus == expectedStatus) { + return true; + } else if (stackStatus == Stack.Status.FAILED) { + return false; + } else { + try { + Thread.sleep(pollInterval * 1000); + } catch (InterruptedException e) { + logger.trace("Sleep threw interrupted exception, should never occur"); + } + } + } + + ctx.setAttribute("TERMINATE_STATUS", "ERROR"); + throw new TimeoutException("Timeout waiting for stack status change"); + + } + + private Snapshot snapshotStack(@SuppressWarnings("unused") RequestContext rc, Stack stack) throws ZoneException, RequestFailedException { + Snapshot snapshot = new Snapshot(); + Context context = stack.getContext(); + + OpenStackContext osContext = (OpenStackContext)context; + + final HeatConnector heatConnector = osContext.getHeatConnector(); + ((OpenStackContext)context).refreshIfStale(heatConnector); + + trackRequest(context); + RequestState.put("SERVICE", "Orchestration"); + RequestState.put("SERVICE_URL", heatConnector.getEndpoint()); + + Heat heat = heatConnector.getClient(); + + SnapshotResource snapshotResource = new SnapshotResource(heat); + + try { + + snapshot = snapshotResource.create(stack.getName(), stack.getId(), new CreateSnapshotParams()).execute(); + + // wait for the stack deletion + StackResource stackResource = new StackResource(heat); + if (!waitForStack(stack, stackResource, "SNAPSHOT_COMPLETE")) { + throw new RequestFailedException("Stack Snapshot failed."); + } + + } catch (OpenStackBaseException e) { + ExceptionMapper.mapException(e); + } + + return snapshot; + } + + private void restoreStack(Stack stack, String snapshotId) throws ZoneException, RequestFailedException { + Context context = stack.getContext(); + + OpenStackContext osContext = (OpenStackContext)context; + + final HeatConnector heatConnector = osContext.getHeatConnector(); + ((OpenStackContext)context).refreshIfStale(heatConnector); + + trackRequest(context); + RequestState.put("SERVICE", "Orchestration"); + RequestState.put("SERVICE_URL", heatConnector.getEndpoint()); + + Heat heat = heatConnector.getClient(); + + SnapshotResource snapshotResource = new SnapshotResource(heat); + + try { + + snapshotResource.restore(stack.getName(), stack.getId(), snapshotId).execute(); + + // wait for the snapshot restore + StackResource stackResource = new StackResource(heat); + if (!waitForStack(stack, stackResource, "RESTORE_COMPLETE")) { + throw new RequestFailedException("Snapshot restore failed."); + } + + } catch (OpenStackBaseException e) { + ExceptionMapper.mapException(e); + } + + } + + private boolean waitForStack(Stack stack, StackResource stackResource, String expectedStatus) + throws OpenStackBaseException, TimeoutException { + int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL); + int timeout = configuration.getIntegerProperty(Constants.PROPERTY_STACK_STATE_CHANGE_TIMEOUT); + long maxTimeToWait = System.currentTimeMillis() + (long) timeout * 1000; + + while (System.currentTimeMillis() < maxTimeToWait) { + String stackStatus = stackResource.show(stack.getName(), stack.getId()).execute().getStackStatus(); + logger.debug("Stack status : " + stackStatus); + if (stackStatus.toUpperCase().contains("FAILED")) return false; + if(checkStatus(expectedStatus, pollInterval, stackStatus)) return true; + } + throw new TimeoutException("Timeout waiting for stack status change"); + } + + private boolean checkStatus(String expectedStatus, int pollInterval, String actualStatus) { + if (actualStatus.toUpperCase().equals(expectedStatus)) { + return true; + } else { + try { + Thread.sleep(pollInterval * 1000); + } catch (InterruptedException ignored) { + } + } + return false; + } + + private void trackRequest(Context context, AbstractService.State... states) { + RequestState.clear(); + + if (null == states) return; + for (AbstractService.State state : states) { + RequestState.put(state.getName(), state.getValue()); + } + + Thread currentThread = Thread.currentThread(); + StackTraceElement[] stack = currentThread.getStackTrace(); + if (stack != null && stack.length > 0) { + int index = 0; + StackTraceElement element; + for (; index < stack.length; index++) { + element = stack[index]; + if ("trackRequest".equals(element.getMethodName())) { //$NON-NLS-1$ + break; + } + } + index++; + + if (index < stack.length) { + element = stack[index]; + RequestState.put(RequestState.METHOD, element.getMethodName()); + RequestState.put(RequestState.CLASS, element.getClassName()); + RequestState.put(RequestState.LINE_NUMBER, Integer.toString(element.getLineNumber())); + RequestState.put(RequestState.THREAD, currentThread.getName()); + RequestState.put(RequestState.PROVIDER, context.getProvider().getName()); + RequestState.put(RequestState.TENANT, context.getTenantName()); + RequestState.put(RequestState.PRINCIPAL, context.getPrincipal()); + } + } + } + + private Stack lookupStack(RequestContext rc, Context context, String id) + throws ZoneException, RequestFailedException { + StackService stackService = context.getStackService(); + Stack stack = null; + String msg; + Provider provider = context.getProvider(); + while (rc.attempt()) { + try { + List<Stack> stackList = stackService.getStacks(); + for (Stack stackObj : stackList) { + if (stackObj.getId().equals(id)) { + stack = stackObj; + break; + } + } + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), stackService.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), stackService.getURL()); + logger.error(msg); + doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg); + throw new RequestFailedException("Lookup Stack", msg, HttpStatus.BAD_GATEWAY_502, stack); + } + + if (stack == null) { + throw new ResourceNotFoundException("Stack not found with Id : {" + id + "}"); + } + return stack; + } + + @SuppressWarnings("nls") + @Override + public Server lookupServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + Server server = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); //should we test the return and fail if false? + MDC.put(MDC_ADAPTER, ADAPTER_NAME); + MDC.put(MDC_SERVICE, LOOKUP_SERVICE); + MDC.put(MDC_SERVICE_NAME, "App-C IaaS Adapter:LookupServer"); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + + //for debugging merge into single method? + debugParameters(params); + debugContext(ctx); + + String vm_url = null; + VMURL vm = null; + try { + + //process vm_url + validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + + //use try with resource to ensure context is closed (returned to pool) + try(Context context = resolveContext(rc, params, appName, vm_url)){ + //resloveContext & getContext call doFailure and log errors before returning null + if (context != null){ + server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + ctx.setAttribute("serverFound", "success"); + doSuccess(rc); + } + } catch (ZoneException e) { + //server not found + String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + ctx.setAttribute("serverFound", "failure"); + } catch (IOException e) { + //exception closing context + String msg = EELFResourceManager.format(Msg.CLOSE_CONTEXT_FAILED, e, vm_url); + logger.error(msg); + } catch (Throwable t) { + String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + LOOKUP_SERVICE, vm_url, "Unknown" ); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + + } catch (RequestFailedException e) { + // parameters not valid, unable to connect to provider + String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + ctx.setAttribute("serverFound", "failure"); + } + return server; + } +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/ProviderCache.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/ProviderCache.java new file mode 100644 index 000000000..c70875da0 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/ProviderCache.java @@ -0,0 +1,164 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.iaas.impl; + +import java.util.HashMap; +import java.util.Map; + +/** + * This class maintains a cache of information by provider, where a provider is identified by both a type and an + * identity URL used to connect to that provider. + * <p> + * Providers may be multi-tenant, such as OpenStack, where the available services and resources vary from one tenant to + * another. Therefore, the provider cache maintains a cache of tenants and the service catalogs for each, as well as the + * credentials used to access the tenants, and a pool of Context objects for each tenant. The context pool allows use of + * the CDP abstraction layer to access the services of the provider within the specific tenant. + * </p> + */ +public class ProviderCache { + + /** + * The type of provider (e.g., OpenStackProvider) used to setup the CDP abstraction layer and load the appropriate + * support + */ + private String providerType; + + /** + * The URL of the provider's identity service or whatever service is used to login and authenticate to the provider + */ + private String identityURL; + + /** + * A string used to identify the provider instance + */ + private String providerName; + + /** + * The map of tenant cache objects by tenant id + */ + private Map<String /* tenant id */, TenantCache> tenants = new HashMap<String, TenantCache>(); + + /** + * @return the value of providerType + */ + public String getProviderType() { + return providerType; + } + + /** + * This method is called to initialize the provider cache, set up the context pools for each of the tenants, + * discover all of the regions supported on the provider, and load all of the service catalogs for each provider. + */ + public void initialize() { + for (Map.Entry<String, TenantCache> entry: tenants.entrySet()) { + entry.getValue().initialize(); + } + } + + /** + * @param providerType + * the value for providerType + */ + public void setProviderType(String providerType) { + this.providerType = providerType; + } + + /** + * @return the value of identityURL + */ + public String getIdentityURL() { + return identityURL; + } + + /** + * @param identityURL + * the value for identityURL + */ + public void setIdentityURL(String identityURL) { + this.identityURL = identityURL; + } + + /** + * @return the value of providerName + */ + public String getProviderName() { + return providerName; + } + + /** + * @param providerName + * the value for providerName + */ + public void setProviderName(String providerName) { + this.providerName = providerName; + } + + /** + * @return the value of tenants + */ + public Map<String, TenantCache> getTenants() { + return tenants; + } + + /** + * This method is a helper to return a specific TenantCache + * + * @param tenantId + * @return + */ + public TenantCache getTenant(String tenantId){ + return tenants.get(tenantId); + } + + // Previously there was no way to add additional tenants to the tenant cache + /** + * This method is used to add a tenant to the provider cache + * + * @param tenantId + * @param UserId + * @param password + * @return the new initialized TenantCache or null if unsuccessful + */ + public TenantCache addTenant(String tenantId, String tenantName, String userId, String password){ + if(tenantId != null || tenantName != null && userId != null && password != null){ + TenantCache tenant = new TenantCache(this); + if(tenantId != null){ + tenant.setTenantId(tenantId); + } + if(tenantName != null){ + tenant.setTenantName(tenantName); + } + tenant.setUserid(userId); + tenant.setPassword(password); + + if(identityURL != null){ + tenant.initialize(); + } + + if (tenant.isInitialized()) { + tenants.put(tenant.getTenantId(), tenant); + return tenant; + } + } + return null; + } +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/RequestContext.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/RequestContext.java new file mode 100644 index 000000000..395d37847 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/RequestContext.java @@ -0,0 +1,250 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + +package org.openecomp.appc.adapter.iaas.impl; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.sdnc.sli.SvcLogicContext; + +/** + * This class is used to track and maintain recovery and time-to-live information for a request as it is being + * processed. + */ +public class RequestContext { + /** + * The number of seconds of wait time between successive attempts to connect to the provider. This is used to + * recover from provider outages or failures. It is not used to recover from logical errors, such as an invalid + * request, server not found, etc. + */ + private Integer retryDelay; + + /** + * The number of times we will attempt to connect to the provider. This is used to recover from provider outages or + * failures. It is not used to recover from logical errors, such as an invalid request, server not found, etc. + */ + private Integer retryLimit; + + /** + * The total time, in milliseconds, that the provider can have to process this request. If the accumulated time + * exceeds the time to live, then the request is failed with a timeout exception, regardless of the state of the + * provider. Note that the caller may supply this as a value in seconds, in which case it must be converted to + * milliseconds for the request context. + */ + private Long timeToLive; + + /** + * The accumulated time, in milliseconds, that has been used so far to process the request. This is compared to the + * time to live each time it is updated. If the accumulated time exceeds the time to live, then the request is + * failed with a timeout exception, regardless of the state of the provider. + */ + private long accumulatedTime; + + /** + * The total number of retries attempted so far + */ + private int attempt; + + /** + * The time when the stopwatch was started + */ + private long startTime = -1; + + /** + * The service logic (DG) context from the SLI + */ + private SvcLogicContext svcLogicContext; + + /** + * The configuration + */ + private Configuration configuration = ConfigurationFactory.getConfiguration(); + + /** + * Set to true whenever the retry limit has been exceeded, reset to false when reset() is called. + */ + private boolean retryFailed; + + /** + * Creates the request context + * + * @param context + * The service logic (SLI) context associated with the current DG + */ + public RequestContext(SvcLogicContext context) { + setSvcLogicContext(context); + } + + /** + * @return The retry delay, in seconds. If zero, then no retry is to be performed + */ + public int getRetryDelay() { + if (retryDelay == null) { + int value = configuration.getIntegerProperty(Constants.PROPERTY_RETRY_DELAY); + retryDelay = Integer.valueOf(value); + } + + return retryDelay.intValue(); + } + + /** + * This method is a helper that allows the caller to delay for the retry interval time and not have to handle the + * thread interruption, timer handling, etc. + */ + public void delay() { + long time = getRetryDelay() * 1000L; + long future = System.currentTimeMillis() + time; + if (time != 0) { + while (System.currentTimeMillis() < future && time > 0) { + try { + Thread.sleep(time); + } catch (InterruptedException e) { + /* + * This is rare, but it can happen if another thread interrupts us while we are sleeping. In that + * case, the thread is resumed before the delay time has actually expired, so re-calculate the + * amount of delay time needed and reenter the sleep until we get to the future time. + */ + time = future - System.currentTimeMillis(); + } + } + } + } + + /** + * @return The number of retries that are allowed per connection + */ + public int getRetryLimit() { + if (retryLimit == null) { + int value = configuration.getIntegerProperty(Constants.PROPERTY_RETRY_LIMIT); + retryLimit = Integer.valueOf(value); + } + + return retryLimit.intValue(); + } + + /** + * Check and count the connection attempt. + * + * @return True if the connection should be attempted. False indicates that the number of retries has been exhausted + * and it should NOT be attempted. + */ + public boolean attempt() { + if (retryFailed || attempt >= getRetryLimit()) { + retryFailed = true; + return false; + } + attempt++; + + return true; + } + + /** + * @return The number of retry attempts so far + */ + public int getAttempts() { + return attempt; + } + + /** + * @return True if the retry limit has been exceeded, false otherwise + */ + public boolean isFailed() { + return retryFailed; + } + + /** + * This method both checks the time to live to see if it has been exceeded and accumulates the total time used so + * far. + * <p> + * Each time this method is called it accumulates the total duration since the last time it was called to the total + * time accumulator. It then checks the total time to the time to live and if greater, it returns false. As long as + * the total time used is less than or equal to the time to live limit, the method returns true. It is important to + * call this method at the very beginning of the process so that all parts of the process are tracked. + * </p> + * + * @return True if the total time to live has not been exceeded. False indicates that the total time to live has + * been exceeded and no further processing should be performed. + */ + public boolean isAlive() { + long now = System.currentTimeMillis(); + if (startTime == -1) { + startTime = now; + return true; + } + accumulatedTime += (now - startTime); + startTime = now; + if (accumulatedTime > timeToLive) { + return false; + } + return true; + } + + /** + * @return The total amount of time used, in milliseconds. + */ + public long getTotalDuration() { + return accumulatedTime; + } + + /** + * This method is called to reset the retry counters. It has no effect on the time to live accumulator. + */ + public void reset() { + attempt = 0; + } + + /** + * Sets the time to live to the value, expressed in seconds + * + * @param time + * The time to live, in seconds + */ + public void setTimeToLiveSeconds(int time) { + setTimeToLiveMS(time * 1000L); + } + + /** + * Sets the time to live to the value, expressed in milliseconds + * + * @param time + * The time to live, in milliseconds + */ + public void setTimeToLiveMS(long time) { + this.timeToLive = time; + } + + /** + * @return The service logic context associated with this request + */ + public SvcLogicContext getSvcLogicContext() { + return svcLogicContext; + } + + /** + * @param svcLogicContext + * The service logic context to be associated with this request + */ + public void setSvcLogicContext(SvcLogicContext svcLogicContext) { + this.svcLogicContext = svcLogicContext; + } +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/RequestFailedException.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/RequestFailedException.java new file mode 100644 index 000000000..c7e7e93c8 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/RequestFailedException.java @@ -0,0 +1,277 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.iaas.impl; + +import org.glassfish.grizzly.http.util.HttpStatus; +import com.att.cdp.zones.model.Server; +import com.att.cdp.zones.model.Stack; + +/** + * This class is used to capture the exact cause and point of failure for the processing of a request. It is then used + * to encode the reason for the failure, status code, and anything else that needs to be captured and reported for + * diagnostic purposes. + */ +public class RequestFailedException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * The operation that was being requested or performed at the time of the failure. + */ + private String operation; + + /** + * A message that details the reason for the failure + */ + private String reason; + + /** + * The server that was being operated upon + */ + private Server server; + + /** + * The stack that was being operated upon + */ + private Stack stack; + /** + * The id of the server being operated upon if the server object is not available (such as the server was not found) + */ + private String serverId; + + /** + * The id of the stack being operated upon if the stack object is not available (such as the stack was not found) + */ + private String stackId; + /** + * The most appropriate Http Status code that reflects the error + */ + private HttpStatus status; + + /** + * + */ + public RequestFailedException() { + // intentionally empty + } + + /** + * @param message + * The error message + */ + public RequestFailedException(String message) { + super(message); + } + + /** + * Construct the request failed exception with the operation being performed, reason for the failure, http status + * code that is most appropriate, and the server we were processing. + * + * @param operation + * The operation being performed + * @param reason + * The reason that the operation was failed + * @param status + * The http status code that is most appropriate + * @param server + * The server that we were processing + */ + @SuppressWarnings("nls") + public RequestFailedException(String operation, String reason, HttpStatus status, Server server) { + super(operation + ":" + reason); + this.operation = operation; + this.reason = reason; + this.status = status; + this.server = server; + if (server != null) { + this.serverId = server.getId(); + } + } + + + /** + * Construct the request failed exception with the operation being performed, reason for the failure, http status + * code that is most appropriate, and the stack we were processing. + * + * @param operation + * The operation being performed + * @param reason + * The reason that the operation was failed + * @param status + * The http status code that is most appropriate + * @param stack + * The stack that we were processing + */ + @SuppressWarnings("nls") + public RequestFailedException(String operation, String reason, HttpStatus status, Stack stack) { + super(operation + ":" + reason); + this.operation = operation; + this.reason = reason; + this.status = status; + this.stack = stack; + if (stack != null) { + this.stackId = stack.getId(); + } + } + + /** + * Construct the request failed exception with the operation being performed, reason for the failure, http status + * code that is most appropriate, and the server we were processing. + * + * @param ex + * The exception that we are wrapping + * @param operation + * The operation being performed + * @param reason + * The reason that the operation was failed + * @param status + * The http status code that is most appropriate + * @param server + * The server that we were processing + */ + @SuppressWarnings("nls") + public RequestFailedException(Throwable ex, String operation, String reason, HttpStatus status, Server server) { + super(operation + ":" + reason, ex); + this.operation = operation; + this.reason = reason; + this.status = status; + this.server = server; + if (server != null) { + this.serverId = server.getId(); + } + } + + /** + * @param message + * The error message + * @param cause + * A nested exception + */ + public RequestFailedException(String message, Throwable cause) { + super(message, cause); + } + + /** + * @param message + * The error message + * @param cause + * A nested exception + * @param enableSuppression + * whether or not suppression is enabled or disabled + * @param writableStackTrace + * whether or not the stack trace should be writable + */ + public RequestFailedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + /** + * @param cause + * the cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or unknown.) + */ + public RequestFailedException(Throwable cause) { + super(cause); + } + + /** + * @return The operation being performed + */ + public String getOperation() { + return operation; + } + + /** + * @return The reason for the failure + */ + public String getReason() { + return reason; + } + + /** + * @return The server being operated upon + */ + public Server getServer() { + return server; + } + + /** + * @return The id of the server being operated upon + */ + public String getServerId() { + return serverId; + } + + /** + * @return The status code from the operation + */ + public HttpStatus getStatus() { + return status; + } + + /** + * @param operation + * The operation being performed + */ + public void setOperation(String operation) { + this.operation = operation; + } + + /** + * @param reason + * The reason for the failure + */ + public void setReason(String reason) { + this.reason = reason; + } + + /** + * @param server + * The server being operated upon + */ + public void setServer(Server server) { + this.server = server; + if (server != null) { + setServerId(server.getId()); + } + } + + /** + * @param serverId + * The id of the server being operated upon + */ + public void setServerId(String serverId) { + this.serverId = serverId; + } + + /** + * @param status + * The status of the request + */ + public void setStatus(HttpStatus status) { + this.status = status; + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/ServiceCatalog.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/ServiceCatalog.java new file mode 100644 index 000000000..8ac81b2b9 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/ServiceCatalog.java @@ -0,0 +1,488 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.iaas.impl; + +import java.net.NoRouteToHostException; +import java.net.SocketException; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import com.att.cdp.exceptions.ContextConnectionException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.openstack.util.ExceptionMapper; +import com.att.cdp.pal.util.Time; +import com.att.cdp.zones.ContextFactory; +import com.att.cdp.zones.spi.AbstractService; +import com.att.cdp.zones.spi.RequestState; +import com.att.cdp.zones.spi.AbstractService.State; + +import com.sun.jersey.api.client.ClientHandlerException; +import com.woorea.openstack.base.client.OpenStackBaseException; +import com.woorea.openstack.base.client.OpenStackClientConnector; +import com.woorea.openstack.base.client.OpenStackResponseException; +import com.woorea.openstack.base.client.OpenStackSimpleTokenProvider; +import com.woorea.openstack.keystone.Keystone; +import com.woorea.openstack.keystone.api.TokensResource; +import com.woorea.openstack.keystone.model.Access; +import com.woorea.openstack.keystone.model.Access.Service; +import com.woorea.openstack.keystone.model.Access.Service.Endpoint; +import com.woorea.openstack.keystone.model.Authentication; +import com.woorea.openstack.keystone.model.Tenant; +import com.woorea.openstack.keystone.model.authentication.UsernamePassword; + +/** + * This class is used to capture and cache the service catalog for a specific OpenStack provider. + * <p> + * This is needed because the way the servers are represented in the ECOMP product is as their fully qualified URL's. + * This is very problematic, because we cant identify their region from the URL, URL's change, and we cant identify the + * versions of the service implementations. In otherwords, the URL does not provide us enough information. + * </p> + * <p> + * The zone abstraction layer is designed to detect the versions of the services dynamically, and step up or down to + * match those reported versions. In order to do that, we need to know before hand what region we are accessing (since + * the supported versions may be different by regions). We will need to authenticate to the identity service in order to + * do this, plus we have to duplicate the code supporting proxies and trusted hosts that exists in the abstraction + * layer, but that cant be helped. + * </p> + * <p> + * What we do to circumvent this is connect to the provider using the lowest supported identity api, and read the entire + * service catalog into this object. Then, we parse the vm URL to extract the host and port and match that to the + * compute services defined in the catalog. When we find a compute service that has the same host name and port, + * whatever region that service is supporting is the region for that server. + * </p> + * <p> + * While we really only need to do this for compute nodes, there is no telling what other situations may arise where the + * full service catalog may be needed. Also, there is very little additional cost (additional RAM) associated with + * caching the full service catalog since there is no way to list only a portion of it. + * </p> + */ +public class ServiceCatalog { + + /** + * The service name for the compute service endpoint + */ + public static final String COMPUTE_SERVICE = "compute"; //$NON-NLS-1$ + + /** + * The service name for the identity service endpoint + */ + public static final String IDENTITY_SERVICE = "identity"; //$NON-NLS-1$ + + /** + * The service name for the compute service endpoint + */ + public static final String IMAGE_SERVICE = "image"; //$NON-NLS-1$ + + /** + * The service name for the network service endpoint + */ + public static final String NETWORK_SERVICE = "network"; //$NON-NLS-1$ + + /** + * The service name for the orchestration service endpoint + */ + public static final String ORCHESTRATION_SERVICE = "orchestration"; //$NON-NLS-1$ + + /** + * The service name for the volume service endpoint + */ + public static final String VOLUME_SERVICE = "volume"; //$NON-NLS-1$ + + /** + * The service name for the persistent object service endpoint + */ + public static final String OBJECT_SERVICE = "object-store"; //$NON-NLS-1$ + + /** + * The service name for the metering service endpoint + */ + public static final String METERING_SERVICE = "metering"; //$NON-NLS-1$ + + /** + * The Openstack Access object that manages the authenticated token and access control + */ + private Access access; + + /** + * The time (local) that the token expires and we need to re-authenticate + */ + @SuppressWarnings("unused") + private long expiresLocal; + + /** + * The set of all regions that have been defined + */ + private Set<String> regions; + + /** + * The read/write lock used to protect the cache contents + */ + private ReadWriteLock rwLock; + + /** + * A map of endpoints for each service organized by service type + */ + private Map<String /* Service Type */, List<Service.Endpoint>> serviceEndpoints; + + /** + * A map of service types that are published + */ + private Map<String /* Service Type */, Service> serviceTypes; + + /** + * The tenant that we are accessing + */ + private Tenant tenant; + + /** + * A "token provider" that manages the authentication token that we obtain when logging in + */ + private OpenStackSimpleTokenProvider tokenProvider; + + public static final String CLIENT_CONNECTOR_CLASS = "com.woorea.openstack.connector.JerseyConnector"; + + /** + * Create the ServiceCatalog cache and load it from the specified provider + * + * @param identityURL + * The identity service URL to connect to + * @param tenantIdentifier + * The name or id of the tenant to authenticate with. If the ID is a UUID format (32-character + * hexadecimal string), then the authentication is done using the tenant ID, otherwise it is done using + * the name. + * @param principal + * The user id to authenticate to the provider + * @param credential + * The password to authenticate to the provider + * @param properties + * Additional properties used to configure the connection, such as proxy and trusted hosts lists + * @throws ZoneException + * @throws ClassNotFoundException + * @throws IllegalAccessException + * @throws InstantiationException + */ + public ServiceCatalog(String identityURL, String tenantIdentifier, String principal, String credential, + Properties properties) throws ZoneException { + rwLock = new ReentrantReadWriteLock(); + serviceTypes = new HashMap<>(); + serviceEndpoints = new HashMap<>(); + regions = new HashSet<>(); + + Class<?> connectorClass; + OpenStackClientConnector connector; + try { + connectorClass = Class.forName(CLIENT_CONNECTOR_CLASS); + connector = (OpenStackClientConnector) connectorClass.newInstance(); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + return; + } + Keystone keystone = new Keystone(identityURL, connector); + + String proxyHost = properties.getProperty(ContextFactory.PROPERTY_PROXY_HOST); + String proxyPort = properties.getProperty(ContextFactory.PROPERTY_PROXY_PORT); + String trustedHosts = properties.getProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS, ""); //$NON-NLS-1$ + if (proxyHost != null && proxyHost.length() > 0) { + keystone.getProperties().setProperty(com.woorea.openstack.common.client.Constants.PROXY_HOST, proxyHost); + keystone.getProperties().setProperty(com.woorea.openstack.common.client.Constants.PROXY_PORT, proxyPort); + } + if (trustedHosts != null) { + keystone.getProperties().setProperty(com.woorea.openstack.common.client.Constants.TRUST_HOST_LIST, + trustedHosts); + } + + Authentication authentication = new UsernamePassword(principal, credential); + TokensResource tokens = keystone.tokens(); + TokensResource.Authenticate authenticate = tokens.authenticate(authentication); + if (tenantIdentifier.length() == 32 && tenantIdentifier.matches("[0-9a-fA-F]+")) { //$NON-NLS-1$ + authenticate = authenticate.withTenantId(tenantIdentifier); + } else { + authenticate = authenticate.withTenantName(tenantIdentifier); + } + + /* + * We have to set up the TrackRequest TLS collection for the ExceptionMapper + */ + trackRequest(); + RequestState.put(RequestState.PROVIDER, "OpenStackProvider"); + RequestState.put(RequestState.TENANT, tenantIdentifier); + RequestState.put(RequestState.PRINCIPAL, principal); + + try { + access = authenticate.execute(); + expiresLocal = getLocalExpiration(access); + tenant = access.getToken().getTenant(); + tokenProvider = new OpenStackSimpleTokenProvider(access.getToken().getId()); + keystone.setTokenProvider(tokenProvider); + parseServiceCatalog(access.getServiceCatalog()); + } catch (OpenStackBaseException e) { + ExceptionMapper.mapException(e); + } catch (Exception ex) { + throw new ContextConnectionException(ex.getMessage()); + } + } + + /** + * Returns the list of service endpoints for the published service type + * + * @param serviceType + * The service type to obtain the endpoints for + * @return The list of endpoints for the service type, or null if none exist + */ + public List<Service.Endpoint> getEndpoints(String serviceType) { + Lock readLock = rwLock.readLock(); + readLock.lock(); + try { + return serviceEndpoints.get(serviceType); + } finally { + readLock.unlock(); + } + } + + /** + * Computes the local time when the access token will expire, after which we will need to re-login to access the + * provider. + * + * @param accessKey + * The access key used to access the provider + * @return The local time the key expires + */ + private static long getLocalExpiration(Access accessKey) { + Date now = Time.getCurrentUTCDate(); + if (accessKey != null && accessKey.getToken() != null) { + Calendar issued = accessKey.getToken().getIssued_at(); + Calendar expires = accessKey.getToken().getExpires(); + if (issued != null && expires != null) { + long tokenLife = expires.getTimeInMillis() - issued.getTimeInMillis(); + return now.getTime() + tokenLife; + } + } + return now.getTime(); + } + + /** + * @return The set of all regions that are defined + */ + public Set<String> getRegions() { + Lock readLock = rwLock.readLock(); + readLock.lock(); + try { + return regions; + } finally { + readLock.unlock(); + } + } + + /** + * @return A list of service types that are published + */ + public List<String> getServiceTypes() { + Lock readLock = rwLock.readLock(); + readLock.lock(); + try { + ArrayList<String> result = new ArrayList<>(); + result.addAll(serviceTypes.keySet()); + return result; + } finally { + readLock.unlock(); + } + } + + /** + * @return The tenant id + */ + public String getTenantId() { + Lock readLock = rwLock.readLock(); + readLock.lock(); + try { + return tenant.getId(); + } finally { + readLock.unlock(); + } + } + + /** + * @return The tenant name + */ + public String getTenantName() { + Lock readLock = rwLock.readLock(); + readLock.lock(); + try { + return tenant.getName(); + } finally { + readLock.unlock(); + } + } + + /** + * Returns an indication if the specified service type is published by this provider + * + * @param serviceType + * The service type to check for + * @return True if a service of that type is published + */ + public boolean isServicePublished(String serviceType) { + Lock readLock = rwLock.readLock(); + readLock.lock(); + try { + return serviceTypes.containsKey(serviceType); + } finally { + readLock.unlock(); + } + } + + /** + * Parses the service catalog and caches the results + * + * @param services + * The list of services published by this provider + */ + private void parseServiceCatalog(List<Service> services) { + Lock lock = rwLock.writeLock(); + lock.lock(); + try { + serviceTypes.clear(); + serviceEndpoints.clear(); + regions.clear(); + + for (Service service : services) { + String type = service.getType(); + serviceTypes.put(type, service); + + List<Service.Endpoint> endpoints = service.getEndpoints(); + for (Service.Endpoint endpoint : endpoints) { + List<Service.Endpoint> endpointList = serviceEndpoints.get(type); + if (endpointList == null) { + endpointList = new ArrayList<>(); + serviceEndpoints.put(type, endpointList); + } + endpointList.add(endpoint); + + String region = endpoint.getRegion(); + if (!regions.contains(region)) { + regions.add(region); + } + } + } + } finally { + lock.unlock(); + } + } + + /** + * This method is used to provide a diagnostic listing of the service catalog + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + + StringBuilder builder = new StringBuilder(); + Lock lock = rwLock.readLock(); + lock.lock(); + try { + builder.append(String.format("Service Catalog: tenant %s, id[%s], description[%s]\n", tenant.getName(), //$NON-NLS-1$ + tenant.getId(), tenant.getDescription())); + if (regions != null && !regions.isEmpty()) { + builder.append(String.format("%d regions:\n", regions.size())); //$NON-NLS-1$ + for (String region : regions) { + builder.append("\t" + region + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + builder.append(String.format("%d services:\n", serviceEndpoints.size())); //$NON-NLS-1$ + for (String serviceType : serviceEndpoints.keySet()) { + List<Endpoint> endpoints = serviceEndpoints.get(serviceType); + Service service = serviceTypes.get(serviceType); + + builder.append(String.format("\t%s [%s] - %d endpoints\n", service.getType(), service.getName(), //$NON-NLS-1$ + endpoints.size())); + for (Endpoint endpoint : endpoints) { + builder.append(String.format("\t\tRegion [%s], public URL [%s]\n", endpoint.getRegion(), //$NON-NLS-1$ + endpoint.getPublicURL())); + } + } + } finally { + lock.unlock(); + } + + return builder.toString(); + } + + /** + * Initializes the request state for the current requested service. + * <p> + * This method is used to track requests made to the various service implementations and to provide additional + * information for diagnostic purposes. The <code>RequestState</code> class stores the state in thread-local storage + * and is available to all code on that thread. + * </p> + * <p> + * This method first obtains the stack trace and scans the stack backward for the call to this method. It then backs + * up one more call and assumes that method is the request that we are "tracking". + * </p> + * + * @param states + * A variable argument list of additional state values that the caller wants to add to the request state + * thread-local object to track the context. + */ + protected void trackRequest(State... states) { + RequestState.clear(); + + for (State state : states) { + RequestState.put(state.getName(), state.getValue()); + } + + Thread currentThread = Thread.currentThread(); + StackTraceElement[] stack = currentThread.getStackTrace(); + if (stack != null && stack.length > 0) { + int index = 0; + StackTraceElement element = null; + for (; index < stack.length; index++) { + element = stack[index]; + if ("trackRequest".equals(element.getMethodName())) { //$NON-NLS-1$ + break; + } + } + index++; + + if (index < stack.length) { + element = stack[index]; + RequestState.put(RequestState.METHOD, element.getMethodName()); + RequestState.put(RequestState.CLASS, element.getClassName()); + RequestState.put(RequestState.LINE_NUMBER, Integer.toString(element.getLineNumber())); + RequestState.put(RequestState.THREAD, currentThread.getName()); + // RequestState.put(RequestState.PROVIDER, context.getProvider().getName()); + // RequestState.put(RequestState.TENANT, context.getTenantName()); + // RequestState.put(RequestState.PRINCIPAL, context.getPrincipal()); + } + } + } +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/TenantCache.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/TenantCache.java new file mode 100644 index 000000000..c0c114dc8 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/TenantCache.java @@ -0,0 +1,378 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.iaas.impl; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.i18n.Msg; +import org.openecomp.appc.pool.Allocator; +import org.openecomp.appc.pool.Destructor; +import org.openecomp.appc.pool.Pool; +import org.openecomp.appc.pool.PoolSpecificationException; +import com.att.cdp.exceptions.ContextConnectionException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.ContextFactory; +import com.att.cdp.zones.Provider; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import com.sun.jersey.api.client.ClientHandlerException; +import com.woorea.openstack.keystone.model.Access.Service.Endpoint; + +/** + * This class maintains a cache of tenants within a specific provider. + * <p> + * Providers may be multi-tenant, such as OpenStack, where the available services and resources vary from one tenant to + * another. Therefore, the provider cache maintains a cache of tenants and the service catalogs for each, as well as the + * credentials used to access the tenants, and a pool of Context objects for each tenant. The context pool allows use of + * the CDP abstraction layer to access the services of the provider within the specific tenant. + * </p> + */ +public class TenantCache implements Allocator<Context>, Destructor<Context> { + + public static final String POOL_PROVIDER_NAME = "pool.provider.name"; + public static final String POOL_TENANT_NAME = "pool.tenant.name"; + public static final String CLIENT_CONNECTOR_CLASS = "com.woorea.openstack.connector.JerseyConnector"; + + /** + * The provider we are part of + */ + private ProviderCache provider; + + /** + * The password used to authenticate + */ + private String password; + + /** + * The context pools by region used to access this tenant + */ + private Map<String /* region */, Pool<Context>> pools = new HashMap<>(); + + /** + * The tenant id + */ + private String tenantId; + + /** + * The tenant name + */ + private String tenantName; + + /** + * The user id used to authenticate + */ + private String userid; + + /** + * The configuration of this adapter + */ + private Configuration configuration; + + /** + * The service catalog for this provider + */ + private ServiceCatalog catalog; + + /** + * Set to true when the cache has been initialized + */ + private boolean initialized; + + /** + * The logger to use + */ + private EELFLogger logger; + + /** + * Construct the cache of tenants for the specified provider + * + * @param provider + * The provider + */ + public TenantCache(ProviderCache provider) { + configuration = ConfigurationFactory.getConfiguration(); + logger = EELFManager.getInstance().getLogger(getClass()); + this.provider = provider; + configuration = ConfigurationFactory.getConfiguration(); + } + + /** + * @return True when the cache has been initialized. A tenant cache is initialized when the service catalog for the + * tenant on the specified provider has been loaded and processed. + */ + public boolean isInitialized() { + return initialized; + } + + /** + * Initializes the tenant cache. + * <p> + * This method authenticates to the provider and obtains the service catalog. For the service catalog we can + * determine all supported regions for this provider, as well as all published services and their endpoints. We will + * cache and maintain a copy of the service catalog for later queries. + * </p> + * <p> + * Once the catalog has been obtained, we create a context pool for each region defined. The context allows access + * to services of a single region only, so we need a separate context by region. It is possible to operate on + * resources that span regions, but to do so will require acquiring a context for each region of interest. + * </p> + * <p> + * The context pool maintains the reusable context objects and allocates them as needed. This class is registered as + * the allocator and destructor for the pool, so that we can create a new context when needed, and close it when no + * longer used. + * </p> + */ + public void initialize() { + logger.debug("Initializing TenantCache"); + + int min = configuration.getIntegerProperty(Constants.PROPERTY_MIN_POOL_SIZE); + int max = configuration.getIntegerProperty(Constants.PROPERTY_MAX_POOL_SIZE); + int delay = configuration.getIntegerProperty(Constants.PROPERTY_RETRY_DELAY); + int limit = configuration.getIntegerProperty(Constants.PROPERTY_RETRY_LIMIT); + + String url = provider.getIdentityURL(); + String tenant = tenantName == null ? tenantId : tenantName; + Properties properties = configuration.getProperties(); + + int attempt = 1; + while (attempt <= limit) { + try { + catalog = new ServiceCatalog(url, tenant, userid, password, properties); + tenantId = catalog.getTenantId(); + tenantName = catalog.getTenantName(); + + for (String region : catalog.getRegions()) { + try { + Pool<Context> pool = new Pool<>(min, max); + pool.setProperty(ContextFactory.PROPERTY_IDENTITY_URL, url); + pool.setProperty(ContextFactory.PROPERTY_TENANT, tenantName); + pool.setProperty(ContextFactory.PROPERTY_CLIENT_CONNECTOR_CLASS, CLIENT_CONNECTOR_CLASS); + pool.setProperty(ContextFactory.PROPERTY_RETRY_DELAY, + configuration.getProperty(Constants.PROPERTY_RETRY_DELAY)); + pool.setProperty(ContextFactory.PROPERTY_RETRY_LIMIT, + configuration.getProperty(Constants.PROPERTY_RETRY_LIMIT)); + pool.setProperty(ContextFactory.PROPERTY_REGION, region); + if (properties.getProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS) != null) { + pool.setProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS, + properties.getProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS)); + } + pool.setAllocator(this); + pool.setDestructor(this); + pools.put(region, pool); + logger.debug(String.format("Put pool for region %s", region)); + } catch (PoolSpecificationException e) { + logger.error("Error creating pool", e); + e.printStackTrace(); + } + } + initialized = true; + break; + } catch (ContextConnectionException e) { + attempt++; + logger.error(Msg.CONNECTION_FAILED_RETRY, provider.getProviderName(), url, tenantName, tenantId, e.getMessage(), Integer.toString(delay), Integer.toString(attempt), + Integer.toString(limit)); + + try { + Thread.sleep(delay * 1000L); + } catch (InterruptedException ie) { + // ignore + } + } catch (ClientHandlerException | ZoneException e) { + logger.error(e.getMessage()); + break; + } + } + + if (!initialized) { + logger.error(Msg.CONNECTION_FAILED, provider.getProviderName(), url); + } + } + + /** + * This method accepts a fully qualified compute node URL and uses that to determine which region of the provider + * hosts that compute node. + * + * @param url + * The parsed URL of the compute node + * @return The region name, or null if no region of this tenant hosts that compute node. + */ + public String determineRegion(VMURL url) { + logger.debug(String.format("Attempting to determine VM region for %s", url)); + String region = null; + Pattern urlPattern = Pattern.compile("[^:]+://([^:/]+)(?::([0-9]+)).*"); + + if (url != null) { + for (Endpoint endpoint : catalog.getEndpoints(ServiceCatalog.COMPUTE_SERVICE)) { + String endpointUrl = endpoint.getPublicURL(); + Matcher matcher = urlPattern.matcher(endpointUrl); + if (matcher.matches()) { + if (url.getHost().equals(matcher.group(1))) { + if (url.getPort() != null) { + if (!url.getPort().equals(matcher.group(2))) { + continue; + } + } + + region = endpoint.getRegion(); + break; + } + } + } + } + logger.debug(String.format("Region for %s is %s", url, region)); + return region; + } + + /** + * @return the value of provider + */ + public ProviderCache getProvider() { + return provider; + } + + /** + * @param provider + * the value for provider + */ + public void setProvider(ProviderCache provider) { + this.provider = provider; + } + + /** + * @return the value of password + */ + public String getPassword() { + return password; + } + + /** + * @param password + * the value for password + */ + public void setPassword(String password) { + this.password = password; + } + + /** + * @return the value of tenantId + */ + public String getTenantId() { + return tenantId; + } + + /** + * @param tenantId + * the value for tenantId + */ + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + /** + * @return the value of tenantName + */ + public String getTenantName() { + return tenantName; + } + + /** + * @param tenantName + * the value for tenantName + */ + public void setTenantName(String tenantName) { + this.tenantName = tenantName; + } + + /** + * @return the value of userid + */ + public String getUserid() { + return userid; + } + + /** + * @param userid + * the value for userid + */ + public void setUserid(String userid) { + this.userid = userid; + } + + /** + * @return the value of pools + */ + public Map<String, Pool<Context>> getPools() { + return pools; + } + + /** + * @see org.openecomp.appc.pool.Allocator#allocate(org.openecomp.appc.pool.Pool) + */ + @SuppressWarnings("unchecked") + @Override + public Context allocate(Pool<Context> pool) { + logger.debug("Allocationg context for pool"); + Class<? extends Provider> providerClass; + try { + providerClass = (Class<? extends Provider>) Class.forName("com.att.cdp.openstack.OpenStackProvider"); + // String providerType = provider.getProviderType(); + + // Context context = ContextFactory.getContext(providerType, pool.getProperties()); + Context context = ContextFactory.getContext(providerClass, pool.getProperties()); + context.login(userid, password); + return context; + } catch (IllegalStateException | IllegalArgumentException | ZoneException | ClassNotFoundException e) { + logger.debug("Failed to allocate context for pool", e); + e.printStackTrace(); + } + return null; + } + + /** + * @see org.openecomp.appc.pool.Destructor#destroy(java.lang.Object, org.openecomp.appc.pool.Pool) + */ + @Override + public void destroy(Context context, Pool<Context> pool) { + try { + context.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * @return the service catalog for this provider + */ + public ServiceCatalog getServiceCatalog() { + return catalog; + } +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/VMURL.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/VMURL.java new file mode 100644 index 000000000..e9709fae0 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/VMURL.java @@ -0,0 +1,138 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.iaas.impl; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * This class is used to parse the VM URL returned from OpenStack and extract all of the constituent parts. + */ +public class VMURL { + + /** + * The regular expression pattern used to parse the URL. Capturing groups are used to identify and extract the + * various component parts of the URL. + */ + private static Pattern pattern = Pattern + .compile("(\\p{Alnum}+)://([^/:]+)(?::([0-9]+))?/v2/([^/]+)/servers/([^/]+)"); + + /** + * The URL scheme or protocol, such as HTTP or HTTPS + */ + private String scheme; + + /** + * The host name or ip address + */ + private String host; + + /** + * The port number, or null if no port is defined + */ + private String port; + + /** + * The tenant UUID + */ + private String tenantId; + + /** + * The server UUID + */ + private String serverId; + + /** + * A private default constructor prevents instantiation by any method other than the factory method + * + * @see #parseURL(String) + */ + private VMURL() { + + } + + /** + * This static method is used to parse the provided server URL string and return a parse results object (VMURL) + * which represents the state of the parse. + * + * @param serverUrl + * The server URL to be parsed + * @return The VMURL parse results object, or null if the URL was not valid or null. + */ + public static VMURL parseURL(String serverUrl) { + VMURL obj = null; + if (serverUrl != null) { + Matcher matcher = pattern.matcher(serverUrl.trim()); + if (matcher.matches()) { + obj = new VMURL(); + obj.scheme = matcher.group(1); + obj.host = matcher.group(2); + obj.port = matcher.group(3); + obj.tenantId = matcher.group(4); + obj.serverId = matcher.group(5); + } + } + + return obj; + } + + /** + * @return The URL scheme + */ + public String getScheme() { + return scheme; + } + + /** + * @return The URL host + */ + public String getHost() { + return host; + } + + /** + * @return The URL port, or null if no port was defined + */ + public String getPort() { + return port; + } + + /** + * @return The tenant id + */ + public String getTenantId() { + return tenantId; + } + + /** + * @return The server ID + */ + public String getServerId() { + return serverId; + } + + @Override + public String toString() { + return String.format("%s://%s:%s/%s/servers/%s", scheme, host, port, tenantId, serverId); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/SnapshotResource.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/SnapshotResource.java new file mode 100644 index 000000000..47ac7ff9e --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/SnapshotResource.java @@ -0,0 +1,70 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat; + +import org.openecomp.appc.adapter.openstack.heat.model.CreateSnapshotParams; +import org.openecomp.appc.adapter.openstack.heat.model.Snapshot; + +import com.woorea.openstack.base.client.Entity; +import com.woorea.openstack.base.client.HttpMethod; +import com.woorea.openstack.base.client.OpenStackClient; +import com.woorea.openstack.base.client.OpenStackRequest; + + +public class SnapshotResource { + + private final OpenStackClient client; + + public SnapshotResource(OpenStackClient client) { + this.client = client; + } + + public CreateSnapshot create(String stackName, String stackID, CreateSnapshotParams params) { + return new CreateSnapshot(stackName, stackID, params); + } + + public RestoreSnapshot restore(String stackName, String stackID, String snapshotID) { + return new RestoreSnapshot(stackName, stackID, snapshotID); + } + + public ShowSnapshot show(String stackName, String stackID, String snapshotID) { + return new ShowSnapshot(stackName, stackID, snapshotID); + } + + public class CreateSnapshot extends OpenStackRequest<Snapshot> { + public CreateSnapshot(String stackName, String stackID, CreateSnapshotParams params) { + super(client, HttpMethod.POST, "/stacks/" + stackName + "/" + stackID + "/snapshots", Entity.json(params), Snapshot.class); + } + } + + public class RestoreSnapshot extends OpenStackRequest<Void> { + public RestoreSnapshot(String stackName, String stackID, String snapshotID) { + super(client, HttpMethod.POST, "/stacks/" + stackName + "/" + stackID + "/snapshots/" + snapshotID + "/restore", null, Void.class); + } + } + + public class ShowSnapshot extends OpenStackRequest<Snapshot> { + public ShowSnapshot(String stackName, String stackID, String snapshotID) { + super(client, HttpMethod.GET, "/stacks/" + stackName + "/" + stackID + "/snapshots/" + snapshotID, null, Snapshot.class); + } + } +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/StackResource.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/StackResource.java new file mode 100644 index 000000000..de4f9da56 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/StackResource.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat; + +import org.openecomp.appc.adapter.openstack.heat.model.CreateSnapshotParams; +import org.openecomp.appc.adapter.openstack.heat.model.Snapshot; + +import com.woorea.openstack.base.client.Entity; +import com.woorea.openstack.base.client.HttpMethod; +import com.woorea.openstack.base.client.OpenStackClient; +import com.woorea.openstack.base.client.OpenStackRequest; +import com.woorea.openstack.heat.model.Stack; + + +public class StackResource { + + private final OpenStackClient client; + + public StackResource(OpenStackClient client) { + this.client = client; + } + + public ShowStack show(String stackName, String stackID) { + return new ShowStack(stackName, stackID); + } + + public class ShowStack extends OpenStackRequest<Stack> { + public ShowStack(String stackName, String stackID) { + super(client, HttpMethod.GET, "/stacks/" + stackName + "/" + stackID, null, Stack.class); + } + } +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/CreateSnapshotParams.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/CreateSnapshotParams.java new file mode 100644 index 000000000..e748f716b --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/CreateSnapshotParams.java @@ -0,0 +1,65 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat.model; + +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.commons.lang.builder.ToStringBuilder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "name" +}) +public class CreateSnapshotParams { + + @JsonProperty("name") + private String name; + + /** + * + * @return + * The name + */ + @JsonProperty("name") + public String getName() { + return name; + } + + /** + * + * @param name + * The name + */ + @JsonProperty("name") + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Data.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Data.java new file mode 100644 index 000000000..6a984a4e6 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Data.java @@ -0,0 +1,253 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat.model; + +import javax.annotation.Generated; +import javax.validation.Valid; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.commons.lang.builder.ToStringBuilder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "status", + "name", + "stack_user_project_id", + "environment", + "template", + "action", + "project_id", + "id", + "resources" +}) +public class Data { + + @JsonProperty("status") + private String status; + @JsonProperty("name") + private String name; + @JsonProperty("stack_user_project_id") + private String stackUserProjectId; + @JsonProperty("environment") + @Valid + private Environment environment; + @JsonProperty("template") + @Valid + private Template template; + @JsonProperty("action") + private String action; + @JsonProperty("project_id") + private String projectId; + @JsonProperty("id") + private String id; + @JsonProperty("resources") + @Valid + private Resources__ resources; + + /** + * + * @return + * The status + */ + @JsonProperty("status") + public String getStatus() { + return status; + } + + /** + * + * @param status + * The status + */ + @JsonProperty("status") + public void setStatus(String status) { + this.status = status; + } + + /** + * + * @return + * The name + */ + @JsonProperty("name") + public String getName() { + return name; + } + + /** + * + * @param name + * The name + */ + @JsonProperty("name") + public void setName(String name) { + this.name = name; + } + + /** + * + * @return + * The stackUserProjectId + */ + @JsonProperty("stack_user_project_id") + public String getStackUserProjectId() { + return stackUserProjectId; + } + + /** + * + * @param stackUserProjectId + * The stack_user_project_id + */ + @JsonProperty("stack_user_project_id") + public void setStackUserProjectId(String stackUserProjectId) { + this.stackUserProjectId = stackUserProjectId; + } + + /** + * + * @return + * The environment + */ + @JsonProperty("environment") + public Environment getEnvironment() { + return environment; + } + + /** + * + * @param environment + * The environment + */ + @JsonProperty("environment") + public void setEnvironment(Environment environment) { + this.environment = environment; + } + + /** + * + * @return + * The template + */ + @JsonProperty("template") + public Template getTemplate() { + return template; + } + + /** + * + * @param template + * The template + */ + @JsonProperty("template") + public void setTemplate(Template template) { + this.template = template; + } + + /** + * + * @return + * The action + */ + @JsonProperty("action") + public String getAction() { + return action; + } + + /** + * + * @param action + * The action + */ + @JsonProperty("action") + public void setAction(String action) { + this.action = action; + } + + /** + * + * @return + * The projectId + */ + @JsonProperty("project_id") + public String getProjectId() { + return projectId; + } + + /** + * + * @param projectId + * The project_id + */ + @JsonProperty("project_id") + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + /** + * + * @return + * The id + */ + @JsonProperty("id") + public String getId() { + return id; + } + + /** + * + * @param id + * The id + */ + @JsonProperty("id") + public void setId(String id) { + this.id = id; + } + + /** + * + * @return + * The resources + */ + @JsonProperty("resources") + public Resources__ getResources() { + return resources; + } + + /** + * + * @param resources + * The resources + */ + @JsonProperty("resources") + public void setResources(Resources__ resources) { + this.resources = resources; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Environment.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Environment.java new file mode 100644 index 000000000..94b7a1585 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Environment.java @@ -0,0 +1,91 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat.model; + +import javax.annotation.Generated; +import javax.validation.Valid; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.commons.lang.builder.ToStringBuilder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "parameters", + "resource_registry" +}) +public class Environment { + + @JsonProperty("parameters") + @Valid + private Parameters parameters; + @JsonProperty("resource_registry") + @Valid + private ResourceRegistry resourceRegistry; + + /** + * + * @return + * The parameters + */ + @JsonProperty("parameters") + public Parameters getParameters() { + return parameters; + } + + /** + * + * @param parameters + * The parameters + */ + @JsonProperty("parameters") + public void setParameters(Parameters parameters) { + this.parameters = parameters; + } + + /** + * + * @return + * The resourceRegistry + */ + @JsonProperty("resource_registry") + public ResourceRegistry getResourceRegistry() { + return resourceRegistry; + } + + /** + * + * @param resourceRegistry + * The resource_registry + */ + @JsonProperty("resource_registry") + public void setResourceRegistry(ResourceRegistry resourceRegistry) { + this.resourceRegistry = resourceRegistry; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Metadata.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Metadata.java new file mode 100644 index 000000000..6b4aa00eb --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Metadata.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat.model; + +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.commons.lang.builder.ToStringBuilder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + +}) +public class Metadata { + + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Parameters.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Parameters.java new file mode 100644 index 000000000..c46fded70 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Parameters.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat.model; + +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.commons.lang.builder.ToStringBuilder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + +}) +public class Parameters { + + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Properties.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Properties.java new file mode 100644 index 000000000..026daac69 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Properties.java @@ -0,0 +1,65 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat.model; + +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.commons.lang.builder.ToStringBuilder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "size" +}) +public class Properties { + + @JsonProperty("size") + private int size; + + /** + * + * @return + * The size + */ + @JsonProperty("size") + public int getSize() { + return size; + } + + /** + * + * @param size + * The size + */ + @JsonProperty("size") + public void setSize(int size) { + this.size = size; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/ResourceData.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/ResourceData.java new file mode 100644 index 000000000..8e3910b2b --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/ResourceData.java @@ -0,0 +1,65 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat.model; + +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.commons.lang.builder.ToStringBuilder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "backup_id" +}) +public class ResourceData { + + @JsonProperty("backup_id") + private String backupId; + + /** + * + * @return + * The backupId + */ + @JsonProperty("backup_id") + public String getBackupId() { + return backupId; + } + + /** + * + * @param backupId + * The backup_id + */ + @JsonProperty("backup_id") + public void setBackupId(String backupId) { + this.backupId = backupId; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/ResourceRegistry.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/ResourceRegistry.java new file mode 100644 index 000000000..799dc65b6 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/ResourceRegistry.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat.model; + +import javax.annotation.Generated; +import javax.validation.Valid; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.commons.lang.builder.ToStringBuilder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "resources" +}) +public class ResourceRegistry { + + @JsonProperty("resources") + @Valid + private Resources resources; + + /** + * + * @return + * The resources + */ + @JsonProperty("resources") + public Resources getResources() { + return resources; + } + + /** + * + * @param resources + * The resources + */ + @JsonProperty("resources") + public void setResources(Resources resources) { + this.resources = resources; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Resources.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Resources.java new file mode 100644 index 000000000..f8b2aeda2 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Resources.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat.model; + +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.commons.lang.builder.ToStringBuilder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + +}) +public class Resources { + + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Resources_.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Resources_.java new file mode 100644 index 000000000..3ac378aac --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Resources_.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat.model; + +import javax.annotation.Generated; +import javax.validation.Valid; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.commons.lang.builder.ToStringBuilder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "volume" +}) +public class Resources_ { + + @JsonProperty("volume") + @Valid + private Volume volume; + + /** + * + * @return + * The volume + */ + @JsonProperty("volume") + public Volume getVolume() { + return volume; + } + + /** + * + * @param volume + * The volume + */ + @JsonProperty("volume") + public void setVolume(Volume volume) { + this.volume = volume; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Resources__.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Resources__.java new file mode 100644 index 000000000..2072cf68b --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Resources__.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat.model; + +import javax.annotation.Generated; +import javax.validation.Valid; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.commons.lang.builder.ToStringBuilder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "volume" +}) +public class Resources__ { + + @JsonProperty("volume") + @Valid + private Volume_ volume; + + /** + * + * @return + * The volume + */ + @JsonProperty("volume") + public Volume_ getVolume() { + return volume; + } + + /** + * + * @param volume + * The volume + */ + @JsonProperty("volume") + public void setVolume(Volume_ volume) { + this.volume = volume; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Snapshot.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Snapshot.java new file mode 100644 index 000000000..47549fc60 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Snapshot.java @@ -0,0 +1,182 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat.model; + +import javax.annotation.Generated; +import javax.validation.Valid; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.commons.lang.builder.ToStringBuilder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "id", + "name", + "status", + "status_reason", + "creation_time", + "data" +}) +public class Snapshot { + + @JsonProperty("id") + private String id; + @JsonProperty("name") + private String name; + @JsonProperty("status") + private String status; + @JsonProperty("status_reason") + private String statusReason; + @JsonProperty("creation_time") + private String creationTime; + @JsonProperty("data") + @Valid + private Data data; + + /** + * + * @return + * The id + */ + @JsonProperty("id") + public String getId() { + return id; + } + + /** + * + * @param id + * The id + */ + @JsonProperty("id") + public void setId(String id) { + this.id = id; + } + + /** + * + * @return + * The name + */ + @JsonProperty("name") + public String getName() { + return name; + } + + /** + * + * @param name + * The name + */ + @JsonProperty("name") + public void setName(String name) { + this.name = name; + } + + /** + * + * @return + * The status + */ + @JsonProperty("status") + public String getStatus() { + return status; + } + + /** + * + * @param status + * The status + */ + @JsonProperty("status") + public void setStatus(String status) { + this.status = status; + } + + /** + * + * @return + * The statusReason + */ + @JsonProperty("status_reason") + public String getStatusReason() { + return statusReason; + } + + /** + * + * @param statusReason + * The status_reason + */ + @JsonProperty("status_reason") + public void setStatusReason(String statusReason) { + this.statusReason = statusReason; + } + + /** + * + * @return + * The creationTime + */ + @JsonProperty("creation_time") + public String getCreationTime() { + return creationTime; + } + + /** + * + * @param creationTime + * The creation_time + */ + @JsonProperty("creation_time") + public void setCreationTime(String creationTime) { + this.creationTime = creationTime; + } + + /** + * + * @return + * The data + */ + @JsonProperty("data") + public Data getData() { + return data; + } + + /** + * + * @param data + * The data + */ + @JsonProperty("data") + public void setData(Data data) { + this.data = data; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/SnapshotDetails.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/SnapshotDetails.java new file mode 100644 index 000000000..b88e569ef --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/SnapshotDetails.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat.model; + +import javax.annotation.Generated; +import javax.validation.Valid; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.commons.lang.builder.ToStringBuilder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "snapshot" +}) +public class SnapshotDetails { + + @JsonProperty("snapshot") + @Valid + private Snapshot snapshot; + + /** + * + * @return + * The snapshot + */ + @JsonProperty("snapshot") + public Snapshot getSnapshot() { + return snapshot; + } + + /** + * + * @param snapshot + * The snapshot + */ + @JsonProperty("snapshot") + public void setSnapshot(Snapshot snapshot) { + this.snapshot = snapshot; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/SnapshotRestoreResponse.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/SnapshotRestoreResponse.java new file mode 100644 index 000000000..8fa6e5272 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/SnapshotRestoreResponse.java @@ -0,0 +1,111 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat.model; + +import javax.annotation.Generated; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.commons.lang.builder.ToStringBuilder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "code", + "message", + "title" +}) +public class SnapshotRestoreResponse { + + @JsonProperty("code") + private String code; + @JsonProperty("message") + private String message; + @JsonProperty("title") + private String title; + + /** + * + * @return + * The code + */ + @JsonProperty("code") + public String getCode() { + return code; + } + + /** + * + * @param code + * The code + */ + @JsonProperty("code") + public void setCode(String code) { + this.code = code; + } + + /** + * + * @return + * The message + */ + @JsonProperty("message") + public String getMessage() { + return message; + } + + /** + * + * @param message + * The message + */ + @JsonProperty("message") + public void setMessage(String message) { + this.message = message; + } + + /** + * + * @return + * The title + */ + @JsonProperty("title") + public String getTitle() { + return title; + } + + /** + * + * @param title + * The title + */ + @JsonProperty("title") + public void setTitle(String title) { + this.title = title; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Template.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Template.java new file mode 100644 index 000000000..ef3aa473c --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Template.java @@ -0,0 +1,90 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat.model; + +import javax.annotation.Generated; +import javax.validation.Valid; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.commons.lang.builder.ToStringBuilder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "heat_template_version", + "resources" +}) +public class Template { + + @JsonProperty("heat_template_version") + private String heatTemplateVersion; + @JsonProperty("resources") + @Valid + private Resources_ resources; + + /** + * + * @return + * The heatTemplateVersion + */ + @JsonProperty("heat_template_version") + public String getHeatTemplateVersion() { + return heatTemplateVersion; + } + + /** + * + * @param heatTemplateVersion + * The heat_template_version + */ + @JsonProperty("heat_template_version") + public void setHeatTemplateVersion(String heatTemplateVersion) { + this.heatTemplateVersion = heatTemplateVersion; + } + + /** + * + * @return + * The resources + */ + @JsonProperty("resources") + public Resources_ getResources() { + return resources; + } + + /** + * + * @param resources + * The resources + */ + @JsonProperty("resources") + public void setResources(Resources_ resources) { + this.resources = resources; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Volume.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Volume.java new file mode 100644 index 000000000..26f4cd7e9 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Volume.java @@ -0,0 +1,90 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat.model; + +import javax.annotation.Generated; +import javax.validation.Valid; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.commons.lang.builder.ToStringBuilder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "type", + "properties" +}) +public class Volume { + + @JsonProperty("type") + private String type; + @JsonProperty("properties") + @Valid + private Properties properties; + + /** + * + * @return + * The type + */ + @JsonProperty("type") + public String getType() { + return type; + } + + /** + * + * @param type + * The type + */ + @JsonProperty("type") + public void setType(String type) { + this.type = type; + } + + /** + * + * @return + * The properties + */ + @JsonProperty("properties") + public Properties getProperties() { + return properties; + } + + /** + * + * @param properties + * The properties + */ + @JsonProperty("properties") + public void setProperties(Properties properties) { + this.properties = properties; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Volume_.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Volume_.java new file mode 100644 index 000000000..f36808a0d --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/openstack/heat/model/Volume_.java @@ -0,0 +1,206 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.openstack.heat.model; + +import javax.annotation.Generated; +import javax.validation.Valid; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import org.apache.commons.lang.builder.ToStringBuilder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ + "status", + "name", + "resource_data", + "resource_id", + "action", + "type", + "metadata" +}) +public class Volume_ { + + @JsonProperty("status") + private String status; + @JsonProperty("name") + private String name; + @JsonProperty("resource_data") + @Valid + private ResourceData resourceData; + @JsonProperty("resource_id") + private String resourceId; + @JsonProperty("action") + private String action; + @JsonProperty("type") + private String type; + @JsonProperty("metadata") + @Valid + private Metadata metadata; + + /** + * + * @return + * The status + */ + @JsonProperty("status") + public String getStatus() { + return status; + } + + /** + * + * @param status + * The status + */ + @JsonProperty("status") + public void setStatus(String status) { + this.status = status; + } + + /** + * + * @return + * The name + */ + @JsonProperty("name") + public String getName() { + return name; + } + + /** + * + * @param name + * The name + */ + @JsonProperty("name") + public void setName(String name) { + this.name = name; + } + + /** + * + * @return + * The resourceData + */ + @JsonProperty("resource_data") + public ResourceData getResourceData() { + return resourceData; + } + + /** + * + * @param resourceData + * The resource_data + */ + @JsonProperty("resource_data") + public void setResourceData(ResourceData resourceData) { + this.resourceData = resourceData; + } + + /** + * + * @return + * The resourceId + */ + @JsonProperty("resource_id") + public String getResourceId() { + return resourceId; + } + + /** + * + * @param resourceId + * The resource_id + */ + @JsonProperty("resource_id") + public void setResourceId(String resourceId) { + this.resourceId = resourceId; + } + + /** + * + * @return + * The action + */ + @JsonProperty("action") + public String getAction() { + return action; + } + + /** + * + * @param action + * The action + */ + @JsonProperty("action") + public void setAction(String action) { + this.action = action; + } + + /** + * + * @return + * The type + */ + @JsonProperty("type") + public String getType() { + return type; + } + + /** + * + * @param type + * The type + */ + @JsonProperty("type") + public void setType(String type) { + this.type = type; + } + + /** + * + * @return + * The metadata + */ + @JsonProperty("metadata") + public Metadata getMetadata() { + return metadata; + } + + /** + * + * @param metadata + * The metadata + */ + @JsonProperty("metadata") + public void setMetadata(Metadata metadata) { + this.metadata = metadata; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/resources/com/att/cdp/default.properties b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/resources/com/att/cdp/default.properties new file mode 100644 index 000000000..6a11d7214 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/resources/com/att/cdp/default.properties @@ -0,0 +1,158 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# +# Default Properties - Configured for integration of CDP into APPC +# +#-------------------------------------------------------------------------------------------- +# The path and file used to load configuration settings, if any +com.att.cdp.bootstrap.path=${user.home},src/main/config,/etc/aft/scld/,/opt/app/aft/scld/etc/,/opt/app/aft/cdp/etc/,C:/Program Files/aft/scld/etc/,etc,../etc,. +com.att.cdp.bootstrap.file=cdp.properties +# com.att.cdp.system.admins= +# +# AFT properties for lat/long/environment and platform +# +AFT_LATITUDE=12.3456 +AFT_LONGITUDE=-12.3456 +AFT_ENVIRONMENT=AFT-ENVIRONMENT +SCLD_PLATFORM=OPEN-SOURCE +# +# The versions of CDP API, CDP itself, and the build number +# +API_VERSION=${version} +CDP_VERSION=${version} +CDP_BUILD=${buildNumber} +# +# The path to search for logging configuration document, and the name of the document +# +com.att.cdp.logging.path=${user.home},src/main/config,etc,../etc,. +com.att.cdp.logging.file=logback.xml +# +# The resource bundle base name to be loaded for message resources. This property can be a comma delimited list of resources to be +# loaded, allowing multiple resource bundles to be loaded simultaneously (for the same locale). +# +com.att.cdp.resources=com/att/cdp/StrategyServiceMessages +# +# Logger names used in the application +# +com.att.cdp.logger=org.openecomp.appc +com.att.cdp.security.logger=org.openecomp.appc.security +com.att.cdp.perf.logger=org.openecomp.appc.perf +com.att.cdp.gui.logger=org.openecomp.appc.gui +com.att.cdp.server.logger=org.openecomp.appc.server +com.att.cdp.coordinator.logger=org.openecomp.appc.coordinator +com.att.cdp.policy.logger=org.openecomp.appc.policy + +# +# This property allows to 'simulate' SSH processes within engine. +# By default, it is set to 'false' - So that it allows to actually execute SSH process. If 'true', it will 'simulate' SSH processes +# +com.att.cdp.ssh.simulate=false +# +# These properties are used to specify the default stack metadata path and file names written and read on each server node +# +com.att.cdp.metadata.path=/etc/cdp/metadata +com.att.cdp.metadata.export.filename=stack.xml +com.att.cdp.metadata.import.filename=stack.xml +# +#Below properties are to specify minimum and maximum bootstrap time in minutes. +#These properties are ONLY supposed to be used in tandem with SSH simulation.(testing purpose) +com.att.cdp.ssh.simulate.minBootstrapTime=6 +com.att.cdp.ssh.simulate.maxBootstrapTime=12 +# +# +# These properties are used to configure the AAF security interface +# +# com.att.cdp.aaf.connection.url = dme2 url to connect to aaf service +# com.att.cdp.aaf.connection.timeout = connection timeout, in seconds +# com.att.cdp.aaf.cache.flush = cache flush interval in minutes +# com.att.cdp.aaf.cache.size = the maximum number of cache entries +# com.att.cdp.aaf.auth.principal = The principal id we use to authenticate ourself to AAF +# com.att.cdp.aaf.auth.credentials = The credentials (password) we use to authenticate ourself to AAF +# +com.att.cdp.aaf.connection.url=https://DME2SITE/service=com.att.authz.AuthorizationService/version=2.0/envContext=TEST/routeOffer=BAU_SE +com.att.cdp.aaf.connection.timeout=10 +com.att.cdp.aaf.cache.flush=5 +com.att.cdp.aaf.cache.size=400 +com.att.cdp.aaf.auth.principal=emailaddress@example.com +com.att.cdp.aaf.auth.credentials=MyPassw0rd +# +# ---------------------------------------------------------------------------------------------------- +# These properties are used to configure the operation of the StackBuilder engine +# +# maximum number of build manager threads in the thread pool +com.att.cdp.engine.maxManagerPool=30 +# max number of worker threads in the pool for use by workers +com.att.cdp.engine.MaxWorkerPool=300 + +# max number of workers that can be created per build request (set to 1 to single-thread a build) +com.att.cdp.engine.maxWorkers=10 +# Maximum amount of time to wait for a provider to complete any requested operation, in minutes. Such +# as creating a server or a volume. +com.att.cdp.engine.maxWaitTime=15 +# +# ---------------------------------------------------------------------------------------------------- +# These properties are used to configure the managed node hostname generation/resolution process +# +com.att.cdp.managed.hostname.resolve.retry=3 +# ---------------------------------------------------------------------------------------------------- +# +# Cassandra Connection Configuration Properties +# +cassandra.userName=cassandra +cassandra.password=cassandra +#cassandra.dataCenter= +cassandra.hosts=127.0.0.1 +cassandra.port=9042 +cassandra.keyspace=cdp +cassandra.minPoolSize=8 +cassandra.maxPoolSize=8 +cassandra.readtimeout=180000 +# +# Cassandra data Migration toggle +com.att.cdp.db.migration=true +com.att.cdp.db.update=true + +#Default Values for Image Attributes Configuration.These SHOULD NOT be removed. +image.default.namepattern=.* +image.default.user=root +image.default.sudo=false + +# ---------------------------------------------------------------------------------------------------- +# +# The path OSSupport will search for OS configuration properties files +# +com.att.cdp.OSType.path=/etc/os/ +# ---------------------------------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------------------------------- +# +# The properties used in ConnectivityBuilder +internet_url=www.google.com +ubuntu_sat_access_url=example.com +grm_server_url=example.com +# +# ---------------------------------------------------------------------------------------------------- +com.att.cdp.ptr.cleanup=true + +# ---------------------------------------------------------------------------------------------------- +# The maximum amount of time in seconds that we should wait for input from the shell +com.att.cdp.ssh.timeout=1800 diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..259cc1ba7 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,102 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# +# Default properties for the APP-C Provider Adapter +# +# ------------------------------------------------------------------------------------------------- +# +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + +appc.application.name=APPC + +# +# Define the message resource bundle name to be loaded +org.openecomp.appc.resources=org/openecomp/appc/i18n/MessageResources +# +# The name of the adapter. +org.openecomp.appc.provider.adaptor.name=org.openecomp.appc.appc_provider_adapter +# +# Set up the logging environment +# +org.openecomp.appc.logging.file=org/openecomp/appc/logback.xml +org.openecomp.appc.logging.path=${user.home};etc;../etc +org.openecomp.appc.logger=org.openecomp.appc +org.openecomp.appc.security.logger=org.openecomp.appc.security +# +# The minimum and maximum provider/tenant context pool sizes. Min=1 means that as soon +# as the provider/tenant is referenced a Context is opened and added to the pool. Max=0 +# means that the upper bound on the pool is unbounded. +org.openecomp.appc.provider.min.pool=1 +org.openecomp.appc.provider.max.pool=0 + +# +# The following properties are used to configure the retry logic for connection to the +# IaaS provider(s). The retry delay property is the amount of time, in seconds, the +# application waits between retry attempts. The retry limit is the number of retries +# that are allowed before the request is failed. +org.openecomp.appc.provider.retry.delay = 30 +org.openecomp.appc.provider.retry.limit = 10 + +# +# The trusted hosts list for SSL access when a certificate is not provided. +# +provider.trusted.hosts=* +# +# The amount of time, in seconds, to wait for a server state change (start->stop, stop->start, etc). +# If the server does not change state to a valid state within the alloted time, the operation +# fails. +org.openecomp.appc.server.state.change.timeout=300 +# +# The amount of time to wait, in seconds, between subsequent polls to the OpenStack provider +# to refresh the status of a resource we are waiting on. +# +org.openecomp.appc.openstack.poll.interval=20 + + # + #The amount of time, in seconds, that the application waits for a change of state of a stacj to a known valid + #sate before giving up and failing the request. + # +org.openecomp.appc.stack.state.change.timeout=100 + + + +# +# The connection information to connect to the provider we are using. These properties +# are "structured" properties, in that the name is a compound name, where the nodes +# of the name can be ordered (1, 2, 3, ...). All of the properties with the same ordinal +# position are defining the same entity. For example, provider1.type and provider1.name +# are defining the same provider, whereas provider2.name and provider2.type are defining +# the values for a different provider. Any number of providers can be defined in this +# way. +# +# Don't change these 2 right now since they are hard coded in the DG +provider1.type=appc +provider1.name=appc + +#These you can change +provider1.identity=appc +provider1.tenant1.name=appc +provider1.tenant1.userid=appc +provider1.tenant1.password=appc diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestIdentityUrl.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestIdentityUrl.java new file mode 100644 index 000000000..4f797f859 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestIdentityUrl.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + +package org.openecomp.appc.adapter.iaas.impl; + +import static org.junit.Assert.assertNotNull; + +import java.util.Properties; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.openecomp.appc.adapter.iaas.impl.IdentityURL; +import org.openecomp.appc.configuration.ConfigurationFactory; + +public class TestIdentityUrl { + + private static String URL; + + @BeforeClass + public static void before() { + Properties props = ConfigurationFactory.getConfiguration().getProperties(); + URL = props.getProperty(""); + } + + /** + * Test that we can parse and interpret valid URLs + */ + @Test + public void testValidURLs() { + URL = "http://192.168.1.1:5000/v2.0/"; + IdentityURL idurl = IdentityURL.parseURL(URL); + assertNotNull(idurl); + System.out.println(idurl.getVersion()); + } +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestProviderAdapterImpl.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestProviderAdapterImpl.java new file mode 100644 index 000000000..d83c18b04 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestProviderAdapterImpl.java @@ -0,0 +1,943 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.iaas.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.ProviderAdapter; +import org.openecomp.appc.adapter.iaas.impl.ProviderAdapterImpl; +import org.openecomp.appc.adapter.iaas.impl.ProviderCache; +import org.openecomp.appc.adapter.iaas.impl.ServiceCatalog; +import org.openecomp.appc.adapter.iaas.impl.TenantCache; +import org.openecomp.appc.adapter.iaas.impl.VMURL; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.exceptions.UnknownProviderException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.zones.ComputeService; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.ContextFactory; +import com.att.cdp.zones.model.Image; +import com.att.cdp.zones.model.Server; +import com.att.cdp.zones.model.Server.Status; +import org.openecomp.sdnc.sli.SvcLogicContext; + +import com.woorea.openstack.keystone.model.Access.Service.Endpoint; + +/** + * Test the ProviderAdapter implementation. + */ +@Category(org.openecomp.appc.adapter.iaas.impl.TestProviderAdapterImpl.class) +public class TestProviderAdapterImpl { + + @SuppressWarnings("nls") + private static final String PROVIDER_NAME = "ILAB"; + + @SuppressWarnings("nls") + private static final String PROVIDER_TYPE = "OpenStackProvider"; + + private static String IDENTITY_URL; + + private static String PRINCIPAL; + + private static String CREDENTIAL; + + private static String TENANT_NAME; + + private static String TENANT_ID; + + private static String USER_ID; + + private static String REGION_NAME; + + private static String SERVER_URL; + + private static Class<?> providerAdapterImplClass; + private static Class<?> configurationFactoryClass; + private static Field providerCacheField; + private static Field configField; + + private ProviderAdapterImpl adapter; + + /** + * Use reflection to locate fields and methods so that they can be manipulated during the test to change the + * internal state accordingly. + * + * @throws NoSuchFieldException + * if the field(s) dont exist + * @throws SecurityException + * if reflective access is not allowed + * @throws NoSuchMethodException + * If the method(s) dont exist + */ + @SuppressWarnings("nls") + @BeforeClass + public static void once() throws NoSuchFieldException, SecurityException, NoSuchMethodException { + providerAdapterImplClass = ProviderAdapterImpl.class; + configurationFactoryClass = ConfigurationFactory.class; + + providerCacheField = providerAdapterImplClass.getDeclaredField("providerCache"); + providerCacheField.setAccessible(true); + + configField = configurationFactoryClass.getDeclaredField("config"); + configField.setAccessible(true); + + Properties props = ConfigurationFactory.getConfiguration().getProperties(); + IDENTITY_URL = props.getProperty("provider1.identity"); + PRINCIPAL = props.getProperty("provider1.tenant1.userid", "appc"); + CREDENTIAL = props.getProperty("provider1.tenant1.password", "appc"); + TENANT_NAME = props.getProperty("provider1.tenant1.name", "appc"); + TENANT_ID = props.getProperty("provider1.tenant1.id", "abcde12345fghijk6789lmnopq123rst"); + REGION_NAME = props.getProperty("provider1.tenant1.region", "RegionOne"); + SERVER_URL = props.getProperty("test.url"); + } + + /** + * Setup the test environment. + * + * @throws IllegalAccessException + * if this Field object is enforcing Java language access control and the underlying field is either + * inaccessible or final. + * @throws IllegalArgumentException + * if the specified object is not an instance of the class or interface declaring the underlying field + * (or a subclass or implementor thereof), or if an unwrapping conversion fails. + * @throws NullPointerException + * if the specified object is null and the field is an instance field. + * @throws ExceptionInInitializerError + * if the initialization provoked by this method fails. + */ + @Before + public void setup() throws IllegalArgumentException, IllegalAccessException { + configField.set(null, null); + Properties properties = new Properties(); + adapter = new ProviderAdapterImpl(properties); + } + + /** + * This method inspects the provider adapter implementation to make sure that the cache of providers and tenants, as + * well as the service catalog, and all pools of contexts have been set up correctly. + * + * @throws IllegalAccessException + * if this Field object is enforcing Java language access control and the underlying field is + * inaccessible. + * @throws IllegalArgumentException + * if the specified object is not an instance of the class or interface declaring the underlying field + * (or a subclass or implementor thereof). + */ + @SuppressWarnings({ + "unchecked" + }) + @Ignore + @Test + public void validateCacheIsCreatedCorrectly() throws IllegalArgumentException, IllegalAccessException { + Map<String, ProviderCache> providerCaches = (Map<String, ProviderCache>) providerCacheField.get(adapter); + + assertNotNull(providerCaches); + assertEquals(1, providerCaches.size()); + assertTrue(providerCaches.containsKey(PROVIDER_NAME)); + + ProviderCache providerCache = providerCaches.get(PROVIDER_NAME); + assertEquals(PROVIDER_NAME, providerCache.getProviderName()); + assertEquals(PROVIDER_TYPE, providerCache.getProviderType()); + + Map<String, TenantCache> tenantCaches = providerCache.getTenants(); + assertNotNull(tenantCaches); + assertEquals(1, tenantCaches.size()); + assertTrue(tenantCaches.containsKey(TENANT_NAME)); + + TenantCache tenantCache = tenantCaches.get(TENANT_NAME); + + assertEquals(TENANT_ID, tenantCache.getTenantId()); + assertEquals(TENANT_NAME, tenantCache.getTenantName()); + assertEquals(USER_ID, tenantCache.getUserid()); + + ServiceCatalog catalog = tenantCache.getServiceCatalog(); + assertNotNull(catalog); + + System.out.println(catalog.toString()); + List<String> serviceTypes = catalog.getServiceTypes(); + assertNotNull(serviceTypes); + assertEquals(12, serviceTypes.size()); + + assertEquals(TENANT_NAME, catalog.getTenantName()); + assertEquals(TENANT_ID, catalog.getTenantId()); + + Set<String> regionNames = catalog.getRegions(); + assertNotNull(regionNames); + assertEquals(1, regionNames.size()); + assertTrue(regionNames.contains(REGION_NAME)); + + List<Endpoint> endpoints = catalog.getEndpoints(ServiceCatalog.IDENTITY_SERVICE); + assertNotNull(endpoints); + assertEquals(1, endpoints.size()); + Endpoint endpoint = endpoints.get(0); + assertNotNull(endpoint); + assertEquals(REGION_NAME, endpoint.getRegion()); + assertEquals(IDENTITY_URL, endpoint.getPublicURL()); + + endpoints = catalog.getEndpoints(ServiceCatalog.COMPUTE_SERVICE); + assertNotNull(endpoints); + assertEquals(1, endpoints.size()); + endpoint = endpoints.get(0); + assertNotNull(endpoint); + assertEquals(REGION_NAME, endpoint.getRegion()); + + endpoints = catalog.getEndpoints(ServiceCatalog.VOLUME_SERVICE); + assertNotNull(endpoints); + assertEquals(1, endpoints.size()); + endpoint = endpoints.get(0); + assertNotNull(endpoint); + assertEquals(REGION_NAME, endpoint.getRegion()); + + endpoints = catalog.getEndpoints(ServiceCatalog.IMAGE_SERVICE); + assertNotNull(endpoints); + assertEquals(1, endpoints.size()); + endpoint = endpoints.get(0); + assertNotNull(endpoint); + assertEquals(REGION_NAME, endpoint.getRegion()); + + endpoints = catalog.getEndpoints(ServiceCatalog.NETWORK_SERVICE); + assertNotNull(endpoints); + assertEquals(1, endpoints.size()); + endpoint = endpoints.get(0); + assertNotNull(endpoint); + assertEquals(REGION_NAME, endpoint.getRegion()); + + assertTrue(catalog.isServicePublished(ServiceCatalog.IDENTITY_SERVICE)); + assertTrue(catalog.isServicePublished(ServiceCatalog.COMPUTE_SERVICE)); + assertTrue(catalog.isServicePublished(ServiceCatalog.VOLUME_SERVICE)); + assertTrue(catalog.isServicePublished(ServiceCatalog.IMAGE_SERVICE)); + assertTrue(catalog.isServicePublished(ServiceCatalog.NETWORK_SERVICE)); + } + + /** + * This test case is used to actually validate that a server has been restarted from an already running state + * + * @throws ZoneException + * If the login cannot be performed because the principal and/or credentials are invalid. + * @throws IllegalArgumentException + * If the principal and/or credential are null or empty, or if the expected argument(s) are not defined + * or are invalid + * @throws IllegalStateException + * If the identity service is not available or cannot be created + * @throws IOException + * if an I/O error occurs + * @throws UnknownProviderException + * If the provider cannot be found + */ + // @Ignore + @Test + public void testRestartRunningServer() + throws IllegalStateException, IllegalArgumentException, ZoneException, UnknownProviderException, IOException { + Properties properties = new Properties(); + properties.setProperty(ContextFactory.PROPERTY_IDENTITY_URL, IDENTITY_URL); + properties.setProperty(ContextFactory.PROPERTY_REGION, REGION_NAME); + properties.setProperty(ContextFactory.PROPERTY_TENANT, TENANT_NAME); + properties.setProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS, "*"); + properties.setProperty(ContextFactory.PROPERTY_DISABLE_PROXY, "true"); + + try (Context context = ContextFactory.getContext(PROVIDER_TYPE, properties)) { + context.login(PRINCIPAL, CREDENTIAL); + VMURL vm = VMURL.parseURL(SERVER_URL); + + ComputeService computeService = context.getComputeService(); + Server server = computeService.getServer(vm.getServerId()); + if (!server.getStatus().equals(Status.RUNNING)) { + server.start(); + assertTrue(waitForStateChange(server, Status.RUNNING)); + } + + Map<String, String> params = new HashMap<>(); + params.put(ProviderAdapter.PROPERTY_INSTANCE_URL, SERVER_URL); + params.put(ProviderAdapter.PROPERTY_PROVIDER_NAME, PROVIDER_NAME); + SvcLogicContext svcContext = new SvcLogicContext(); + + server = adapter.restartServer(params, svcContext); + + assertEquals(Server.Status.RUNNING, server.getStatus()); + } + } + + + /****************************************/ + /** + * Tests that the vmStatuschecker method works and returns the correct status of the VM requested + * + * @throws ZoneException + * If the login cannot be performed because the principal and/or credentials are invalid. + * @throws IllegalArgumentException + * If the principal and/or credential are null or empty, or if the expected argument(s) are not defined + * or are invalid + * @throws IllegalStateException + * If the identity service is not available or cannot be created + * @throws IOException + * if an I/O error occurs + * @throws UnknownProviderException + * If the provider cannot be found + */ + // @Ignore + @Test + public void testVmStatuschecker() throws IllegalStateException, IllegalArgumentException, ZoneException, + UnknownProviderException, IOException { + Properties properties = new Properties(); + properties.setProperty(ContextFactory.PROPERTY_IDENTITY_URL, IDENTITY_URL); + properties.setProperty(ContextFactory.PROPERTY_REGION, REGION_NAME); + properties.setProperty(ContextFactory.PROPERTY_TENANT, TENANT_NAME); + properties.setProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS, "*"); + properties.setProperty(ContextFactory.PROPERTY_DISABLE_PROXY, "true"); + + try (Context context = ContextFactory.getContext(PROVIDER_TYPE, properties)) { + context.login(PRINCIPAL, CREDENTIAL); + VMURL vm = VMURL.parseURL(SERVER_URL); + + ComputeService computeService = context.getComputeService(); + Server server = computeService.getServer(vm.getServerId()); + if (!server.getStatus().equals(Status.RUNNING)) { + server.start(); + assertTrue(waitForStateChange(server, Status.RUNNING));} + //or instead of the if-block, can ensureRunning(server) be used? + ensureRunning(server); + assertEquals(Server.Status.RUNNING, server.getStatus()); + } + } + /****************************************/ + + + /** + * Tests that we can restart a server that is already stopped + * + * @throws ZoneException + * If the login cannot be performed because the principal and/or credentials are invalid. + * @throws IllegalArgumentException + * If the principal and/or credential are null or empty, or if the expected argument(s) are not defined + * or are invalid. + * @throws IllegalStateException + * If the identity service is not available or cannot be created + * @throws UnknownProviderException + * If the provider cannot be found + * @throws IOException + * if an I/O error occurs + */ + // @Ignore + @Test + public void testRestartStoppedServer() + throws IllegalStateException, IllegalArgumentException, ZoneException, UnknownProviderException, IOException { + Properties properties = new Properties(); + properties.setProperty(ContextFactory.PROPERTY_IDENTITY_URL, IDENTITY_URL); + properties.setProperty(ContextFactory.PROPERTY_REGION, REGION_NAME); + properties.setProperty(ContextFactory.PROPERTY_TENANT, TENANT_NAME); + properties.setProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS, "*"); + + try (Context context = ContextFactory.getContext(PROVIDER_TYPE, properties)) { + context.login(PRINCIPAL, CREDENTIAL); + VMURL vm = VMURL.parseURL(SERVER_URL); + + ComputeService computeService = context.getComputeService(); + Server server = computeService.getServer(vm.getServerId()); + if (!server.getStatus().equals(Status.READY)) { + server.stop(); + assertTrue(waitForStateChange(server, Status.READY)); + } + + Map<String, String> params = new HashMap<>(); + params.put(ProviderAdapter.PROPERTY_INSTANCE_URL, SERVER_URL); + params.put(ProviderAdapter.PROPERTY_PROVIDER_NAME, PROVIDER_NAME); + SvcLogicContext svcContext = new SvcLogicContext(); + + server = adapter.restartServer(params, svcContext); + + assertEquals(Server.Status.RUNNING, server.getStatus()); + + } + } + + /** + * Tests that we can rebuild a running server (not created from a bootable volume) + * + * @throws ZoneException + * If the login cannot be performed because the principal and/or credentials are invalid. + * @throws IllegalArgumentException + * If the principal and/or credential are null or empty, or if the expected argument(s) are not defined + * or are invalid. + * @throws IllegalStateException + * If the identity service is not available or cannot be created + * @throws UnknownProviderException + * If the provider cannot be found + * @throws IOException + * if an I/O error occurs + * @throws APPCException + * If the server cannot be rebuilt for some reason + */ + // @Ignore + @Test + public void testRebuildRunningServer() + throws IOException, IllegalStateException, IllegalArgumentException, ZoneException, APPCException { + Properties properties = new Properties(); + properties.setProperty(ContextFactory.PROPERTY_IDENTITY_URL, IDENTITY_URL); + properties.setProperty(ContextFactory.PROPERTY_REGION, REGION_NAME); + properties.setProperty(ContextFactory.PROPERTY_TENANT, TENANT_NAME); + properties.setProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS, "*"); + + try (Context context = ContextFactory.getContext(PROVIDER_TYPE, properties)) { + context.login(PRINCIPAL, CREDENTIAL); + VMURL vm = VMURL.parseURL(SERVER_URL); + + ComputeService computeService = context.getComputeService(); + Server server = computeService.getServer(vm.getServerId()); + ensureRunning(server); + + Map<String, String> params = new HashMap<>(); + params.put(ProviderAdapter.PROPERTY_INSTANCE_URL, SERVER_URL); + params.put(ProviderAdapter.PROPERTY_PROVIDER_NAME, PROVIDER_NAME); + SvcLogicContext svcContext = new SvcLogicContext(); + + server = adapter.rebuildServer(params, svcContext); + assertTrue(waitForStateChange(server, Status.RUNNING)); + + } + } + + /** + * Tests that we can rebuild a paused server (not created from a bootable volume) + * + * @throws ZoneException + * If the login cannot be performed because the principal and/or credentials are invalid. + * @throws IllegalArgumentException + * If the principal and/or credential are null or empty, or if the expected argument(s) are not defined + * or are invalid. + * @throws IllegalStateException + * If the identity service is not available or cannot be created + * @throws UnknownProviderException + * If the provider cannot be found + * @throws IOException + * if an I/O error occurs + * @throws APPCException + * If the server cannot be rebuilt for some reason + */ + // @Ignore + @Test + public void testRebuildPausedServer() + throws IOException, IllegalStateException, IllegalArgumentException, ZoneException, APPCException { + Properties properties = new Properties(); + properties.setProperty(ContextFactory.PROPERTY_IDENTITY_URL, IDENTITY_URL); + properties.setProperty(ContextFactory.PROPERTY_REGION, REGION_NAME); + properties.setProperty(ContextFactory.PROPERTY_TENANT, TENANT_NAME); + properties.setProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS, "*"); + + try (Context context = ContextFactory.getContext(PROVIDER_TYPE, properties)) { + context.login(PRINCIPAL, CREDENTIAL); + VMURL vm = VMURL.parseURL(SERVER_URL); + + ComputeService computeService = context.getComputeService(); + Server server = computeService.getServer(vm.getServerId()); + ensurePaused(server); + + Map<String, String> params = new HashMap<>(); + params.put(ProviderAdapter.PROPERTY_INSTANCE_URL, SERVER_URL); + params.put(ProviderAdapter.PROPERTY_PROVIDER_NAME, PROVIDER_NAME); + SvcLogicContext svcContext = new SvcLogicContext(); + + server = adapter.rebuildServer(params, svcContext); + assertTrue(waitForStateChange(server, Status.RUNNING)); + } + } + + /** + * Tests that we can rebuild a paused server (not created from a bootable volume) + * + * @throws ZoneException + * If the login cannot be performed because the principal and/or credentials are invalid. + * @throws IllegalArgumentException + * If the principal and/or credential are null or empty, or if the expected argument(s) are not defined + * or are invalid. + * @throws IllegalStateException + * If the identity service is not available or cannot be created + * @throws UnknownProviderException + * If the provider cannot be found + * @throws IOException + * if an I/O error occurs + * @throws APPCException + * If the server cannot be rebuilt for some reason + */ + // @Ignore + @Test + public void testRebuildSuspendedServer() + throws IOException, IllegalStateException, IllegalArgumentException, ZoneException, APPCException { + Properties properties = new Properties(); + properties.setProperty(ContextFactory.PROPERTY_IDENTITY_URL, IDENTITY_URL); + properties.setProperty(ContextFactory.PROPERTY_REGION, REGION_NAME); + properties.setProperty(ContextFactory.PROPERTY_TENANT, TENANT_NAME); + properties.setProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS, "*"); + + try (Context context = ContextFactory.getContext(PROVIDER_TYPE, properties)) { + context.login(PRINCIPAL, CREDENTIAL); + VMURL vm = VMURL.parseURL(SERVER_URL); + + ComputeService computeService = context.getComputeService(); + Server server = computeService.getServer(vm.getServerId()); + ensureSuspended(server); + + Map<String, String> params = new HashMap<>(); + params.put(ProviderAdapter.PROPERTY_INSTANCE_URL, SERVER_URL); + params.put(ProviderAdapter.PROPERTY_PROVIDER_NAME, PROVIDER_NAME); + SvcLogicContext svcContext = new SvcLogicContext(); + + server = adapter.rebuildServer(params, svcContext); + assertTrue(waitForStateChange(server, Status.RUNNING)); + } + } + + /** + * Tests that we can rebuild a paused server (not created from a bootable volume) + * + * @throws ZoneException + * If the login cannot be performed because the principal and/or credentials are invalid. + * @throws IllegalArgumentException + * If the principal and/or credential are null or empty, or if the expected argument(s) are not defined + * or are invalid. + * @throws IllegalStateException + * If the identity service is not available or cannot be created + * @throws UnknownProviderException + * If the provider cannot be found + * @throws IOException + * if an I/O error occurs + * @throws APPCException + * If the server cannot be rebuilt for some reason + */ + // @Ignore + @Test + public void testRebuildStoppedServer() + throws IOException, IllegalStateException, IllegalArgumentException, ZoneException, APPCException { + Properties properties = new Properties(); + properties.setProperty(ContextFactory.PROPERTY_IDENTITY_URL, IDENTITY_URL); + properties.setProperty(ContextFactory.PROPERTY_REGION, REGION_NAME); + properties.setProperty(ContextFactory.PROPERTY_TENANT, TENANT_NAME); + properties.setProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS, "*"); + + try (Context context = ContextFactory.getContext(PROVIDER_TYPE, properties)) { + context.login(PRINCIPAL, CREDENTIAL); + VMURL vm = VMURL.parseURL(SERVER_URL); + + ComputeService computeService = context.getComputeService(); + Server server = computeService.getServer(vm.getServerId()); + ensureStopped(server); + + Map<String, String> params = new HashMap<>(); + params.put(ProviderAdapter.PROPERTY_INSTANCE_URL, SERVER_URL); + params.put(ProviderAdapter.PROPERTY_PROVIDER_NAME, PROVIDER_NAME); + SvcLogicContext svcContext = new SvcLogicContext(); + + server = adapter.rebuildServer(params, svcContext); + assertTrue(waitForStateChange(server, Status.RUNNING)); + } + } + + /** + * Test subsequent action on second vm in different Tenant resulting in {"itemNotFound": {"message": "Instance could not be found", "code": 404}} + * + * @throws ZoneException + * If the login cannot be performed because the principal and/or credentials are invalid. + * @throws IllegalArgumentException + * If the principal and/or credential are null or empty, or if the expected argument(s) are not defined + * or are invalid + * @throws IllegalStateException + * If the identity service is not available or cannot be created + * @throws IOException + * if an I/O error occurs + * @throws APPCException + */ + + @Test + public void testTenantVerification() throws IllegalStateException, IllegalArgumentException, ZoneException, + IOException, APPCException { + + Properties properties = new Properties(); + properties.setProperty(ContextFactory.PROPERTY_IDENTITY_URL, "http://example.com:5000"); + properties.setProperty(ContextFactory.PROPERTY_TENANT, "APP-C"); + properties.setProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS, "*"); + + String vmUrl = + "http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345"; + + //try (Context context = ContextFactory.getContext(PROVIDER_TYPE, properties)) { + // context.login("AppC", "AppC"); + + // call lookupServer on vm in defined tenant "APP-C_TLV" + VMURL vm = VMURL.parseURL(vmUrl); + + Map<String, String> params = new HashMap<>(); + params.put(ProviderAdapter.PROPERTY_INSTANCE_URL, vmUrl); + params.put(ProviderAdapter.PROPERTY_IDENTITY_URL, "http://example.com:5000/v2.0"); + params.put(ProviderAdapter.PROPERTY_PROVIDER_NAME, "http://example.com:5000/v2.0"); + SvcLogicContext svcContext = new SvcLogicContext(); + + long start, end = 0; + + System.out.println("\n--------------------Begin lookupServer on tenant 1--------------------"); + start = System.currentTimeMillis(); + Server server = adapter.lookupServer(params, svcContext); + end = System.currentTimeMillis(); + + System.out.println(String.format("lookupServer on tenant 1 took %ds", (end - start) / 1000)); + System.out.println("----------------------------------------------------------------------\n"); + assertNotNull(server); + + //repeat to show that context is reused for second request + System.out.println("\n-----------------Begin repeat lookupServer on tenant 1----------------"); + start = System.currentTimeMillis(); + server = adapter.lookupServer(params, svcContext); + end = System.currentTimeMillis(); + + System.out.println(String.format("Repeat lookupServer on tenant 1 took %ds", (end - start) / 1000)); + System.out.println("----------------------------------------------------------------------\n"); + assertNotNull(server); + + // call lookupServer on vm in second tenant "Play" + // This is where we would fail due to using the previous + // tenants context + vmUrl = "http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345"; + vm = VMURL.parseURL(vmUrl); + params.put(ProviderAdapter.PROPERTY_INSTANCE_URL, vmUrl); + + System.out.println("\n--------------------Begin lookupServer on tenant 2--------------------"); + start = System.currentTimeMillis(); + server = adapter.lookupServer(params, svcContext); + end = System.currentTimeMillis(); + System.out.println(String.format("\nlookupServer on tenant 2 took %ds", (end - start) / 1000)); + System.out.println("----------------------------------------------------------------------\n"); + assertNotNull(server); + + // call lookupServer on vm in non-existing tenant + vmUrl = "http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345"; + vm = VMURL.parseURL(vmUrl); + params.put(ProviderAdapter.PROPERTY_INSTANCE_URL, vmUrl); + + System.out.println("\n--------------Begin lookupServer on non-existant tenant--------------"); + start = System.currentTimeMillis(); + server = adapter.lookupServer(params, svcContext); + end = System.currentTimeMillis(); + System.out.println(String.format("\nlookupServer on tenant 3 took %ds", (end - start) / 1000)); + System.out.println("----------------------------------------------------------------------\n"); + assertNull(server); + + //} + } + /****************************************/ + + + @Test + public void testSnapshotServer() throws Exception { + Properties properties = new Properties(); + properties.setProperty(ContextFactory.PROPERTY_IDENTITY_URL, "http://example.com:5000"); + // properties.setProperty(ContextFactory.PROPERTY_REGION, ""); + properties.setProperty(ContextFactory.PROPERTY_TENANT, "Play"); + properties.setProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS, "*"); + + String vmUrl = + "http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345"; + + try (Context context = ContextFactory.getContext(PROVIDER_TYPE, properties)) { + context.login("AppC", "AppC"); + VMURL vm = VMURL.parseURL(vmUrl); + + Map<String, String> params = new HashMap<>(); + params.put(ProviderAdapter.PROPERTY_INSTANCE_URL, vmUrl); + params.put(ProviderAdapter.PROPERTY_IDENTITY_URL, "http://example.com:5000/v2.0"); + params.put(ProviderAdapter.PROPERTY_PROVIDER_NAME, "http://example.com:5000/v2.0"); + SvcLogicContext svcContext = new SvcLogicContext(); + + long start, end = 0; + + start = System.currentTimeMillis(); + Image image = adapter.createSnapshot(params, svcContext); + end = System.currentTimeMillis(); + + System.out.println(String.format("Image ID: %s", image.getId())); + System.out.println(String.format("Snapshot took %ds", (end - start) / 1000)); + + start = System.currentTimeMillis(); + adapter.rebuildServer(params, svcContext); + end = System.currentTimeMillis(); + System.out.println(String.format("Rebuild took %ds", (end - start) / 1000)); + } + + } + + /** + * Ensures that the server is in stopped (shutdown) state prior to test + * + * @param server + * The server to ensure is stopped + * @throws ZoneException + * If the server can't be operated upon for some reason + */ + @SuppressWarnings("nls") + private static void ensureStopped(Server server) throws ZoneException { + switch (server.getStatus()) { + case READY: + break; + + case PENDING: + waitForStateChange(server, Server.Status.READY, Server.Status.RUNNING, Server.Status.PAUSED, + Server.Status.SUSPENDED, Server.Status.ERROR); + ensureSuspended(server); + break; + + case PAUSED: + server.unpause(); + waitForStateChange(server, Server.Status.RUNNING); + server.stop(); + waitForStateChange(server, Server.Status.READY); + break; + + case SUSPENDED: + server.resume(); + waitForStateChange(server, Server.Status.RUNNING); + server.stop(); + waitForStateChange(server, Server.Status.READY); + break; + + case RUNNING: + server.stop(); + waitForStateChange(server, Server.Status.READY); + break; + + case DELETED: + case ERROR: + default: + fail("Server state is not valid for test - " + server.getStatus().name()); + } + } + + /** + * Ensures that the server is in suspended state prior to test + * + * @param server + * The server to ensure is suspended + * @throws ZoneException + * If the server can't be operated upon for some reason + */ + @SuppressWarnings("nls") + private static void ensureSuspended(Server server) throws ZoneException { + switch (server.getStatus()) { + case SUSPENDED: + break; + + case PENDING: + waitForStateChange(server, Server.Status.READY, Server.Status.RUNNING, Server.Status.PAUSED, + Server.Status.SUSPENDED, Server.Status.ERROR); + ensureSuspended(server); + break; + + case PAUSED: + server.unpause(); + waitForStateChange(server, Server.Status.RUNNING); + server.suspend(); + waitForStateChange(server, Server.Status.SUSPENDED); + break; + + case READY: + server.start(); + waitForStateChange(server, Server.Status.RUNNING); + server.suspend(); + waitForStateChange(server, Server.Status.SUSPENDED); + break; + + case RUNNING: + server.suspend(); + waitForStateChange(server, Server.Status.SUSPENDED); + break; + + case DELETED: + case ERROR: + default: + fail("Server state is not valid for test - " + server.getStatus().name()); + } + } + + /** + * This method makes sure that the indicated server is running before performing a test + * + * @param server + * The server to ensure is running + * @throws ZoneException + * If the server can't be operated upon + */ + @SuppressWarnings("nls") + private static void ensureRunning(Server server) throws ZoneException { + switch (server.getStatus()) { + case RUNNING: + break; + + case PENDING: + waitForStateChange(server, Server.Status.READY, Server.Status.RUNNING, Server.Status.PAUSED, + Server.Status.SUSPENDED, Server.Status.ERROR); + ensureRunning(server); + break; + + case PAUSED: + server.unpause(); + waitForStateChange(server, Server.Status.RUNNING); + break; + + case SUSPENDED: + server.resume(); + waitForStateChange(server, Server.Status.RUNNING); + break; + + case READY: + server.start(); + waitForStateChange(server, Server.Status.RUNNING); + break; + + case DELETED: + case ERROR: + default: + fail("Server state is not valid for test - " + server.getStatus().name()); + } + } + + /** + * This method will make sure that the server we are testing is paused + * + * @param server + * The server to make sure is paused for the test + * @throws ZoneException + * If anything fails + */ + @SuppressWarnings("nls") + private static void ensurePaused(Server server) throws ZoneException { + switch (server.getStatus()) { + case PAUSED: + break; + + case PENDING: + waitForStateChange(server, Server.Status.READY, Server.Status.RUNNING, Server.Status.PAUSED, + Server.Status.SUSPENDED, Server.Status.ERROR); + ensurePaused(server); + break; + + case READY: + server.start(); + waitForStateChange(server, Server.Status.RUNNING); + server.pause(); + waitForStateChange(server, Server.Status.PAUSED); + break; + + case RUNNING: + server.pause(); + waitForStateChange(server, Server.Status.PAUSED); + break; + + case SUSPENDED: + server.resume(); + waitForStateChange(server, Server.Status.RUNNING); + server.pause(); + waitForStateChange(server, Server.Status.PAUSED); + break; + + case ERROR: + case DELETED: + default: + fail("Server state is not valid for test - " + server.getStatus().name()); + } + } + + /** + * Enter a pool-wait loop checking the server state to see if it has entered one of the desired states or not. + * <p> + * This method checks the state of the server periodically for one of the desired states. When the server enters one + * of the desired states, the method returns a successful indication (true). If the server never enters one of the + * desired states within the alloted timeout period, then the method returns a failed response (false). No + * exceptions are thrown from this method. + * </p> + * + * @param server + * The server to wait on + * @param desiredStates + * A variable list of desired states, any one of which is allowed. + * @return True if the server entered one of the desired states, and false if not and the wait loop timed out. + */ + private static boolean waitForStateChange(Server server, Server.Status... desiredStates) { + int timeout = + ConfigurationFactory.getConfiguration().getIntegerProperty(Constants.PROPERTY_SERVER_STATE_CHANGE_TIMEOUT); + long limit = System.currentTimeMillis() + (timeout * 1000); + Server vm = server; + + try { + while (limit > System.currentTimeMillis()) { + vm.refresh(); + for (Server.Status desiredState : desiredStates) { + if (server.getStatus().equals(desiredState)) { + return true; + } + } + + try { + Thread.sleep(10000L); + } catch (InterruptedException e) { + // ignore + } + } + } catch (ZoneException e) { + e.printStackTrace(); + } + + return false; + } + + /* + * @Test public void testTerminateStack() throws IllegalStateException, IllegalArgumentException, ZoneException, + * UnknownProviderException, IOException { Properties properties = new Properties(); + * properties.setProperty(ContextFactory.PROPERTY_IDENTITY_URL, IDENTITY_URL); + * properties.setProperty(ContextFactory.PROPERTY_REGION, REGION_NAME); + * properties.setProperty(ContextFactory.PROPERTY_TENANT, TENANT_NAME); + * properties.setProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS, "*"); + * properties.setProperty(ContextFactory.PROPERTY_DISABLE_PROXY, "true"); try (Context context = + * ContextFactory.getContext(PROVIDER_TYPE, properties)) { context.login(PRINCIPAL, CREDENTIAL); VMURL vm = + * VMURL.parseURL(SERVER_URL); ComputeService computeService = context.getComputeService(); Server server = + * computeService.getServer(vm.getServerId()); if (!server.getStatus().equals(Status.RUNNING)) { server.start(); + * assertTrue(waitForStateChange(server, Status.RUNNING)); } Map<String, String> params = new HashMap<>(); + * params.put(ProviderAdapter.PROPERTY_INSTANCE_URL, SERVER_URL); params.put(ProviderAdapter.PROPERTY_PROVIDER_NAME, + * PROVIDER_NAME); SvcLogicContext svcContext = new SvcLogicContext(); Stack stack = adapter.terminateStack(params, + * svcContext); assertNotNull(stack); } } + */ + +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestProviderAdapterImplNoConnection.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestProviderAdapterImplNoConnection.java new file mode 100644 index 000000000..d4683aa80 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestProviderAdapterImplNoConnection.java @@ -0,0 +1,170 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.adapter.iaas.impl; + +import java.lang.reflect.Field; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.openecomp.appc.adapter.iaas.impl.ProviderAdapterImpl; +import org.openecomp.appc.adapter.iaas.impl.RequestContext; +import org.openecomp.appc.adapter.iaas.impl.RequestFailedException; +import org.openecomp.appc.adapter.iaas.impl.VMURL; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.slf4j.MDC; + +/** + * This class is used to test methods and functions of the adapter implementation that do not require and do not set up + * connections to any providers. + */ + +public class TestProviderAdapterImplNoConnection { + + private static Class<?> providerAdapterImplClass; + private static Class<?> configurationFactoryClass; + private static Field providerCacheField; + private static Field configField; + + private ProviderAdapterImpl adapter; + + /** + * Use reflection to locate fields and methods so that they can be manipulated during the test to change the + * internal state accordingly. + * + * @throws NoSuchFieldException + * if the field(s) dont exist + * @throws SecurityException + * if reflective access is not allowed + * @throws NoSuchMethodException + * If the method(s) dont exist + */ + @SuppressWarnings("nls") + @BeforeClass + public static void once() throws NoSuchFieldException, SecurityException, NoSuchMethodException { + providerAdapterImplClass = ProviderAdapterImpl.class; + configurationFactoryClass = ConfigurationFactory.class; + + providerCacheField = providerAdapterImplClass.getDeclaredField("providerCache"); + providerCacheField.setAccessible(true); + + configField = configurationFactoryClass.getDeclaredField("config"); + configField.setAccessible(true); + } + + /** + * initialize the test cases + */ + @Before + public void setup() { + adapter = new ProviderAdapterImpl(false); + } + + /** + * This test expects a failure because the value to be validated is a null URL + * + * @throws RequestFailedException + * Expected + */ + @SuppressWarnings("nls") + @Test(expected = RequestFailedException.class) + public void testValidateParameterPatternExpectFailNullValue() throws RequestFailedException { + MDC.put(ProviderAdapterImpl.MDC_SERVICE, "junit"); + SvcLogicContext svcContext = new SvcLogicContext(); + RequestContext rc = new RequestContext(svcContext); + String link = null; + + adapter.validateVMURL(VMURL.parseURL(link)); + } + + /** + * This test expects a failure because the value to be validated is an empty URL + * + * @throws RequestFailedException + * Expected + */ + @SuppressWarnings("nls") + @Test(expected = RequestFailedException.class) + public void testValidateParameterPatternExpectFailEmptyValue() throws RequestFailedException { + MDC.put(ProviderAdapterImpl.MDC_SERVICE, "junit"); + SvcLogicContext svcContext = new SvcLogicContext(); + RequestContext rc = new RequestContext(svcContext); + String link = ""; + + adapter.validateVMURL(VMURL.parseURL(link)); + } + + /** + * This test expects a failure because the value to be validated is a blank URL + * + * @throws RequestFailedException + * Expected + */ + @SuppressWarnings("nls") + @Test(expected = RequestFailedException.class) + public void testValidateParameterPatternExpectFailBlankValue() throws RequestFailedException { + MDC.put(ProviderAdapterImpl.MDC_SERVICE, "junit"); + SvcLogicContext svcContext = new SvcLogicContext(); + RequestContext rc = new RequestContext(svcContext); + String link = " "; + + adapter.validateVMURL(VMURL.parseURL(link)); + } + + /** + * This test expects a failure because the value to be validated is a bad URL + * + * @throws RequestFailedException + * Expected + */ + @SuppressWarnings("nls") + @Test(expected = RequestFailedException.class) + public void testValidateParameterPatternExpectFailBadURL() throws RequestFailedException { + MDC.put(ProviderAdapterImpl.MDC_SERVICE, "junit"); + SvcLogicContext svcContext = new SvcLogicContext(); + RequestContext rc = new RequestContext(svcContext); + String link = "http://some.host:1234/01d82c08594a4b23a0f9260c94be0c4d/"; + + adapter.validateVMURL(VMURL.parseURL(link)); + } + + /** + * This test expects to pass + * + * @throws RequestFailedException + * Un-Expected + */ + @SuppressWarnings("nls") + @Test + public void testValidateParameterPatternValidURL() throws RequestFailedException { + MDC.put(ProviderAdapterImpl.MDC_SERVICE, "junit"); + SvcLogicContext svcContext = new SvcLogicContext(); + RequestContext rc = new RequestContext(svcContext); + String link = + "http://some.host:1234/v2/01d82c08594a4b23a0f9260c94be0c4d/servers/f888f89f-096b-421e-ba36-34f714071551"; + + adapter.validateVMURL(VMURL.parseURL(link)); + } +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestRequestContext.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestRequestContext.java new file mode 100644 index 000000000..a7cc5dc3c --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestRequestContext.java @@ -0,0 +1,159 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + +package org.openecomp.appc.adapter.iaas.impl; + +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Test; +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.impl.RequestContext; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; + +/** + * Test the RequestContext object + * <p> + * The request context is used to track retries, recovery attempts, and time to live of the processing of a request. + * </p> + */ + +public class TestRequestContext { + + private RequestContext rc; + private Configuration config = ConfigurationFactory.getConfiguration(); + + /** + * Set up the test environment by forcing the retry delay and limit to small values for the test and setting up the + * request context object. + */ + @Before + public void setup() { + config.setProperty(Constants.PROPERTY_RETRY_DELAY, "1"); + config.setProperty(Constants.PROPERTY_RETRY_LIMIT, "3"); + rc = new RequestContext(null); + rc.setTimeToLiveSeconds(2); + } + + /** + * Ensure that we set up the property correctly + */ + @Test + public void testRetryDelayProperty() { + assertEquals(1, rc.getRetryDelay()); + } + + /** + * Ensure that we set up the property correctly + */ + @Test + public void testRetryLimitProperty() { + assertEquals(3, rc.getRetryLimit()); + } + + /** + * This test ensures that the retry attempt counter is zero on a new context + */ + @Test + public void testRetryCountNoRetries() { + assertEquals(0, rc.getAttempts()); + } + + /** + * Test that the delay is accurate + */ + @Test + public void testDelay() { + long future = System.currentTimeMillis() + (rc.getRetryDelay() * 1000L); + + rc.delay(); + + assertTrue(System.currentTimeMillis() >= future); + } + + /** + * The RequestContext tracks the number of retry attempts against the limit. This test verifies that tracking logic + * works correctly. + */ + @Test + public void testCanRetry() { + assertEquals(0, rc.getAttempts()); + assertTrue(rc.attempt()); + assertEquals(1, rc.getAttempts()); + assertTrue(rc.attempt()); + assertEquals(2, rc.getAttempts()); + assertTrue(rc.attempt()); + assertEquals(3, rc.getAttempts()); + assertFalse(rc.attempt()); + assertEquals(3, rc.getAttempts()); + assertFalse(rc.attempt()); + assertEquals(3, rc.getAttempts()); + assertFalse(rc.attempt()); + assertEquals(3, rc.getAttempts()); + } + + /** + * The same RequestContext is used throughout the processing, and retries need to be reset once successfully + * connected so that any earlier (successful) recoveries are not considered when performing any new future + * recoveries. This test ensures that a reset clears the retry counter and that we can attempt retries again up to + * the limit. + */ + @Test + public void testResetAndCanRetry() { + assertTrue(rc.attempt()); + assertTrue(rc.attempt()); + assertTrue(rc.attempt()); + rc.reset(); + + assertTrue(rc.attempt()); + assertTrue(rc.attempt()); + assertTrue(rc.attempt()); + assertFalse(rc.attempt()); + assertFalse(rc.attempt()); + assertFalse(rc.attempt()); + } + + /** + * This test is used to test tracking of time to live for the request context. Because time is inexact, the + * assertions can only be ranges of values, such as at least some value or greater. The total duration tracking in + * the request context is only updated on each call to {@link RequestContext#isAlive()}. Also, durations are NOT + * affected by calls to reset. + */ + @Test + public void testTimeToLive() { + assertTrue(rc.getTotalDuration() == 0L); + assertTrue(rc.isAlive()); + rc.reset(); + rc.delay(); + assertTrue(rc.isAlive()); + assertTrue(rc.getTotalDuration() >= 1000L); + rc.reset(); + rc.delay(); + rc.isAlive(); + assertTrue(rc.getTotalDuration() >= 2000L); + rc.reset(); + rc.delay(); + assertFalse(rc.isAlive()); + assertTrue(rc.getTotalDuration() >= 3000L); + } +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestServiceCatalog.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestServiceCatalog.java new file mode 100644 index 000000000..ac8cde31a --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestServiceCatalog.java @@ -0,0 +1,147 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.adapter.iaas.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; +import java.util.Properties; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.openecomp.appc.adapter.iaas.impl.ServiceCatalog; +import org.openecomp.appc.configuration.ConfigurationFactory; +import com.att.cdp.exceptions.ZoneException; + +import com.woorea.openstack.keystone.model.Access.Service; + +/** + * This class tests the service catalog against a known provider. + */ +@Ignore +public class TestServiceCatalog { + + // Number + private static int EXPECTED_REGIONS = 1; + private static int EXPECTED_ENDPOINTS = 1; + + private static String PRINCIPAL; + private static String CREDENTIAL; + private static String TENANT_NAME; + private static String TENANT_ID; + private static String IDENTITY_URL; + private static String REGION_NAME; + + private ServiceCatalog catalog; + + private Properties properties; + + @BeforeClass + public static void before() { + Properties props = ConfigurationFactory.getConfiguration().getProperties(); + IDENTITY_URL = props.getProperty("provider1.identity"); + PRINCIPAL = props.getProperty("provider1.tenant1.userid", "appc"); + CREDENTIAL = props.getProperty("provider1.tenant1.password", "appc"); + TENANT_NAME = props.getProperty("provider1.tenant1.name", "appc"); + TENANT_ID = + props.getProperty("provider1.tenant1.id", + props.getProperty("test.tenantid", "abcde12345fghijk6789lmnopq123rst")); + REGION_NAME = props.getProperty("provider1.tenant1.region", "RegionOne"); + + EXPECTED_REGIONS = Integer.valueOf(props.getProperty("test.expected-regions", "0")); + EXPECTED_ENDPOINTS = Integer.valueOf(props.getProperty("test.expected-endpoints", "0")); + } + + /** + * Setup the test environment by loading a new service catalog for each test + * + * @throws ZoneException + */ + @Before + public void setup() throws ZoneException { + properties = new Properties(); + catalog = new ServiceCatalog(IDENTITY_URL, TENANT_NAME, PRINCIPAL, CREDENTIAL, properties); + } + + /** + * Test that the tenant name and ID are returned correctly + */ + @Test + public void testKnownTenant() { + assertEquals(TENANT_NAME, catalog.getTenantName()); + assertEquals(TENANT_ID, catalog.getTenantId()); + } + + /** + * Test that we find all of the expected region(s) + */ + @Test + public void testKnownRegions() { + assertEquals(EXPECTED_REGIONS, catalog.getRegions().size()); + // assertEquals(REGION_NAME, catalog.getRegions().toArray()[0]); + } + + /** + * Test that we can check for published services correctly + */ + @Test + public void testServiceTypesPublished() { + assertTrue(catalog.isServicePublished("compute")); + assertFalse(catalog.isServicePublished("bogus")); + } + + /** + * Check that we can get the list of published services + */ + @Test + public void testPublishedServicesList() { + List<String> services = catalog.getServiceTypes(); + + assertTrue(services.contains(ServiceCatalog.COMPUTE_SERVICE)); + assertTrue(services.contains(ServiceCatalog.IDENTITY_SERVICE)); + assertTrue(services.contains(ServiceCatalog.IMAGE_SERVICE)); + assertTrue(services.contains(ServiceCatalog.NETWORK_SERVICE)); + assertTrue(services.contains(ServiceCatalog.VOLUME_SERVICE)); + } + + /** + * Test that we can get the endpoint(s) for a service + */ + @Test + public void testEndpointList() { + List<Service.Endpoint> endpoints = catalog.getEndpoints(ServiceCatalog.COMPUTE_SERVICE); + + assertNotNull(endpoints); + assertFalse(endpoints.isEmpty()); + assertEquals(EXPECTED_ENDPOINTS, endpoints.size()); + + Service.Endpoint endpoint = endpoints.get(0); + // assertEquals(REGION_NAME, endpoint.getRegion()); + } +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestVMURL.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestVMURL.java new file mode 100644 index 000000000..852bb4137 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestVMURL.java @@ -0,0 +1,107 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.adapter.iaas.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.util.Properties; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.openecomp.appc.adapter.iaas.impl.VMURL; +import org.openecomp.appc.configuration.ConfigurationFactory; + +public class TestVMURL { + + private static String IP; + private static String PORT; + private static String TENANTID; + private static String VMID; + private static String URL; + + @BeforeClass + public static void before() { + Properties props = ConfigurationFactory.getConfiguration().getProperties(); + IP = props.getProperty("test.ip"); + PORT = props.getProperty("test.port"); + TENANTID = props.getProperty("test.tenantid"); + VMID = props.getProperty("test.vmid"); + URL = String.format("http://%s:%s/v2/%s/servers/%s", IP, PORT, TENANTID, VMID); + } + + /** + * Test that we can parse and interpret valid URLs + */ + @Test + public void testValidURLs() { + VMURL url = VMURL.parseURL(URL); + + assertEquals("http", url.getScheme()); + assertEquals(IP, url.getHost()); + assertEquals(PORT, url.getPort()); + assertEquals(TENANTID, url.getTenantId()); + assertEquals(VMID, url.getServerId()); + + url = VMURL.parseURL(String.format("http://%s/v2/%s/servers/%s", IP, TENANTID, VMID)); + assertEquals("http", url.getScheme()); + assertEquals(IP, url.getHost()); + assertNull(url.getPort()); + assertEquals(TENANTID, url.getTenantId()); + assertEquals(VMID, url.getServerId()); + } + + /** + * Test that we ignore and return null for invalid URLs + */ + @Test + public void testInvalidURLs() { + VMURL url = VMURL.parseURL(null); + assertNull(url); + + url = VMURL.parseURL(String.format("%s:%s/v2/%s/servers/%s", IP, PORT, TENANTID, VMID)); + assertNull(url); + + url = VMURL.parseURL(String.format("http:/%s:%s/v2/%s/servers/%s", IP, PORT, TENANTID, VMID)); + assertNull(url); + + url = VMURL.parseURL(String.format("http:///%s:%s/v2/%s/servers/%s", IP, PORT, TENANTID, VMID)); + assertNull(url); + + url = VMURL.parseURL(String.format("http://v2/%s/servers/%s", TENANTID, VMID)); + assertNull(url); + + url = VMURL.parseURL(String.format("%s:%s/%s/servers/%s", IP, PORT, TENANTID, VMID)); + assertNull(url); + + url = VMURL.parseURL(String.format("%s:%s/v2/servers/%s", IP, PORT, VMID)); + assertNull(url); + + url = VMURL.parseURL(String.format("%s:%s/v2/%s/%s", IP, PORT, TENANTID, VMID)); + assertNull(url); + + url = VMURL.parseURL(String.format("%s:%s/v2/%s/servers", IP, PORT, TENANTID)); + assertNull(url); + } +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/test/ExecutorHarness.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/test/ExecutorHarness.java new file mode 100644 index 000000000..d552edccf --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/test/ExecutorHarness.java @@ -0,0 +1,181 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.test; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.openecomp.appc.test.InterceptLogger; + +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + +/** + * This class is used as a test harness to wrap the call to an executor node. + */ + +public class ExecutorHarness { + + /** + * The executor to be tested + */ + private SvcLogicJavaPlugin executor; + + /** + * The collection of all exec methods found on the class + */ + private Map<String, Method> methods; + + /** + * The field of the class being tested that contains the reference to the logger to be used. This is modified to + * point to our interception logger for the test. + */ + private Field contextLogger; + + /** + * The interception logger that buffers all messages logged and allows us to look at them as part of the test case. + */ + private InterceptLogger logger; + + /** + * Create the harness and initialize it + * + * @throws SecurityException + * If a security manager, s, is present and any of the following conditions is met: + * <ul> + * <li>invocation of s.checkMemberAccess(this, Member.DECLARED) denies access to the declared field</li> + * <li>the caller's class loader is not the same as or an ancestor of the class loader for the current + * class and invocation of s.checkPackageAccess() denies access to the package of this class</li> + * </ul> + * @throws NoSuchFieldException + * if a field with the specified name is not found. + * @throws IllegalAccessException + * if this Field object is enforcing Java language access control and the underlying field is either + * inaccessible or final. + * @throws IllegalArgumentException + * if the specified object is not an instance of the class or interface declaring the underlying field + * (or a subclass or implementor thereof), or if an unwrapping conversion fails. + */ + @SuppressWarnings("nls") + public ExecutorHarness() throws NoSuchFieldException, SecurityException, IllegalArgumentException, + IllegalAccessException { + methods = new HashMap<>(); + new SvcLogicContext(); + + Class<?> contextClass = SvcLogicContext.class; + contextLogger = contextClass.getDeclaredField("LOG"); + contextLogger.setAccessible(true); + logger = new InterceptLogger(); + contextLogger.set(null, logger); + } + + /** + * Convenience constructor + * + * @param executor + * The executor to be tested by the harness + * @throws SecurityException + * If a security manager, s, is present and any of the following conditions is met: + * <ul> + * <li>invocation of s.checkMemberAccess(this, Member.DECLARED) denies access to the declared field</li> + * <li>the caller's class loader is not the same as or an ancestor of the class loader for the current + * class and invocation of s.checkPackageAccess() denies access to the package of this class</li> + * </ul> + * @throws NoSuchFieldException + * if a field with the specified name is not found. + * @throws IllegalAccessException + * if this Field object is enforcing Java language access control and the underlying field is either + * inaccessible or final. + * @throws IllegalArgumentException + * if the specified object is not an instance of the class or interface declaring the underlying field + * (or a subclass or implementor thereof), or if an unwrapping conversion fails. + */ + public ExecutorHarness(SvcLogicJavaPlugin executor) throws NoSuchFieldException, SecurityException, + IllegalArgumentException, IllegalAccessException { + this(); + setExecutor(executor); + } + + /** + * @param executor + * The java plugin class to be executed + */ + public void setExecutor(SvcLogicJavaPlugin executor) { + this.executor = executor; + scanExecutor(); + } + + /** + * @return The java plugin class to be executed + */ + public SvcLogicJavaPlugin getExecutor() { + return executor; + } + + /** + * @return The set of all methods that meet the signature requirements + */ + public List<String> getExecMethodNames() { + List<String> names = new ArrayList<>(); + names.addAll(methods.keySet()); + return names; + } + + /** + * Returns an indication if the named method is a valid executor method that could be called from a DG execute node + * + * @param methodName + * The method name to be validated + * @return True if the method name meets the signature requirements, false if the method either does not exist or + * does not meet the requirements. + */ + public boolean isExecMethod(String methodName) { + return methods.containsKey(methodName); + } + + /** + * This method scans the executor class hierarchy to locate all methods that match the required signature of the + * executor and records these methods in a map. + */ + private void scanExecutor() { + methods.clear(); + Class<?> executorClass = executor.getClass(); + Method[] publicMethods = executorClass.getMethods(); + for (Method method : publicMethods) { + if (method.getReturnType().equals(Void.class)) { + Class<?>[] paramTypes = method.getParameterTypes(); + if (paramTypes.length == 2) { + if (Map.class.isAssignableFrom(paramTypes[0]) + && SvcLogicContext.class.isAssignableFrom(paramTypes[1])) { + methods.put(method.getName(), method); + } + } + } + } + } +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/test/InterceptLogger.java b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/test/InterceptLogger.java new file mode 100644 index 000000000..394352136 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/test/InterceptLogger.java @@ -0,0 +1,451 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + +package org.openecomp.appc.test; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Marker; + +import ch.qos.logback.classic.Level; + +/** + * This class is used as an intercept logger that can be used in testing to intercept and record all messages that are + * logged, thus allowing a junit test case to examine the log output and make assertions. + */ +public class InterceptLogger implements org.slf4j.Logger { + + /** + * This inner class represents an intercepted log event. + */ + public class LogRecord { + private Level level; + private String message; + private long timestamp; + private Throwable t; + + public LogRecord(Level level, String message) { + setLevel(level); + setTimestamp(System.currentTimeMillis()); + setMessage(message); + } + + public LogRecord(Level level, String message, Throwable t) { + this(level, message); + setThrowable(t); + } + + /** + * @return the value of level + */ + public Level getLevel() { + return level; + } + + /** + * @return the value of message + */ + public String getMessage() { + return message; + } + + /** + * @return the value of timestamp + */ + public long getTimestamp() { + return timestamp; + } + + /** + * @param level + * the value for level + */ + public void setLevel(Level level) { + this.level = level; + } + + /** + * @param message + * the value for message + */ + public void setMessage(String message) { + this.message = message; + } + + /** + * @param timestamp + * the value for timestamp + */ + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + /** + * @return the value of t + */ + public Throwable getThrowable() { + return t; + } + + /** + * @param t + * the value for t + */ + public void setThrowable(Throwable t) { + this.t = t; + } + + } + + /** + * The list of all intercepted log events + */ + private List<LogRecord> events; + + /** + * Create the intercept logger + */ + public InterceptLogger() { + events = new ArrayList<LogRecord>(1000); + } + + /** + * @return Returns all intercepted log events + */ + public List<LogRecord> getLogRecords() { + return events; + } + + /** + * Clears all log events + */ + public void clear() { + events.clear(); + } + + @Override + public void debug(Marker marker, String msg) { + debug(msg); + } + + @Override + public void debug(Marker marker, String format, Object arg) { + debug(MessageFormat.format(format, arg)); + } + + @Override + public void debug(Marker marker, String format, Object... arguments) { + debug(MessageFormat.format(format, arguments)); + } + + @Override + public void debug(Marker marker, String format, Object arg1, Object arg2) { + debug(MessageFormat.format(format, arg1, arg2)); + } + + @Override + public void debug(Marker marker, String msg, Throwable t) { + debug(msg, t); + } + + @Override + public void debug(String msg) { + events.add(new LogRecord(Level.DEBUG, msg)); + } + + @Override + public void debug(String format, Object arg) { + events.add(new LogRecord(Level.DEBUG, MessageFormat.format(format, arg))); + } + + @Override + public void debug(String format, Object... arguments) { + events.add(new LogRecord(Level.DEBUG, MessageFormat.format(format, arguments))); + } + + @Override + public void debug(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.DEBUG, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void debug(String msg, Throwable t) { + events.add(new LogRecord(Level.DEBUG, msg, t)); + } + + @Override + public void error(Marker marker, String msg) { + error(msg); + } + + @Override + public void error(Marker marker, String format, Object arg) { + error(format, arg); + } + + @Override + public void error(Marker marker, String format, Object... arguments) { + error(format, arguments); + } + + @Override + public void error(Marker marker, String format, Object arg1, Object arg2) { + error(format, arg1, arg2); + } + + @Override + public void error(Marker marker, String msg, Throwable t) { + events.add(new LogRecord(Level.ERROR, msg, t)); + } + + @Override + public void error(String msg) { + events.add(new LogRecord(Level.ERROR, msg)); + } + + @Override + public void error(String format, Object arg) { + events.add(new LogRecord(Level.ERROR, MessageFormat.format(format, arg))); + } + + @Override + public void error(String format, Object... arguments) { + events.add(new LogRecord(Level.ERROR, MessageFormat.format(format, arguments))); + } + + @Override + public void error(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.ERROR, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void error(String msg, Throwable t) { + events.add(new LogRecord(Level.ERROR, msg, t)); + } + + @Override + public String getName() { + return null; + } + + @Override + public void info(Marker marker, String msg) { + info(msg); + } + + @Override + public void info(Marker marker, String format, Object arg) { + info(format, arg); + } + + @Override + public void info(Marker marker, String format, Object... arguments) { + info(format, arguments); + } + + @Override + public void info(Marker marker, String format, Object arg1, Object arg2) { + info(format, arg1, arg2); + } + + @Override + public void info(Marker marker, String msg, Throwable t) { + events.add(new LogRecord(Level.INFO, msg, t)); + } + + @Override + public void info(String msg) { + events.add(new LogRecord(Level.INFO, msg)); + } + + @Override + public void info(String format, Object arg) { + events.add(new LogRecord(Level.INFO, MessageFormat.format(format, arg))); + } + + @Override + public void info(String format, Object... arguments) { + events.add(new LogRecord(Level.INFO, MessageFormat.format(format, arguments))); + } + + @Override + public void info(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.INFO, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void info(String msg, Throwable t) { + events.add(new LogRecord(Level.INFO, msg, t)); + } + + @Override + public boolean isDebugEnabled() { + return true; + } + + @Override + public boolean isDebugEnabled(Marker marker) { + return true; + } + + @Override + public boolean isErrorEnabled() { + return true; + } + + @Override + public boolean isErrorEnabled(Marker marker) { + return true; + } + + @Override + public boolean isInfoEnabled() { + return true; + } + + @Override + public boolean isInfoEnabled(Marker marker) { + return true; + } + + @Override + public boolean isTraceEnabled() { + return true; + } + + @Override + public boolean isTraceEnabled(Marker marker) { + return true; + } + + @Override + public boolean isWarnEnabled() { + return true; + } + + @Override + public boolean isWarnEnabled(Marker marker) { + return true; + } + + @Override + public void trace(Marker marker, String msg) { + trace(msg); + } + + @Override + public void trace(Marker marker, String format, Object arg) { + trace(format, arg); + } + + @Override + public void trace(Marker marker, String format, Object... argArray) { + trace(format, argArray); + } + + @Override + public void trace(Marker marker, String format, Object arg1, Object arg2) { + trace(format, arg1, arg2); + } + + @Override + public void trace(Marker marker, String msg, Throwable t) { + trace(msg, t); + } + + @Override + public void trace(String msg) { + events.add(new LogRecord(Level.TRACE, msg)); + } + + @Override + public void trace(String format, Object arg) { + events.add(new LogRecord(Level.TRACE, MessageFormat.format(format, arg))); + } + + @Override + public void trace(String format, Object... arguments) { + events.add(new LogRecord(Level.TRACE, MessageFormat.format(format, arguments))); + } + + @Override + public void trace(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.TRACE, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void trace(String msg, Throwable t) { + events.add(new LogRecord(Level.TRACE, msg, t)); + } + + @Override + public void warn(Marker marker, String msg) { + warn(msg); + } + + @Override + public void warn(Marker marker, String format, Object arg) { + warn(format, arg); + } + + @Override + public void warn(Marker marker, String format, Object... arguments) { + warn(format, arguments); + } + + @Override + public void warn(Marker marker, String format, Object arg1, Object arg2) { + warn(format, arg1, arg2); + } + + @Override + public void warn(Marker marker, String msg, Throwable t) { + events.add(new LogRecord(Level.WARN, msg, t)); + } + + @Override + public void warn(String msg) { + events.add(new LogRecord(Level.WARN, msg)); + } + + @Override + public void warn(String format, Object arg) { + events.add(new LogRecord(Level.WARN, MessageFormat.format(format, arg))); + } + + @Override + public void warn(String format, Object... arguments) { + events.add(new LogRecord(Level.WARN, MessageFormat.format(format, arguments))); + } + + @Override + public void warn(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.WARN, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void warn(String msg, Throwable t) { + events.add(new LogRecord(Level.WARN, msg, t)); + } +} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..2daa085ad --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/resources/org/openecomp/appc/default.properties @@ -0,0 +1,109 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# +# Default properties for the APP-C Provider Adapter +# +# ------------------------------------------------------------------------------------------------- +# +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + +appc.application.name=APPC + +# +# Define the message resource bundle name to be loaded +org.openecomp.appc.resources=org/openecomp/appc/i18n/MessageResources +# +# The name of the adapter. +org.openecomp.appc.provider.adaptor.name=org.openecomp.appc.appc_provider_adapter +# +# Set up the logging environment +# +org.openecomp.appc.logging.file=org/openecomp/appc/logback.xml +org.openecomp.appc.logging.path=${user.home};etc;../etc +org.openecomp.appc.logger=org.openecomp.appc +org.openecomp.appc.security.logger=org.openecomp.appc.security +# +# The minimum and maximum provider/tenant context pool sizes. Min=1 means that as soon +# as the provider/tenant is referenced a Context is opened and added to the pool. Max=0 +# means that the upper bound on the pool is unbounded. +org.openecomp.appc.provider.min.pool=1 +org.openecomp.appc.provider.max.pool=0 + +# +# The following properties are used to configure the retry logic for connection to the +# IaaS provider(s). The retry delay property is the amount of time, in seconds, the +# application waits between retry attempts. The retry limit is the number of retries +# that are allowed before the request is failed. +org.openecomp.appc.provider.retry.delay = 30 +org.openecomp.appc.provider.retry.limit = 10 + +# +# The trusted hosts list for SSL access when a certificate is not provided. +# +provider.trusted.hosts=* +# +# The amount of time, in seconds, to wait for a server state change (start->stop, stop->start, etc). +# If the server does not change state to a valid state within the alloted time, the operation +# fails. +org.openecomp.appc.server.state.change.timeout=300 +# +# The amount of time to wait, in seconds, between subsequent polls to the OpenStack provider +# to refresh the status of a resource we are waiting on. +# +org.openecomp.appc.openstack.poll.interval=20 +# +# The connection information to connect to the provider we are using. These properties +# are "structured" properties, in that the name is a compound name, where the nodes +# of the name can be ordered (1, 2, 3, ...). All of the properties with the same ordinal +# position are defining the same entity. For example, provider1.type and provider1.name +# are defining the same provider, whereas provider2.name and provider2.type are defining +# the values for a different provider. Any number of providers can be defined in this +# way. +# + + +# Don't change these 2 right now since they are hard coded in the DG +provider1.type=appc +provider1.name=appc + +#These you can change +provider1.identity=appc +provider1.tenant1.name=appc +provider1.tenant1.userid=appc +provider1.tenant1.password=appc + +# After a change to the provider make sure to recheck these values with an api call to provider1.identity/tokens +test.expected-regions=1 +test.expected-endpoints=1 + +#Your OpenStack IP +test.ip=192.168.1.2 +# Your OpenStack Platform's Keystone Port (default is 5000) +test.port=5000 +test.tenantid=abcde12345fghijk6789lmnopq123rst +test.vmid=abc12345-1234-5678-890a-abcdefg12345 +# Port 8774 below is default port for OpenStack's Nova API Service +test.url=http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345 + diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-features/.gitignore b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-features/.gitignore new file mode 100644 index 000000000..615a76bbc --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-features/.gitignore @@ -0,0 +1,4 @@ +/target/ +/bin/ +/classes/ +/.settings/ diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-features/pom.xml b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-features/pom.xml new file mode 100644 index 000000000..48588a6fb --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-features/pom.xml @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-iaas-adapter</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>appc-iaas-adapter-features</artifactId> + <name>IaaS Adaptor - Features</name> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-iaas-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>features-mdsal</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </dependency> + + <!-- dependency for opendaylight-karaf-empty for use by testing --> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>opendaylight-karaf-empty</artifactId> + <type>zip</type> + </dependency> + +<!-- <dependency> --> +<!-- Required for launching the feature tests --> +<!-- <groupId>org.opendaylight.yangtools</groupId> --> +<!-- <artifactId>features-test</artifactId> --> +<!-- <scope>test</scope> --> +<!-- </dependency> --> + + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>features-yangtools</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <!-- launches the feature test, which validates that your karaf feature + can be installed inside of a karaf container. It doesn't validate that your + functionality works correctly, just that you have all of the dependent bundles + defined correctly. --> + <!-- <plugin> --> + <!-- <groupId>org.apache.maven.plugins</groupId> --> + <!-- <artifactId>maven-surefire-plugin</artifactId> --> + <!-- <version>2.16</version> --> + <!-- <configuration> --> + <!-- <systemPropertyVariables> --> + <!-- <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId> --> + <!-- <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId> --> + <!-- <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version> --> + <!-- </systemPropertyVariables> --> + <!-- <dependenciesToScan> --> + <!-- <dependency>org.opendaylight.yangtools:features-test</dependency> --> + <!-- </dependenciesToScan> --> + <!-- </configuration> --> + <!-- </plugin> --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-features/src/main/resources/features.xml b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-features/src/main/resources/features.xml new file mode 100644 index 000000000..f68027e90 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-features/src/main/resources/features.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="appc-iaas-adapter-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + +<!-- <repository>mvn:org.opendaylight.mdsal/features-mdsal/${odl.mdsal.version}/xml/features</repository> --> + <repository>mvn:org.opendaylight.mdsal/features-mdsal/${features-mdsal.version}/xml/features</repository> + + + <feature name='appc-iaas-adapter' description="appc-iaas-adapter" version='${project.version}'> + <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> +<!-- <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> --> + <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> + <feature>sdnc-sli</feature> + <bundle>mvn:org.openecomp.appc/appc-iaas-adapter-bundle/${project.version}</bundle> + </feature> + +</features> diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-installer/.gitignore b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-installer/.gitignore new file mode 100644 index 000000000..731eb433c --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-installer/.gitignore @@ -0,0 +1,2 @@ +/target/ +/.settings/ diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-installer/pom.xml b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-installer/pom.xml new file mode 100644 index 000000000..376196e42 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-installer/pom.xml @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-iaas-adapter</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>appc-iaas-adapter-installer</artifactId> + <name>IaaS Adapter - Karaf Installer</name> + <packaging>pom</packaging> + + <properties> + <application.name>appc-iaas-adapter</application.name> + <features.boot>appc-iaas-adapter</features.boot> + <features.repositories>mvn:org.openecomp.appc/appc-iaas-adapter-features/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-iaas-adapter-features</artifactId> + <classifier>features</classifier> + <type>xml</type> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-iaas-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>mvn-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>false</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>true</attach> + <finalName>${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <excludeGroupIds>org.opendaylight</excludeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals> + <!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-installer/src/assembly/assemble_installer_zip.xml b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..9fbaad8c5 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>adapter</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..1ac5a82bc --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,47 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>adapter</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + +</assembly> diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-installer/src/main/resources/scripts/install-feature.sh b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..1d769fada --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,40 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +#!/bin/bash + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -n -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot} diff --git a/app-c/appc/appc-adapters/appc-iaas-adapter/pom.xml b/app-c/appc/appc-adapters/appc-iaas-adapter/pom.xml new file mode 100644 index 000000000..27ae766fc --- /dev/null +++ b/app-c/appc/appc-adapters/appc-iaas-adapter/pom.xml @@ -0,0 +1,125 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-adapters</artifactId> + <version>1.0.0</version> + </parent> + + <artifactId>appc-iaas-adapter</artifactId> + <name>IaaS Adaptor</name> + <description>Abstraction to connect to and utilize the services of cloud providers such as OpenStack or VMWare.</description> + <packaging>pom</packaging> + + <reporting> + <plugins> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <additionalDependencies> + <additionalDependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4</artifactId> + <version>${antlr.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4-runtime</artifactId> + <version>4.3</version> + </additionalDependency> + </additionalDependencies> + </configuration> + <reportSets> + <reportSet> + <reports> + <report>javadoc-no-fork</report> + <report>test-javadoc-no-fork</report> + </reports> + </reportSet> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jxr-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-changelog-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>dual-report</id> + <configuration> + <type>range</type> + <range>30</range> + </configuration> + <reports> + <report>changelog</report> + <report>file-activity</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>taglist-maven-plugin</artifactId> + <version>2.4</version> + </plugin> + </plugins> + </reporting> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-iaas-adapter-features</artifactId> + <classifier>features</classifier> + <type>xml</type> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-iaas-adapter-provider</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + + </dependencyManagement> + + <modules> + <module>appc-iaas-adapter-bundle</module> + <module>appc-iaas-adapter-features</module> + <module>appc-iaas-adapter-installer</module> + </modules> +</project> diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-adapters/appc-netconf-adapter/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/pom.xml b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/pom.xml new file mode 100644 index 000000000..861529836 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/pom.xml @@ -0,0 +1,189 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-netconf-adapter</artifactId> + <version>1.0.0</version> + </parent> + + <artifactId>appc-netconf-adapter-bundle</artifactId> + <packaging>bundle</packaging> + <name>NETCONF Adapter - bundle</name> + <properties> + <exam.version>4.9.1</exam.version> + <url.version>1.6.0</url.version> + <sal-netconf-connector.version>1.3.1-Beryllium-SR1</sal-netconf-connector.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dmaap-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>javax</groupId> + <artifactId>javaee-api</artifactId> + <version>7.0</version> + </dependency> + + <dependency> + <groupId>com.att.cdp</groupId> + <artifactId>cdp-pal-common</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>com.att.cdp</groupId> + <artifactId>cdp-pal-openstack</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>javax.ws.rs</groupId> + <artifactId>javax.ws.rs-api</artifactId> + </dependency> + + <!-- Jersey support needed for OpenStack connector and API version logic --> + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-client</artifactId> + </dependency> + + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-json</artifactId> + </dependency> + + <dependency> + <groupId>javax.xml.bind</groupId> + <artifactId>jaxb-api</artifactId> + <version>2.1</version> + </dependency> + + <!-- Needed to run test cases --> + <dependency> + <groupId>org.glassfish.jersey.core</groupId> + <artifactId>jersey-common</artifactId> + <version>2.9.1</version> + </dependency> + + <dependency> + <groupId>org.codehaus.jackson</groupId> + <artifactId>jackson-jaxrs</artifactId> + <version>1.9.12</version> + </dependency> + + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>4.5.1</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>equinoxSDK381</groupId> + <artifactId>org.eclipse.osgi</artifactId> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </dependency> + + <dependency> + <groupId>com.vmware</groupId> + <artifactId>vijava</artifactId> + <version>5.1</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>xerces</groupId> + <artifactId>xerces</artifactId> + <version>2.4.0</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore</artifactId> + <version>${apache.httpcomponents.version}</version> + </dependency> + + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>1.2</version> + </dependency> + + <dependency> + <groupId>org.json</groupId> + <artifactId>json</artifactId> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>appc-netconf-adapter</Bundle-SymbolicName> + <Bundle-Activator>org.openecomp.appc.adapter.netconf.AppcNetconfAdapterActivator</Bundle-Activator> + <Export-Package>org.openecomp.appc.adapter.netconf,org.openecomp.appc.adapter.netconf.dao,org.openecomp.appc.adapter.netconf.util,org.openecomp.appc.adapter.netconf.exception</Export-Package> + <Import-Package> + org.w3c.dom.*,com.sun.org.apache.xerces.*,javax.sql.*,javax.sql.rowset.*,javax.xml.*,org.openecomp.appc.adapter.dmaap.*,javax.crypto.*,org.openecomp.appc.common.exception.*,com.mysql.*,org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.bind.*,javax.naming.* + </Import-Package> + <Embed-Dependency>*;scope=compile|runtime;artifactId=!sli-common|dblib-provider|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis|appc-dmaap-adapter-bundle</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + + <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/AppcNetconfAdapterActivator.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/AppcNetconfAdapterActivator.java new file mode 100644 index 000000000..aac49c288 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/AppcNetconfAdapterActivator.java @@ -0,0 +1,130 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf; + +import org.openecomp.appc.adapter.netconf.internal.NetconfDataAccessServiceImpl; +import org.openecomp.sdnc.sli.resource.dblib.DbLibService; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; + +public class AppcNetconfAdapterActivator implements BundleActivator { + + /** + * The bundle registration + */ + private ServiceRegistration registration = null; + private ServiceRegistration reporterRegistration = null; + private ServiceRegistration factoryRegistration = null; + private ServiceRegistration dbRegistration = null; + + /** + * The reference to the actual implementation object that implements the services + */ + private NetconfClientFactory clientFactory; + private NetconfDataAccessService DAService; + + /** + * The logger to be used + */ + //private static final EELFLogger logger = EELFManager.getInstance().getLogger(AppcNetconfAdapterActivator.class); + + /** + * Called when this bundle is started so the Framework can perform the bundle-specific activities necessary to start + * this bundle. This method can be used to register services or to allocate any resources that this bundle needs. + * <p> + * This method must complete and return to its caller in a timely manner. + * </p> + * + * @param context + * The execution context of the bundle being started. + * @throws java.lang.Exception + * If this method throws an exception, this bundle is marked as stopped and the Framework will remove + * this bundle's listeners, unregister all services registered by this bundle, and release all services + * used by this bundle. + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + + if (registration == null) { + clientFactory = new NetconfClientFactory(); + factoryRegistration = context.registerService(NetconfClientFactory.class, clientFactory, null); + + DAService = new NetconfDataAccessServiceImpl(); + //set dblib service + DbLibService dblibSvc = null; + ServiceReference sref = context.getServiceReference(DbLibService.class.getName()); + dblibSvc = (DbLibService)context.getService(sref); + DAService.setDbLibService(dblibSvc); + /////////////////////////////////// + factoryRegistration = context.registerService(NetconfDataAccessService.class, DAService, null); + } + + //logger.info(Msg.COMPONENT_INITIALIZED, "NETCONF adapter"); + } + + /** + * Called when this bundle is stopped so the Framework can perform the bundle-specific activities necessary to stop + * the bundle. In general, this method should undo the work that the BundleActivator.start method started. There + * should be no active threads that were started by this bundle when this bundle returns. A stopped bundle must not + * call any Framework objects. + * <p> + * This method must complete and return to its caller in a timely manner. + * </p> + * + * @param context + * The execution context of the bundle being stopped. + * @throws java.lang.Exception + * If this method throws an exception, the bundle is still marked as stopped, and the Framework will + * remove the bundle's listeners, unregister all services registered by the bundle, and release all + * services used by the bundle. * + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + if (registration != null) { + registration.unregister(); + registration = null; + } + if (reporterRegistration != null) { + reporterRegistration.unregister(); + reporterRegistration = null; + } + + if (null != factoryRegistration) { + factoryRegistration.unregister(); + factoryRegistration = null; + } + + if (dbRegistration != null) { + dbRegistration.unregister(); + dbRegistration = null; + } + } + + public String getName() { + return "APPC NETCONF adapter"; + } + +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/ConnectionDetails.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/ConnectionDetails.java new file mode 100644 index 000000000..71fe16f6b --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/ConnectionDetails.java @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf; + + +public class ConnectionDetails { + + private String host; + private int port; + private String username; + private String password; + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/MockOperationalStateValidatorImpl.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/MockOperationalStateValidatorImpl.java new file mode 100644 index 000000000..95eae28af --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/MockOperationalStateValidatorImpl.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf; + +import org.openecomp.appc.exceptions.APPCException; + + +public class MockOperationalStateValidatorImpl implements OperationalStateValidator { + @Override + public VnfType getVnfType() { + return VnfType.MOCK; + } + + @Override + public String getConfigurationFileName() { + String configFileName = OperationalStateValidatorFactory.configuration.getProperty(this.getClass().getCanonicalName() + CONFIG_FILE_PROPERTY_SUFFIX); + return configFileName; + } + + @Override + public void validateResponse(String response) throws APPCException { + if(response != null && response.toUpperCase().contains("INVALID")){ + throw new APPCException("INVALID"); + } + } +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/NetconfClient.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/NetconfClient.java new file mode 100644 index 000000000..904155273 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/NetconfClient.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf; + +import org.openecomp.appc.exceptions.APPCException; + + + +public interface NetconfClient { + + /** + * Open connection to netconf device. + * + * @param connectionDetails object providing details required for netconf connection + */ + void connect(NetconfConnectionDetails connectionDetails) throws APPCException; + + /** + * Send Netconf message to device and receive response. + * + * @param message input netconf xml message + * @return output netconf xml message + */ + String exchangeMessage(String message) throws APPCException; + + /** + * send configuration to Netconf server + * + * @param configuration - xml configuration payload + */ + void configure(String configuration) throws APPCException; + + /** + * returns running configuration of Netconf server + */ + String getConfiguration() throws APPCException; + + /** + * Disconnect from netconf device. + */ + void disconnect() throws APPCException; +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/NetconfClientFactory.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/NetconfClientFactory.java new file mode 100644 index 000000000..20fec5c49 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/NetconfClientFactory.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf; + +import org.openecomp.appc.adapter.netconf.jsch.NetconfClientJsch; +import org.openecomp.appc.adapter.netconf.odlconnector.NetconfClientRestconfImpl; + + +public class NetconfClientFactory { + + public NetconfClient GetNetconfClient(NetconfClientType type){ + + if(type==NetconfClientType.RESTCONF) { + return new NetconfClientRestconfImpl(); + }else if(type == NetconfClientType.SSH){ + return new NetconfClientJsch(); + } + + return null; + } +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/NetconfClientRestconf.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/NetconfClientRestconf.java new file mode 100644 index 000000000..04368615a --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/NetconfClientRestconf.java @@ -0,0 +1,70 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf; + +import org.openecomp.appc.exceptions.APPCException; + + + +public interface NetconfClientRestconf { + + /* + mount device to controller + @param deviceMountPointName - the name of the mounting point in controller + @param payload - json data describing device info + */ + void connect(String deviceMountPointName, String payload) throws APPCException; + + /* + check connection to device + @param deviceMountPointName - the name of the mounting point in controller + */ + boolean checkConnection(String deviceMountPointName) throws APPCException; + + /* + send configuration to Netconf server + @param configuration - xml configuration payload + @param deviceMountPointName - the name of the mounting point in controller + @param moduleName - name of the yang model + @param nodeName - name of the node created in server + */ + void configure(String configuration, String deviceMountPointName, String moduleName, String nodeName) throws APPCException; + + /* + backup device configuration + @param deviceMountPointName - the name of the mounting point in controlle + */ + //void backupConfiguration(String deviceMountPointName); + /* + returns configuration of Netconf server + @param deviceMountPointName - the name of the mounting point in controller + @param moduleName - name of the yang model + @param nodeName - name of the node created in server + */ + String getConfiguration(String deviceName, String moduleName, String nodeName) throws APPCException; + + /* + unmount device + @param deviceMountPointName - the name of the mounting point in controller + */ + void disconnect(String deviceMountPointName) throws APPCException; +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/NetconfClientType.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/NetconfClientType.java new file mode 100644 index 000000000..9757ae9ec --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/NetconfClientType.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf; + + +public enum NetconfClientType { + RESTCONF, + SSH +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/NetconfConnectionDetails.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/NetconfConnectionDetails.java new file mode 100644 index 000000000..fdbda2916 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/NetconfConnectionDetails.java @@ -0,0 +1,92 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf; + +import java.util.List; +import java.util.Properties; + +/** + * Provides details required for connecting to netconf device. + */ +public class NetconfConnectionDetails { + + private String host; + private int port; + private String username; + private String password; + + public static int DEFAULT_PORT = 830; + private List<String> capabilities; + private Properties additionalProperties; + + public NetconfConnectionDetails() { + super(); + setPort(DEFAULT_PORT); + } + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public List<String> getCapabilities() { + return capabilities; + } + + public void setCapabilities(List<String> capabilities) { + this.capabilities = capabilities; + } + + public Properties getAdditionalProperties() { + return additionalProperties; + } + + public void setAdditionalProperties(Properties additionalProperties) { + this.additionalProperties = additionalProperties; + } +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/NetconfDataAccessService.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/NetconfDataAccessService.java new file mode 100644 index 000000000..3536cf3b9 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/NetconfDataAccessService.java @@ -0,0 +1,82 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf; + +import org.openecomp.appc.adapter.netconf.exception.DataAccessException; +import org.openecomp.sdnc.sli.resource.dblib.DbLibService; + + +@SuppressWarnings("JavaDoc") +public interface NetconfDataAccessService { + + /** + * + * @param schema + */ + void setSchema(String schema); + + /** + * + * @param dbLibService + */ + void setDbLibService(DbLibService dbLibService); + + /** + * + * @param xmlID + * @return + * @throws DataAccessException + */ + String retrieveConfigFileName(String xmlID) throws DataAccessException; + + /** + * + * @param vnfType + * @param connectionDetails + * @return + * @throws DataAccessException + */ + boolean retrieveConnectionDetails(String vnfType, ConnectionDetails connectionDetails) throws DataAccessException; + + /** + * + * @param vnfType + * @param connectionDetails + * @return + * @throws DataAccessException + */ + boolean retrieveNetconfConnectionDetails(String vnfType, NetconfConnectionDetails connectionDetails) throws + DataAccessException; + + /** + * + * @param instanceId + * @param requestId + * @param creationDate + * @param logText + * @return + * @throws DataAccessException + */ + boolean logDeviceInteraction(String instanceId, String requestId, String creationDate, String logText) throws + DataAccessException; + +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/OperationalStateValidator.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/OperationalStateValidator.java new file mode 100644 index 000000000..fb9aba002 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/OperationalStateValidator.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf; + +import org.openecomp.appc.exceptions.APPCException; + + +public interface OperationalStateValidator { + public VnfType getVnfType(); + public String getConfigurationFileName(); + public void validateResponse(String response) throws APPCException; + final public static String CONFIG_FILE_PROPERTY_SUFFIX = "-CONFIG_FILE"; +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/OperationalStateValidatorFactory.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/OperationalStateValidatorFactory.java new file mode 100644 index 000000000..94b87f497 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/OperationalStateValidatorFactory.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf; + +import org.apache.commons.lang3.NotImplementedException; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; + +public class OperationalStateValidatorFactory { + protected static final Configuration configuration = ConfigurationFactory.getConfiguration(); + + public static OperationalStateValidator getOperationalStateValidator(String vnfType) { + VnfType vnfTypeEnum = null; + try { + vnfTypeEnum = VnfType.getVnfType(vnfType); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Illegal value in vnfType. vnfType="+vnfType,e); + } + return getOperationalStateValidator(vnfTypeEnum); + } + + public static OperationalStateValidator getOperationalStateValidator(VnfType vnfType) { + switch (vnfType) { + case VNF: + case VNF_MOCK: + return new VNFOperationalStateValidatorImpl(); + case MOCK: + return new MockOperationalStateValidatorImpl(); + default: + throw new NotImplementedException("missing implementaion for the given vnfType:" + vnfType.name()); + } + } +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/VNFOperationalStateValidatorImpl.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/VNFOperationalStateValidatorImpl.java new file mode 100644 index 000000000..fa84ea1a1 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/VNFOperationalStateValidatorImpl.java @@ -0,0 +1,132 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf; + +import org.apache.commons.lang3.StringUtils; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.StringReader; +import java.util.*; + +public class VNFOperationalStateValidatorImpl implements OperationalStateValidator { + private static final String OPERATIONAL_STATE_ELEMENT_NAME = "operationalState"; + @Override + public VnfType getVnfType() { + return VnfType.VNF; + } + + @Override + public String getConfigurationFileName() { + String configFileName = OperationalStateValidatorFactory.configuration.getProperty(this.getClass().getCanonicalName() + CONFIG_FILE_PROPERTY_SUFFIX); + configFileName = configFileName == null? "VnfGetOperationalStates" : configFileName; + return configFileName; + } + + @Override + public void validateResponse(String response) throws APPCException { + if(StringUtils.isEmpty(response)) { + throw new APPCException("empty response"); + } + + boolean isValid = false; + String errorMsg = "unexpected response"; + try { + List<Map.Entry> operationalStateList = getOperationalStateList(response); + if(operationalStateList != null && !operationalStateList.isEmpty()) { + for (Map.Entry stateEntry : operationalStateList) { + if(!((String)stateEntry.getValue()).equalsIgnoreCase("ENABLED")){ + errorMsg = "at least one "+OPERATIONAL_STATE_ELEMENT_NAME+" is not in valid satae. "+operationalStateList.toString(); + isValid = false; + break; + }else{ + isValid =true; + } + } + }else { + errorMsg = "response without any "+OPERATIONAL_STATE_ELEMENT_NAME+" element"; + } + } catch (Exception e ) { + isValid = false; + errorMsg = e.toString(); + } + if(!isValid) throw new APPCException(errorMsg); + } + + private static List<Map.Entry> getOperationalStateList(String xmlText) throws IOException, ParserConfigurationException, SAXException { + List<Map.Entry> entryList = null; + if(StringUtils.isNotEmpty(xmlText)) { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + + Document document = builder.parse(new ByteArrayInputStream(xmlText.getBytes("UTF-8"))); + if(document != null) { + Element rootElement = document.getDocumentElement(); + NodeList nodeList = rootElement.getElementsByTagName(OPERATIONAL_STATE_ELEMENT_NAME); + if (nodeList != null && nodeList.getLength() > 0) { + for (int i = 0; i < nodeList.getLength(); i++) { + Node node = nodeList.item(i); + String text = node.getTextContent(); + String id = getElementID(node); + entryList = (entryList == null) ? new ArrayList<Map.Entry>() : entryList; + Map.Entry entry = new AbstractMap.SimpleEntry<String, String>(id, text); + entryList.add(entry); + } + } + } + } + return entryList; + } + + private static String getElementID(Node node) { + String id = null; + Node parentNode = node.getParentNode(); + if (parentNode != null) { + if (node.getNodeType() == Node.ELEMENT_NODE) { + NodeList nodeList = ((Element) parentNode).getElementsByTagName("id"); + if (nodeList != null && nodeList.getLength() > 0) { + Node idNode = nodeList.item(0); + id = idNode != null ? idNode.getTextContent() : null; + } + }else { + id = parentNode.getNodeValue()+"|"+parentNode.getTextContent(); + } + } + + id = StringUtils.isEmpty(id) ? null : StringUtils.normalizeSpace(id); + id = StringUtils.isBlank(id) ? null : id; + id = id != null ? id : "unknown-id"; + return id; + } + +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/VnfType.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/VnfType.java new file mode 100644 index 000000000..18f334fa1 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/VnfType.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf; + +public enum VnfType { + VNF("VNF"), + MOCK("MOCK"), + VNF_MOCK("MOCK"), + ; + + String familyType; + String upperCaseName; + VnfType(String familyType) { + this.familyType = familyType; + this.upperCaseName = name().toUpperCase(); + } + + public VnfType getFamilyType() { + return VnfType.valueOf(familyType); + } + + public String getUpperCaseName() { + return upperCaseName; + } + + public static VnfType getVnfType(String inSensitiveCaseName){ + String localUpperCaseName = inSensitiveCaseName.toUpperCase(); + for(VnfType vnfType : VnfType.values()){ + if(vnfType.getUpperCaseName().equals(localUpperCaseName)){ + return vnfType; + } + } + throw new IllegalArgumentException( + "No enum with upperCaseName for this input value:" + inSensitiveCaseName ); + } +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/exception/DataAccessException.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/exception/DataAccessException.java new file mode 100644 index 000000000..1f3b9d830 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/exception/DataAccessException.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf.exception; + + +public class DataAccessException extends RuntimeException { + + private static final long serialVersionUID = -155423437162622414L; + + public DataAccessException(){ + } + + public DataAccessException(String message){ + super(message); + } + + public DataAccessException(Throwable cause){ + super(cause); + } + + public DataAccessException(String message , Throwable cause){ + super(message , cause); + } + +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/exception/NetconfDAOException.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/exception/NetconfDAOException.java new file mode 100644 index 000000000..c8c692c2a --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/exception/NetconfDAOException.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf.exception; + +public class NetconfDAOException extends RuntimeException { + + private static final long serialVersionUID = -155423437162622414L; + + public NetconfDAOException(){ + } + + public NetconfDAOException(String message){ + super(message); + } + + public NetconfDAOException(Throwable cause){ + super(cause); + } + + public NetconfDAOException(String message , Throwable cause){ + super(message , cause); + } + + +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/internal/NetconfAdapter.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/internal/NetconfAdapter.java new file mode 100644 index 000000000..7740728f4 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/internal/NetconfAdapter.java @@ -0,0 +1,129 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf.internal; + +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.concurrent.*; + +/** + * Provides basic methods for exchanging netconf messages. + */ +public class NetconfAdapter { + + private static final Logger LOG = LoggerFactory.getLogger(NetconfAdapter.class); + private static final long MAX_WAITING_TIME = 1800000; + private static ExecutorService executor = Executors.newFixedThreadPool(5); + + // device input stream + private InputStream in; + // device output stream + private OutputStream out; + private long maxWaitingTime = ConfigurationFactory.getConfiguration().getLongProperty("org.openecomp.appc.netconf.recv.timeout", MAX_WAITING_TIME); + + /** + * Constructor. + * + * @param in InputStream this instance will read netconf messages from + * @param out OutputStream this instance will write netconf messages to + * @throws IOException + */ + public NetconfAdapter(InputStream in, OutputStream out) throws IOException { + this.in = in; + this.out = out; + } + + /** + * Receives netconf message from InputStream and return it's text (without netconf frame characters). + * + * @return text of message received from netconf device + * @throws IOException + */ + public String receiveMessage() throws IOException { + + final NetconfMessage message = new NetconfMessage(); + final byte[] buf = new byte[1024]; + + //int readByte = 1; + // Read data with timeout + Callable<Boolean> readTask = new Callable<Boolean>() { + @Override + public Boolean call() throws Exception { + int c; + while ((c = in.read(buf)) > 0) { + if (c > 0) { + message.append(buf, 0, c); + if (message.isCompleted()) { + break; + } + } + } + + if (c < 0) { + return false; + } + return true; + } + }; + + Future<Boolean> future = executor.submit(readTask); + Boolean status; + try { + status = future.get(maxWaitingTime, TimeUnit.MILLISECONDS); + } catch (Exception e) { + throw new IOException(e); + } + + if (status == false) { + throw new IOException("Failed to read netconf message"); + } + + + String text = message.getText(); + if (text != null) { + text = text.trim(); + } + if (LOG.isDebugEnabled()) { + LOG.debug("Received message from netconf device:\n" + text); + } + return text; + } + + /** + * Sends netconf message with provided text (adds netconf frame characters and sends the message). + * + * @param text text of message to be sent to netconf device + * @throws IOException + */ + public void sendMessage(final String text) throws IOException { + if (LOG.isDebugEnabled()) { + LOG.debug("Sending message to netconf device:\n" + text); + } + out.write(new NetconfMessage(text).getFrame()); + out.flush(); + } +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/internal/NetconfAdapter2.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/internal/NetconfAdapter2.java new file mode 100644 index 000000000..e0f166483 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/internal/NetconfAdapter2.java @@ -0,0 +1,103 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf.internal; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; + +/** + * Provides basic methods for exchanging netconf messages. + */ +public class NetconfAdapter2 { + + private static final Logger LOG = LoggerFactory.getLogger(NetconfAdapter2.class); + + // device input pipe + private final PipedOutputStream pipedOutIn = new PipedOutputStream(); + private PipedInputStream in; + // device output pipe + private final PipedInputStream pipedInOut = new PipedInputStream(); + private PipedOutputStream out; + + /** + * Constructor. + * + * @throws IOException + */ + public NetconfAdapter2() throws IOException { + in = new PipedInputStream(pipedOutIn); + out = new PipedOutputStream(pipedInOut); + } + + /** + * @return InputStream this instance will read netconf messages from. + */ + public InputStream getIn() { + return in; + } + + /** + * @return OutputStream this instance will write netconf messages to. + */ + public OutputStream getOut() { + return out; + } + + /** + * Receives netconf message from InputStream and return it's text (without netconf frame characters). + * + * @return text of message received from netconf device + * @throws IOException + */ + public String receiveMessage() throws IOException { + NetconfMessage message = new NetconfMessage(); + byte[] buf = new byte[1024]; + int c; + while((c = pipedInOut.read(buf)) > 0) { + message.append(buf, 0, c); + if (message.isCompleted()) { + break; + } + } + String text = message.getText(); + if(LOG.isDebugEnabled()) { + LOG.debug("Received message from netconf device:\n" + text); + } + return text; + } + + /** + * Sends netconf message with provided text (adds netconf frame characters and sends the message). + * + * @param text text of message to be sent to netconf device + * @throws IOException + */ + public void sendMessage(final String text) throws IOException { + if(LOG.isDebugEnabled()) { + LOG.debug("Sending message to netconf device:\n" + text); + } + pipedOutIn.write(new NetconfMessage(text).getFrame()); +// pipedOutIn.flush(); + } +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/internal/NetconfConstMessages.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/internal/NetconfConstMessages.java new file mode 100644 index 000000000..d68900802 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/internal/NetconfConstMessages.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf.internal; + +public class NetconfConstMessages { + + public static final String CAPABILITIES_START = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + + "<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" + + " <capabilities>\n"; + + public static final String CAPABILITIES_BASE = + " <capability>urn:ietf:params:netconf:base:1.0</capability>\n"; + + public static final String CAPABILITIES_END = + " </capabilities>\n" + + "</hello>"; + + public static final String GET_RUNNING_CONFIG = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + + "<rpc message-id=\"1\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" + + " <get-config>\n" + + " <source>\n" + + " <running/>\n" + + " </source>\n" + + " </get-config>\n" + + "</rpc>"; + + public static final String CLOSE_SESSION = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + + "<rpc message-id=\"terminateConnection\" xmlns:netconf=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" + + " <close-session/>\n" + + "</rpc>"; +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/internal/NetconfDataAccessServiceImpl.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/internal/NetconfDataAccessServiceImpl.java new file mode 100644 index 000000000..53eb5b520 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/internal/NetconfDataAccessServiceImpl.java @@ -0,0 +1,154 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf.internal; + +import javax.sql.rowset.CachedRowSet; + +import org.openecomp.appc.adapter.netconf.ConnectionDetails; +import org.openecomp.appc.adapter.netconf.NetconfConnectionDetails; +import org.openecomp.appc.adapter.netconf.NetconfDataAccessService; +import org.openecomp.appc.adapter.netconf.exception.DataAccessException; +import org.openecomp.appc.adapter.netconf.util.Constants; +import org.openecomp.appc.exceptions.APPCException; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.resource.dblib.DbLibService; + +import java.sql.SQLException; +import java.util.ArrayList; + + +public class NetconfDataAccessServiceImpl implements NetconfDataAccessService { + + private static EELFLogger logger = EELFManager.getInstance().getLogger(NetconfDataAccessServiceImpl.class); + + public void setSchema(String schema) { + this.schema = schema; + } + + private String schema; + + public void setDbLibService(DbLibService service) {dbLibService = service;} + + private DbLibService dbLibService; + + @Override + public String retrieveConfigFileName(String xmlID) throws DataAccessException { + String fileContent = ""; + + String queryString = "select " + Constants.FILE_CONTENT_TABLE_FIELD_NAME + " " + + "from " + Constants.CONFIGFILES_TABLE_NAME + " " + + "where " + Constants.FILE_NAME_TABLE_FIELD_NAME + " = ?"; + + ArrayList<String> argList = new ArrayList<>(); + argList.add(xmlID); + + try { + + final CachedRowSet data = dbLibService.getData(queryString, argList, schema); + if (data.first()) { + fileContent = data.getString(Constants.FILE_CONTENT_TABLE_FIELD_NAME); + } + + } catch (Throwable e) { + logger.error("Error Accessing Database " + e); + throw new DataAccessException(e); + } + + return fileContent; + } + + @Override + public boolean retrieveConnectionDetails(String vnfType, ConnectionDetails connectionDetails) throws + DataAccessException { + boolean recordFound = false; + + String queryString = "select " + Constants.USER_NAME_TABLE_FIELD_NAME + "," + Constants.PASSWORD_TABLE_FIELD_NAME + "," + Constants.PORT_NUMBER_TABLE_FIELD_NAME + " " + + "from " + Constants.DEVICE_AUTHENTICATION_TABLE_NAME + " " + + "where " + Constants.VNF_TYPE_TABLE_FIELD_NAME + " = ?"; + + ArrayList<String> argList = new ArrayList<>(); + argList.add(vnfType); + + try { + + final CachedRowSet data = dbLibService.getData(queryString, argList, schema); + if (data.first()) { + connectionDetails.setUsername(data.getString(Constants.USER_NAME_TABLE_FIELD_NAME)); + connectionDetails.setPassword(data.getString(Constants.PASSWORD_TABLE_FIELD_NAME)); + connectionDetails.setPort(data.getInt(Constants.PORT_NUMBER_TABLE_FIELD_NAME)); + recordFound = true; + } + + } catch (SQLException e) { + logger.error("Error Accessing Database " + e); + throw new DataAccessException(e); + } + + return recordFound; + } + + @Override + public boolean retrieveNetconfConnectionDetails(String vnfType, NetconfConnectionDetails connectionDetails) throws + DataAccessException + { + ConnectionDetails connDetails = new ConnectionDetails(); + if(this.retrieveConnectionDetails(vnfType, connDetails)) + { + connectionDetails.setHost(connDetails.getHost()); + connectionDetails.setPort(connDetails.getPort()); + connectionDetails.setUsername(connDetails.getUsername()); + connectionDetails.setPassword(connDetails.getPassword()); + } + return true; + } + + @Override + public boolean logDeviceInteraction(String instanceId, String requestId, String creationDate, String logText) throws + DataAccessException { + + String queryString = "INSERT INTO "+ Constants.DEVICE_INTERFACE_LOG_TABLE_NAME+"("+ + Constants.SERVICE_INSTANCE_ID_FIELD_NAME+","+ + Constants.REQUEST_ID_FIELD_NAME+","+ + Constants.CREATION_DATE_FIELD_NAME+","+ + Constants.LOG_FIELD_NAME+") "; + queryString += "values(?,?,?,?)"; + + ArrayList<String> argList = new ArrayList<>(); + argList.add(instanceId); + argList.add(requestId); + argList.add(creationDate); + argList.add(logText); + + try { + + dbLibService.writeData(queryString, argList, schema); + + } catch (SQLException e) { + logger.error("Logging Device interaction failed - "+ queryString); + throw new DataAccessException(e); + } + + return true; + } + +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/internal/NetconfMessage.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/internal/NetconfMessage.java new file mode 100644 index 000000000..200145b0a --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/internal/NetconfMessage.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf.internal; + +import java.io.ByteArrayOutputStream; + +class NetconfMessage { + + private static final String EOM = "]]>]]>"; + + private String text; + private MessageBuffer buffer = new MessageBuffer(); + private int eomNotch; + + NetconfMessage() { + } + + NetconfMessage(String text) { + if(text == null) { + throw new NullPointerException("Netconf message payload is null"); + } + append(text.getBytes(), 0, text.length()); + if(this.text == null) { + this.text = text; + } + } + + void append(byte[] bytes, int start, int end) { + boolean eomFound = false; + for(int i = start; i < end; i++) { + if(bytes[i] == EOM.charAt(eomNotch)) { + // advance notch + eomNotch++; + } else { + // reset notch + eomNotch = 0; + } + if(eomNotch == EOM.length()) { + // end of message found + eomFound = true; + end = i + 1; + break; + } + } + buffer.write(bytes, start, end); + if(eomFound) { + text = new String(buffer.getBytes(), 0, buffer.size() - EOM.length()); + buffer.reset(); + } + } + + String getText() { + return text; + } + + boolean isCompleted() { + return (text != null); + } + + byte[] getFrame() { + StringBuilder sb = new StringBuilder(); + if(text != null) { + sb.append(text).append("\n"); + } + sb.append(EOM); + return sb.toString().getBytes(); + } + + private class MessageBuffer extends ByteArrayOutputStream { + + byte[] getBytes() { + return buf; + } + } +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/jsch/JSchLogger.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/jsch/JSchLogger.java new file mode 100644 index 000000000..e6b47db38 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/jsch/JSchLogger.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf.jsch; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * JSch logger implementation delegating to logback. + */ +public class JSchLogger implements com.jcraft.jsch.Logger { + + private static final Logger LOG = LoggerFactory.getLogger(JSchLogger.class); + + @Override + public boolean isEnabled(int level) { + return true; + } + + @Override + public void log(int level, String message) { + switch(level) { + case com.jcraft.jsch.Logger.DEBUG: + LOG.debug(message); + break; + + case com.jcraft.jsch.Logger.INFO: + LOG.info(message); + break; + + case com.jcraft.jsch.Logger.WARN: + LOG.warn(message); + break; + + case com.jcraft.jsch.Logger.ERROR: + case com.jcraft.jsch.Logger.FATAL: + LOG.error(message); + break; + } + } +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/jsch/NetconfClientJsch.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/jsch/NetconfClientJsch.java new file mode 100644 index 000000000..c743b2dd8 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/jsch/NetconfClientJsch.java @@ -0,0 +1,171 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf.jsch; + +import com.jcraft.jsch.Channel; +import com.jcraft.jsch.ChannelSubsystem; +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.Session; + +import java.io.IOException; +import java.util.List; +import java.util.Properties; + +import org.openecomp.appc.adapter.netconf.NetconfClient; +import org.openecomp.appc.adapter.netconf.NetconfConnectionDetails; +import org.openecomp.appc.adapter.netconf.internal.NetconfAdapter; +import org.openecomp.appc.adapter.netconf.internal.NetconfConstMessages; +import org.openecomp.appc.encryption.EncryptionTool; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.i18n.Msg; +import com.att.eelf.i18n.EELFResourceManager; + +/** + * Implementation of NetconfClient interface based on JCraft jsch library. + */ +public class NetconfClientJsch implements NetconfClient { + + private static final int SESSION_CONNECT_TIMEOUT = 30000; + private static final int CHANNEL_CONNECT_TIMEOUT = 10000; + + private Session session; + private Channel channel; + private NetconfAdapter netconfAdapter; +// private NetconfAdapter2 netconfAdapter; + + + @Override + public void connect(NetconfConnectionDetails connectionDetails) throws APPCException { + String host = connectionDetails.getHost(); + int port = connectionDetails.getPort(); + String username = connectionDetails.getUsername(); + String password = connectionDetails.getPassword(); + try { + JSch.setLogger(new JSchLogger()); + JSch jsch = new JSch(); + session = jsch.getSession(EncryptionTool.getInstance().decrypt(username), host, port); + session.setPassword(EncryptionTool.getInstance().decrypt(password)); + session.setConfig("StrictHostKeyChecking", "no"); + + Properties additionalProps = connectionDetails.getAdditionalProperties(); + if((additionalProps != null) && !additionalProps.isEmpty()) { + session.setConfig(additionalProps); + } + + session.connect(SESSION_CONNECT_TIMEOUT); + session.setTimeout(10000); + try { +// session.setServerAliveCountMax(0); // If this is not set to '0', then socket timeout on all reads will not work!!!! + channel = session.openChannel("subsystem"); + ((ChannelSubsystem)channel).setSubsystem("netconf"); + netconfAdapter = new NetconfAdapter(channel.getInputStream(), channel.getOutputStream()); +// netconfAdapter = new NetconfAdapter2(); +// channel.setInputStream(netconfAdapter.getIn()); +// channel.setOutputStream(netconfAdapter.getOut()); + channel.connect(CHANNEL_CONNECT_TIMEOUT); + hello(connectionDetails.getCapabilities()); + } catch(Exception e) { + disconnect(); + throw e; + } + } catch(Exception e) { + String message = EELFResourceManager.format(Msg.CANNOT_ESTABLISH_CONNECTION, host, String.valueOf(port), username); + throw new APPCException(message, e); + } + } + + @Override + public String exchangeMessage(String message) throws APPCException { + try { + netconfAdapter.sendMessage(message); + return netconfAdapter.receiveMessage(); + } catch(IOException e) { + throw new APPCException(e); + } + } + + @Override + public void configure(String configuration) throws APPCException { + try { + isOk(exchangeMessage(configuration)); + } catch(IOException e) { + throw new APPCException(e); + } + } + + @Override + public String getConfiguration() throws APPCException { + return exchangeMessage(NetconfConstMessages.GET_RUNNING_CONFIG); + } + + @Override + public void disconnect() { + try { + if((channel != null) && !channel.isClosed()) { + netconfAdapter.sendMessage(NetconfConstMessages.CLOSE_SESSION); + isOk(netconfAdapter.receiveMessage()); + } + } catch(IOException e) { + throw new RuntimeException("Error closing netconf device", e); + } finally { + netconfAdapter = null; + if(channel != null) { + channel.disconnect(); + channel = null; + } + if(session != null) { + session.disconnect(); + session = null; + } + } + } + + private void hello(List<String> capabilities) throws IOException { + String helloIn = netconfAdapter.receiveMessage(); + if(helloIn == null) { + throw new IOException("Expected hello message, but nothing received error from netconf device"); + } + if(helloIn.contains("<rpc-error>")) { + throw new IOException("Expected hello message, but received error from netconf device:\n" + helloIn); + } + StringBuilder sb = new StringBuilder(); + sb.append(NetconfConstMessages.CAPABILITIES_START); + sb.append(NetconfConstMessages.CAPABILITIES_BASE); + if(capabilities != null) { + for(String capability: capabilities) { + sb.append(" ").append(capability).append("\n"); + } + } + sb.append(NetconfConstMessages.CAPABILITIES_END); + String helloOut = sb.toString(); + netconfAdapter.sendMessage(helloOut); + } + + private void isOk(String response) throws IOException { + if(response == null) { + throw new IOException("No response from netconf device"); + } + if(!response.contains("<ok/>")) { + throw new IOException("Error response from netconf device: \n" + response); + } + } +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/odlconnector/NetconfClientRestconfImpl.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/odlconnector/NetconfClientRestconfImpl.java new file mode 100644 index 000000000..2c10cdedd --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/odlconnector/NetconfClientRestconfImpl.java @@ -0,0 +1,233 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf.odlconnector; + +import org.apache.http.HttpStatus; +import org.openecomp.appc.adapter.netconf.NetconfClient; +import org.openecomp.appc.adapter.netconf.NetconfClientRestconf; +import org.openecomp.appc.adapter.netconf.NetconfConnectionDetails; +import org.openecomp.appc.adapter.netconf.util.Constants; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.util.httpClient; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import java.util.Properties; + +public class NetconfClientRestconfImpl implements NetconfClient, NetconfClientRestconf { + + private EELFLogger logger = EELFManager.getInstance().getLogger(NetconfClientRestconfImpl.class); + + private NetconfConnectionDetails connectionDetails; + + //constructor + public NetconfClientRestconfImpl(){ + } + + //restconf client impl + + @SuppressWarnings("deprecation") + @Override + public void configure(String configuration, String deviceMountPointName, String moduleName, String nodeName) throws APPCException { + + logger.info("Configuring device "+deviceMountPointName+" with configuration "+configuration); + + int httpCode = httpClient.putMethod(Constants.PROTOCOL,Constants.CONTROLLER_IP,Constants.CONTROLLER_PORT,getModuleConfigurePath(deviceMountPointName, moduleName, nodeName),configuration,"application/json"); + + if (httpCode != HttpStatus.SC_OK) { + logger.error("Configuration request failed. throwing Exception !"); + throw new APPCException("Error configuring node :"+nodeName + ", of Module :" + moduleName + ", in device :" + deviceMountPointName); + } + } + + @Override + public void connect(String deviceMountPointName, String payload) throws APPCException{ + + logger.info("Connecting device "+deviceMountPointName); + + int httpCode = httpClient.postMethod(Constants.PROTOCOL,Constants.CONTROLLER_IP,Constants.CONTROLLER_PORT,getConnectPath(),payload,"application/json"); + + if(httpCode != HttpStatus.SC_NO_CONTENT){ + logger.error("Connect request failed with code "+httpCode+". throwing Exception !"); + throw new APPCException("Error connecting device :" + deviceMountPointName); + } + } + + @Override + public boolean checkConnection(String deviceMountPointName) throws APPCException { + logger.info("Checking device "+deviceMountPointName+" connectivity"); + + String result = httpClient.getMethod(Constants.PROTOCOL,Constants.CONTROLLER_IP,Constants.CONTROLLER_PORT,getCheckConnectivityPath(deviceMountPointName),"application/json"); + + return result != null; + } + + @Override + public void disconnect(String deviceMountPointName) throws APPCException { + logger.info("Disconnecting "+deviceMountPointName); + + int httpCode = httpClient.deleteMethod(Constants.PROTOCOL,Constants.CONTROLLER_IP,Constants.CONTROLLER_PORT,getDisconnectPath(deviceMountPointName),"application/json"); + + if(httpCode != HttpStatus.SC_OK){ + logger.error("Disconnection of device "+deviceMountPointName+" failed!"); + throw new APPCException("Disconnection of device "+deviceMountPointName+" failed!"); + } + } + + @Override + public String getConfiguration(String deviceMountPointName, String moduleName, String nodeName) throws APPCException{ + logger.info("Getting configuration of device "+deviceMountPointName); + + String result = httpClient.getMethod(Constants.PROTOCOL,Constants.CONTROLLER_IP,Constants.CONTROLLER_PORT,getModuleConfigurePath(deviceMountPointName, moduleName, nodeName),"application/json"); + + if (result == null) { + logger.error("Configuration request failed. throwing Exception !"); + throw new APPCException("Error getting configuration of node :"+nodeName + ", of Module :" + moduleName + ", in device :" + deviceMountPointName); + } + + return result; + } + + //netconf client impl + + @Override + public void connect(NetconfConnectionDetails connectionDetails) throws APPCException { + if(connectionDetails == null){ + throw new APPCException("Invalid connection details - null value"); + } + this.connectionDetails = connectionDetails; + this.connect(connectionDetails.getHost(),getPayload()); + } + + @Override + public String exchangeMessage(String message) throws APPCException { + // TODO implement + return null; + } + + @Override + public void configure(String configuration) throws APPCException { + if(connectionDetails == null){ + throw new APPCException("Invalid connection details - null value"); + } + + Properties props = connectionDetails.getAdditionalProperties(); + if(props == null || !props.containsKey("module.name") || !props.containsKey("node.name")){ + throw new APPCException("Invalid properties!"); + } + + String moduleName = props.getProperty("module.name"); + String nodeName = props.getProperty("node.name"); + String deviceMountPointName = connectionDetails.getHost(); + + int httpCode = httpClient.putMethod(Constants.PROTOCOL,Constants.CONTROLLER_IP,Constants.CONTROLLER_PORT,getModuleConfigurePath(deviceMountPointName, moduleName, nodeName),configuration,"application/xml"); + + if (httpCode != HttpStatus.SC_OK) { + logger.error("Configuration request failed. throwing Exception !"); + throw new APPCException("Error configuring node :"+nodeName + ", of Module :" + moduleName + ", in device :" + deviceMountPointName); + } + } + + @Override + public String getConfiguration() throws APPCException { + if(connectionDetails == null){ + throw new APPCException("Invalid connection details - null value"); + } + + Properties props = connectionDetails.getAdditionalProperties(); + if(props == null || !props.containsKey("module.name") || !props.containsKey("node.name")){ + throw new APPCException("Invalid properties!"); + } + + return this.getConfiguration(connectionDetails.getHost(),props.getProperty("module.name"),props.getProperty("node.name")); + } + + @Override + public void disconnect() throws APPCException { + if(connectionDetails == null){ + throw new APPCException("Invalid connection details - null value"); + } + this.disconnect(connectionDetails.getHost()); + } + + //private methods + private String getModuleConfigurePath(String deviceMountPointName, String moduleName, String nodeName){ + + + String deviceSpecificPath = deviceMountPointName + "/yang-ext:mount/" + moduleName + ":" + nodeName; + + return Constants.CONFIGURE_PATH + deviceSpecificPath; + } + + private String getConnectPath(){ + + return Constants.CONNECT_PATH; + } + + private String getCheckConnectivityPath(String deviceMountPointName) { + return Constants.CHECK_CONNECTION_PATH + deviceMountPointName; + } + + private String getDisconnectPath(String deviceMountPointName) { + return Constants.DISCONNECT_PATH + deviceMountPointName; + } + + private String getPayload() { + return "{\n" + + " \"config:module\":\n" + + " {\n" + + " \"type\":\"odl-sal-netconf-connector-cfg:sal-netconf-connector\",\n" + + " \"netconf-northbound-ssh\\odl-sal-netconf-connector-cfg:name\":"+connectionDetails.getHost()+",\n" + + " \"odl-sal-netconf-connector-cfg:address\":"+connectionDetails.getHost()+",\n" + + " \"odl-sal-netconf-connector-cfg:port\":"+connectionDetails.getPort()+",\n" + + " \"odl-sal-netconf-connector-cfg:username\":"+connectionDetails.getUsername()+",\n" + + " \"odl-sal-netconf-connector-cfg:password\":"+connectionDetails.getPassword()+",\n" + + " \"tcp-only\":\"false\",\n" + + " \"odl-sal-netconf-connector-cfg:event-executor\":\n" + + " {\n" + + " \"type\":\"netty:netty-event-executor\",\n" + + " \"name\":\"global-event-executor\"\n" + + " },\n" + + " \"odl-sal-netconf-connector-cfg:binding-registry\":\n" + + " {\n" + + " \"type\":\"opendaylight-md-sal-binding:binding-broker-osgi-registry\",\n" + + " \"name\":\"binding-osgi-broker\"\n" + + " },\n" + + " \"odl-sal-netconf-connector-cfg:dom-registry\":\n" + + " {\n" + + " \"type\":\"opendaylight-md-sal-dom:dom-broker-osgi-registry\",\n" + + " \"name\":\"dom-broker\"\n" + + " },\n" + + " \"odl-sal-netconf-connector-cfg:client-dispatcher\":\n" + + " {\n" + + " \"type\":\"odl-netconf-cfg:netconf-client-dispatcher\",\n" + + " \"name\":\"global-netconf-dispatcher\"\n" + + " },\n" + + " \"odl-sal-netconf-connector-cfg:processing-executor\":\n" + + " {\n" + + " \"type\":\"threadpool:threadpool\",\n" + + " \"name\":\"global-netconf-processing-executor\"\n" + + " }\n" + + " }\n" + + "}"; + } +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/util/Constants.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/util/Constants.java new file mode 100644 index 000000000..92141e1b7 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/util/Constants.java @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf.util; + +public class Constants { + + public static final String CONFIGURE_PATH = "/restconf/config/opendaylight-inventory:nodes/node/"; + public static final String CONNECT_PATH = "/restconf/config/opendaylight-inventory:nodes/node/controller-config/yang-ext:mount/config:modules"; + public static final String CHECK_CONNECTION_PATH = "/restconf/operational/opendaylight-inventory:nodes/node/"; + public static final String DISCONNECT_PATH = "/restconf/config/opendaylight-inventory:nodes/node/controller-config/yang-ext:mount/config:modules/module/odl-sal-netconf-connector-cfg:sal-netconf-connector/"; + + public static final String CONTROLLER_IP = "127.0.0.1"; + public static final int CONTROLLER_PORT = 8181; + public static final String PROTOCOL = "http"; + + // tables and fields + public static final String NETCONF_SCHEMA = "sdnctl"; + public static final String DEVICE_AUTHENTICATION_TABLE_NAME = "DEVICE_AUTHENTICATION"; + public static final String CONFIGFILES_TABLE_NAME = "CONFIGFILES"; + public static final String DEVICE_INTERFACE_LOG_TABLE_NAME = "DEVICE_INTERFACE_LOG"; + public static final String FILE_CONTENT_TABLE_FIELD_NAME = "FILE_CONTENT"; + public static final String FILE_NAME_TABLE_FIELD_NAME = "FILE_NAME"; + public static final String USER_NAME_TABLE_FIELD_NAME = "USER_NAME"; + public static final String PASSWORD_TABLE_FIELD_NAME = "PASSWORD"; + public static final String VM_HOST_TABLE_FIELD_NAME = "VM_HOST"; + public static final String VM_NAME_TABLE_FIELD_NAME = "VM_NAME"; + public static final String PORT_NUMBER_TABLE_FIELD_NAME = "PORT_NUMBER"; + public static final String VNF_TYPE_TABLE_FIELD_NAME = "VNF_TYPE"; + public static final String SERVICE_INSTANCE_ID_FIELD_NAME = "SERVICE_INSTANCE_ID"; + public static final String REQUEST_ID_FIELD_NAME = "REQUEST_ID"; + public static final String CREATION_DATE_FIELD_NAME = "CREATION_DATE"; + public static final String LOG_FIELD_NAME = "LOG"; + + // input fields names + public static final String VNF_TYPE_FIELD_NAME = "org.openecomp.appc.vftype"; + public static final String TARGET_VNF_TYPE = "target-vnf-type"; + public static final String FILE_CONTENT_FIELD_NAME = "file-content"; + public static final String CONNECTION_DETAILS_FIELD_NAME = "connection-details"; + public static final String CONFIGURATION_FILE_FIELD_NAME = "configuration-file-name"; + public static final String VNF_HOST_IP_ADDRESS_FIELD_NAME = "vnf-host-ip-address"; + public static final String DG_ERROR_FIELD_NAME = "org.openecomp.appc.dg.error"; + public static final String RESOURCEKEY = "resourceKey"; + public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; + +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..fc741daf5 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,41 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + +org.openecomp.appc.netconf.db.jdbc.driver=netconfctl +org.openecomp.appc.netconf.db.url.netconfctl=jdbc:mysql://127.0.0.1:3306/test +org.openecomp.appc.netconf.db.user.netconfctl=test +org.openecomp.appc.netconf.db.pass.netconfctl=123456 +org.openecomp.appc.netconf.recv.timeout=1800000 + +### ### +### Properties commented out below provided in appc.properties ### +### ### +#event.pool.members=<DMAAP_IP>:3904 +event.topic.write=APPC-TEST1 +event.client.key=VIlbtVl6YLhNUrtU +event.client.secret=64AG2hF4pYeG2pq7CT6XwUOT +#restconf.user=<RESTCONF_USER> +#restconf.pass=<RESTCONF_PASSWORD> + +org.openecomp.appc.adapter.netconf.VNFOperationalStateValidatorImpl-CONFIG_FILE=VnfGetOperationalStates diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/OperationalStateValidatorTest.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/OperationalStateValidatorTest.java new file mode 100644 index 000000000..d6d5ae278 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/OperationalStateValidatorTest.java @@ -0,0 +1,197 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +import org.openecomp.appc.exceptions.APPCException; +import org.junit.Test; +import org.openecomp.appc.adapter.netconf.OperationalStateValidator; +import org.openecomp.appc.adapter.netconf.OperationalStateValidatorFactory; +import org.openecomp.appc.adapter.netconf.VnfType; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + + +public class OperationalStateValidatorTest { + + @Test + public void testVNFValidResponse() { + String validResponse = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + + "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"101\">\n" + + " <data>\n" + + " <ManagedElement xmlns=\"urn:org:openecomp:appc:Test\">\n" + + " <managedElementId>1</managedElementId>\n" + + " <VnfFunction xmlns=\"urn:org:openecomp:appc:Test\">\n" + + " <id>1</id>\n" + + " <ProcessorManagement>\n" + + " <id>1</id>\n" + + " <MatedPair>\n" + + " <id>1</id>\n" + + " <operationalState>ENABLED</operationalState>\n" + + " <PayloadProcessor>\n" + + " <id>processor_0_5</id>\n" + + " <operationalState>ENABLED</operationalState>\n" + + " </PayloadProcessor>\n" + + " <PayloadProcessor>\n" + + " <id>processor_0_7</id>\n" + + " <operationalState>ENABLED</operationalState>\n" + + " </PayloadProcessor>\n" + + " </MatedPair>\n" + + " <SystemController>\n" + + " <id>SC-1</id>\n" + + " <operationalState>ENABLED</operationalState>\n" + + " </SystemController>\n" + + " <SystemController>\n" + + " <id>SC-2</id>\n" + + " <operationalState>ENABLED</operationalState>\n" + + " </SystemController>\n" + + " </ProcessorManagement>\n" + + " </VnfFunction>\n" + + " </ManagedElement>\n" + + " </data>\n" + + "</rpc-reply>"; + OperationalStateValidator operationalStateValidator = OperationalStateValidatorFactory.getOperationalStateValidator(VnfType.VNF); + assertValidResponse(validResponse, operationalStateValidator); + } + + void assertInvalidResponse(String response, OperationalStateValidator operationalStateValidator) { + try { + operationalStateValidator.validateResponse(response); + fail("invalid resposne passed without exception!!!"); + } catch (APPCException e) { + assertNotNull(e.getMessage()); + } + } + + @Test + public void testVNFInvalidResponses() { + + OperationalStateValidator operationalStateValidator = OperationalStateValidatorFactory.getOperationalStateValidator(VnfType.VNF); + assertInvalidResponse(null, operationalStateValidator); + + assertInvalidResponse("", operationalStateValidator); + + String response = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; + assertInvalidResponse(response, operationalStateValidator); + + response = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + + "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"101\">\n" + + "</rpc-reply>"; + assertInvalidResponse(response, operationalStateValidator); + + response = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + + "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"101\">\n" + + " <data>\n" + + " <ManagedElement xmlns=\"urn:org:openecomp:appc:Test\">\n" + + " <managedElementId>1</managedElementId>\n" + + " <VnfFunction xmlns=\"urn:org:openecomp:appc:Test\">\n" + + " <id>1</id>\n" + + " <ProcessorManagement>\n" + + " <id>1</id>\n" + + " <MatedPair>\n" + + " <id>1</id>\n" + + " <operationalState>ENABLED</operationalState>\n" + + " <PayloadProcessor>\n" + + " <id>processor_0_5</id>\n" + + " <operationalState>ENABLED</operationalState>\n" + + " </PayloadProcessor>\n" + + " <PayloadProcessor>\n" + + " <id>processor_0_7</id>\n" + + " <operationalState>ENABLED</operationalState>\n" + + " </PayloadProcessor>\n" + + " </MatedPair>\n" + + " <SystemController>\n" + + " <id>SC-1</id>\n" + + " <operationalState>ENABLED</operationalState>\n" + + " </SystemController>\n" + + " <SystemController>\n" + + " <id>SC-2</id>\n" + + " <operationalState></operationalState>\n" + + " </SystemController>\n" + + " </ProcessorManagement>\n" + + " </VnfFunction>\n" + + " </ManagedElement>\n" + + " </data>\n" + + "</rpc-reply>"; + assertInvalidResponse(response, operationalStateValidator); + } + + void assertValidResponse(String response, OperationalStateValidator operationalStateValidator) { + try { + operationalStateValidator.validateResponse(response); + } catch (APPCException e) { + fail("Got unexpected exception. Validation failed. " + e.getMessage()); + } + } + + @Test + public void testMockValidResponse() { + String response = "valid"; + OperationalStateValidator operationalStateValidator = OperationalStateValidatorFactory.getOperationalStateValidator("mock"); + assertValidResponse(response, operationalStateValidator); + + response = ""; + assertValidResponse(response, operationalStateValidator); + + response = null; + assertValidResponse(response, operationalStateValidator); + } + + @Test + public void testMockInValidResponse() { + String response = "anything InValid anything.. "; + OperationalStateValidator operationalStateValidator = OperationalStateValidatorFactory.getOperationalStateValidator(VnfType.MOCK); + assertInvalidResponse(response, operationalStateValidator); + } + + @Test + public void testGetOperationalStateValidatorForInValidVnfType() { + try{ + OperationalStateValidatorFactory.getOperationalStateValidator("wrongVnfType"); + fail("invalid vnfType without exception!!!"); + } catch (Exception e) { + assertNotNull(e.getMessage()); + } + } + + @Test + public void testGetOperationalStateValidatorForValidVnfType() { + String vnfType = VnfType.VNF.name().toLowerCase(); + assertGettingValidatorForValidVnf(vnfType); + + vnfType = VnfType.VNF.name().toUpperCase(); + assertGettingValidatorForValidVnf(vnfType); + + vnfType = VnfType.MOCK.name().toLowerCase(); + assertGettingValidatorForValidVnf(vnfType); + + vnfType = VnfType.MOCK.name().toUpperCase(); + assertGettingValidatorForValidVnf(vnfType); + } + + void assertGettingValidatorForValidVnf(String vnfType) { + try{ + OperationalStateValidator operationalStateValidator = OperationalStateValidatorFactory.getOperationalStateValidator(vnfType); + assertNotNull(operationalStateValidator); + } catch (Exception e) { + fail("valid vnfType throw exception!!!"); + } + } +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/openecomp/appc/adapter/netconf/internal/TestNetconfAdapter.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/openecomp/appc/adapter/netconf/internal/TestNetconfAdapter.java new file mode 100644 index 000000000..5e63d5010 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/openecomp/appc/adapter/netconf/internal/TestNetconfAdapter.java @@ -0,0 +1,88 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf.internal; + +import org.junit.Assert; +import org.junit.Test; +import org.openecomp.appc.adapter.netconf.internal.NetconfAdapter; + +import java.io.IOException; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; + +public class TestNetconfAdapter { + + private static final String EOM = "]]>]]>"; + + @Test + public void testReceiveMessage() throws IOException { + PipedOutputStream pos = new PipedOutputStream(); + PipedInputStream is = new PipedInputStream(pos); + + PipedInputStream pis = new PipedInputStream(); + PipedOutputStream os = new PipedOutputStream(pis); + + NetconfAdapter netconfAdapter = new NetconfAdapter(is, os); + + String request = "Hello, netconf!"; + pos.write(request.getBytes()); + pos.write(EOM.getBytes()); + String response = netconfAdapter.receiveMessage(); + Assert.assertNotNull(response); + Assert.assertEquals(request, response.trim()); + } + + @Test + public void testSendMessage() throws IOException { + PipedOutputStream pos = new PipedOutputStream(); + PipedInputStream is = new PipedInputStream(pos); + + PipedInputStream pis = new PipedInputStream(); + PipedOutputStream os = new PipedOutputStream(pis); + + NetconfAdapter netconfAdapter = new NetconfAdapter(is, os); + + String request = "Hello, netconf!"; + netconfAdapter.sendMessage(request); + byte[] bytes = new byte[request.length()+EOM.length()+2]; + int count = pis.read(bytes); + String response = new String(bytes, 0, count); + Assert.assertNotNull(response); + Assert.assertTrue(response.endsWith(EOM)); + response = response.substring(0, response.length() - EOM.length()).trim(); + Assert.assertEquals(request, response); + } + + @Test + public void testSendReceive() throws IOException { + PipedOutputStream os = new PipedOutputStream(); + PipedInputStream is = new PipedInputStream(os); + + NetconfAdapter netconfAdapter = new NetconfAdapter(is, os); + + String request = "Hello, netconf!"; + netconfAdapter.sendMessage(request); + String response = netconfAdapter.receiveMessage(); + Assert.assertNotNull(response); + Assert.assertEquals(request, response.trim()); + } +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/openecomp/appc/adapter/netconf/jsch/TestGetRunningConfig.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/openecomp/appc/adapter/netconf/jsch/TestGetRunningConfig.java new file mode 100644 index 000000000..a26c6e9e9 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/openecomp/appc/adapter/netconf/jsch/TestGetRunningConfig.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf.jsch; + +import java.util.Collections; +import java.util.List; + +import org.openecomp.appc.adapter.netconf.NetconfConnectionDetails; +import org.openecomp.appc.adapter.netconf.jsch.NetconfClientJsch; +import org.openecomp.appc.exceptions.APPCException; + +public class TestGetRunningConfig { + + private static final String HOST = "192.168.1.2"; + private static final String USER = "test"; + private static final String PSWD = "test123"; + private static final int PORT = 830; + private static final List<String> CAPABILITIES = Collections.singletonList("<capability>urn:org:openecomp:appc:capability:1.1.0</capability>"); + + public static void main(String[] args) throws APPCException { + try { + NetconfConnectionDetails connectionDetails = new NetconfConnectionDetails(); + connectionDetails.setHost(HOST); + connectionDetails.setPort(PORT); + connectionDetails.setUsername(USER); + connectionDetails.setPassword(PSWD); + connectionDetails.setCapabilities(CAPABILITIES); + NetconfClientJsch netconfClientJsch = new NetconfClientJsch(); + netconfClientJsch.connect(connectionDetails); + try { + System.out.println("=> Running get configuration..."); + String configuration = netconfClientJsch.getConfiguration(); + System.out.println("=> Configuration:\n" + configuration); + } finally { + netconfClientJsch.disconnect(); + } + } catch(Exception e) { + e.printStackTrace(); + } + } +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/openecomp/appc/adapter/netconf/jsch/TestModifyConfig.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/openecomp/appc/adapter/netconf/jsch/TestModifyConfig.java new file mode 100644 index 000000000..e4baecc89 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/openecomp/appc/adapter/netconf/jsch/TestModifyConfig.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf.jsch; + +import java.util.Collections; +import java.util.List; + +import org.openecomp.appc.adapter.netconf.NetconfConnectionDetails; +import org.openecomp.appc.adapter.netconf.jsch.NetconfClientJsch; +import org.openecomp.appc.exceptions.APPCException; + +public class TestModifyConfig { + + private static final String HOST = "192.168.1.2"; + private static final String USER = "test"; + private static final String PSWD = "test123"; + private static final int PORT = 830; + private static final List<String> CAPABILITIES = Collections.singletonList("<capability>urn:org:openecomp:appc:capability:1.1.0</capability>"); + private static final String CONFIG = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + + "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"1\">\n" + + " <edit-config>\n" + + " <target>\n" + + " <running />\n" + + " </target>\n" + + " <default-operation>merge</default-operation>\n" + + " <config xmlns:xc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" + + " <ManagedElement xmlns=\"urn:org.openecomp.appc:Test\">\n" + + " <managedElementId>1</managedElementId>\n" + + " <VnfFunction xmlns=\"urn:org:openecomp:appc:VnfFunction\">\n" + + " <id>1</id>\n" + + " <Interfaces>\n" + + " <id>1</id>\n" + + " <DiaRealmRf>\n" + + " <realm>example.com</realm>\n" + + " <reconnectTimer>60</reconnectTimer>\n" + + " </DiaRealmRf>\n" + + " </Interfaces>\n" + + " </VnfFunction>\n" + + " </ManagedElement>\n" + + " </config>\n" + + " </edit-config>\n" + + "</rpc>"; + + public static void main(String[] args) throws APPCException { + try { + NetconfConnectionDetails connectionDetails = new NetconfConnectionDetails(); + connectionDetails.setHost(HOST); + connectionDetails.setPort(PORT); + connectionDetails.setUsername(USER); + connectionDetails.setPassword(PSWD); + connectionDetails.setCapabilities(CAPABILITIES); + NetconfClientJsch netconfClientJsch = new NetconfClientJsch(); + netconfClientJsch.connect(connectionDetails); + try { + System.out.println("=> Running get configuration..."); + String configuration = netconfClientJsch.getConfiguration(); + System.out.println("=> Configuration:\n" + configuration); + + System.out.println("=> Reconfiguring device..."); + String outMessage = netconfClientJsch.exchangeMessage(CONFIG); + System.out.println("=> Reconfiguration response:\n" + outMessage); + + System.out.println("=> Running get configuration..."); + configuration = netconfClientJsch.getConfiguration(); + System.out.println("=> Configuration:\n" + configuration); + } finally { + netconfClientJsch.disconnect(); + } + } catch(Exception e) { + e.printStackTrace(); + } + } +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/openecomp/appc/adapter/netconf/jsch/TestModifyConfigMock.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/openecomp/appc/adapter/netconf/jsch/TestModifyConfigMock.java new file mode 100644 index 000000000..1fe2e1093 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/openecomp/appc/adapter/netconf/jsch/TestModifyConfigMock.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf.jsch; + +import java.util.Collections; +import java.util.List; + +import org.openecomp.appc.adapter.netconf.NetconfConnectionDetails; +import org.openecomp.appc.adapter.netconf.jsch.NetconfClientJsch; +import org.openecomp.appc.exceptions.APPCException; + +public class TestModifyConfigMock { + + private static final String HOST = "192.168.1.2"; + private static final String USER = "test"; + private static final String PSWD = "test123"; + private static final int PORT = 830; + private static final List<String> CAPABILITIES = Collections.singletonList("<capability>urn:org:openecomp:appc:capability:1.1.0</capability>"); + private static final String CONFIG = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + + "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"1\">\n" + + " <edit-config>\n" + + " <target>\n" + + " <running />\n" + + " </target>\n" + + " <default-operation>merge</default-operation>\n" + + " <config xmlns:xc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" + + " <ManagedElement xmlns=\"urn:org.openecomp.appc:Test\">\n" + + " <managedElementId>1</managedElementId>\n" + + " <VnfFunction xmlns=\"urn:org:openecomp:appc:VnfFunction\">\n" + + " <id>1</id>\n" + + " <Interfaces>\n" + + " <id>1</id>\n" + + " <DiaRealmRf>\n" + + " <realm>example.com</realm>\n" + + " <reconnectTimer>60</reconnectTimer>\n" + + " </DiaRealmRf>\n" + + " </Interfaces>\n" + + " </VnfFunction>\n" + + " </ManagedElement>\n" + + " </config>\n" + + " </edit-config>\n" + + "</rpc>"; + + public static void main(String[] args) throws APPCException { + try { + NetconfConnectionDetails connectionDetails = new NetconfConnectionDetails(); + connectionDetails.setHost(HOST); + connectionDetails.setPort(PORT); + connectionDetails.setUsername(USER); + connectionDetails.setPassword(PSWD); + connectionDetails.setCapabilities(CAPABILITIES); + NetconfClientJsch netconfClientJsch = new NetconfClientJsch(); + netconfClientJsch.connect(connectionDetails); + try { + System.out.println("=> Running get configuration..."); + String configuration = netconfClientJsch.getConfiguration(); + System.out.println("=> Configuration:\n" + configuration); + + System.out.println("=> Reconfiguring device..."); + String outMessage = netconfClientJsch.exchangeMessage(CONFIG); + System.out.println("=> Reconfiguration response:\n" + outMessage); + + System.out.println("=> Running get configuration..."); + configuration = netconfClientJsch.getConfiguration(); + System.out.println("=> Configuration:\n" + configuration); + } finally { + netconfClientJsch.disconnect(); + } + } catch(Exception e) { + e.printStackTrace(); + } + } +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/openecomp/appc/adapter/netconf/jsch/TestModifyConfigRouterMock.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/openecomp/appc/adapter/netconf/jsch/TestModifyConfigRouterMock.java new file mode 100644 index 000000000..256e8e8f5 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/openecomp/appc/adapter/netconf/jsch/TestModifyConfigRouterMock.java @@ -0,0 +1,91 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf.jsch; + +import java.util.Collections; +import java.util.List; + +import org.openecomp.appc.adapter.netconf.NetconfConnectionDetails; +import org.openecomp.appc.adapter.netconf.jsch.NetconfClientJsch; +import org.openecomp.appc.exceptions.APPCException; + +public class TestModifyConfigRouterMock { + + private static final String HOST = "10.147.27.50"; // yuma netconf simulator + private static final int PORT = 830; + private static final String USER = "admin"; + private static final String PSWD = "admin"; + private static final List<String> CAPABILITIES = Collections.emptyList(); + private static final String CONFIG = + "<rpc message-id=\"101\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" + + " <edit-config>\n" + + " <target>\n" + + " <candidate/>\n" + + " </target>\n" + + " <config xmlns:xc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" + + " <router xmlns=\"urn:sdnhub:odl:tutorial:router\">\n" + + " <ospf>\n" + + " <process-id>1</process-id>\n" + + " <networks>\n" + + " <subnet-ip>100.100.100.0/24</subnet-ip>\n" + + " <area-id>10</area-id>\n" + + " </networks>\n" + + " </ospf>\n" + + " <bgp>\n" + + " <as-number>1000</as-number>\n" + + " <router-id>10.10.1.1</router-id>\n" + + " <neighbors>\n" + + " <as-number>2000</as-number>\n" + + " <peer-ip>10.10.1.2</peer-ip>\n" + + " </neighbors>\n" + + " </bgp>\n" + + " </router>\n" + + " </config>\n" + + " </edit-config>\n" + + "</rpc>\n"; + + public static void main(String[] args) throws APPCException { + try { + NetconfConnectionDetails connectionDetails = new NetconfConnectionDetails(); + connectionDetails.setHost(HOST); + connectionDetails.setPort(PORT); + connectionDetails.setUsername(USER); + connectionDetails.setPassword(PSWD); + connectionDetails.setCapabilities(CAPABILITIES); + NetconfClientJsch netconfClientJsch = new NetconfClientJsch(); + netconfClientJsch.connect(connectionDetails); + try { + System.out.println("=> Running get configuration..."); + String configuration = netconfClientJsch.getConfiguration(); + System.out.println("=> Configuration:\n" + configuration); + + System.out.println("=> Reconfiguring device..."); + String outMessage = netconfClientJsch.exchangeMessage(CONFIG); + System.out.println("=> Reconfiguration response:\n" + outMessage); + } finally { + netconfClientJsch.disconnect(); + } + } catch(Exception e) { + e.printStackTrace(); + } + } +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/openecomp/appc/adapter/netconf/jsch/TestOperationalStates.java b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/openecomp/appc/adapter/netconf/jsch/TestOperationalStates.java new file mode 100644 index 000000000..39c1a871c --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/test/java/org/openecomp/appc/adapter/netconf/jsch/TestOperationalStates.java @@ -0,0 +1,87 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.netconf.jsch; + +import java.util.Collections; +import java.util.List; + +import org.openecomp.appc.adapter.netconf.NetconfConnectionDetails; +import org.openecomp.appc.adapter.netconf.jsch.NetconfClientJsch; +import org.openecomp.appc.exceptions.APPCException; + +public class TestOperationalStates { + + private static final String HOST = "192.168.1.2"; + private static final String USER = "test"; + private static final String PSWD = "test123"; + private static final int PORT = 830; + private static final List<String> CAPABILITIES = Collections.singletonList("<capability>urn:org:openecomp:appc:capability:1.1.0</capability>"); + private static final String GET_OPERATIONAL_STATES = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + + "<rpc message-id=\"101\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" + + " <get>\n" + + " <filter>\n" + + " <ManagedElement xmlns=\"urn:org:openecomp:appc:Test\">\n" + + " <VnfFunction xmlns=\"urn:org:openecomp:appc:Test\">\n" + + " <ProcessorManagement>\n" + + " <MatedPair>\n" + + " <operationalState/>\n" + + " <PayloadProcessor>\n" + + " <operationalState/>\n" + + " </PayloadProcessor>\n" + + " </MatedPair>\n" + + " <SystemController>\n" + + " <operationalState/>\n" + + " </SystemController>\n" + + " </ProcessorManagement>\n" + + " </VnfFunction>\n" + + " </ManagedElement>\n" + + " </filter>\n" + + " </get>\n" + + "</rpc>"; + + public static void main(String[] args) throws APPCException { + try { + NetconfConnectionDetails connectionDetails = new NetconfConnectionDetails(); + connectionDetails.setHost(HOST); + connectionDetails.setPort(PORT); + connectionDetails.setUsername(USER); + connectionDetails.setPassword(PSWD); + connectionDetails.setCapabilities(CAPABILITIES); + NetconfClientJsch netconfClientJsch = new NetconfClientJsch(); + netconfClientJsch.connect(connectionDetails); + try { + System.out.println("=> Running get configuration..."); + String configuration = netconfClientJsch.getConfiguration(); + System.out.println("=> Configuration:\n" + configuration); + + System.out.println("=> Running get operational states..."); + String outMessage = netconfClientJsch.exchangeMessage(GET_OPERATIONAL_STATES); + System.out.println("=> Operational states:\n" + outMessage); + } finally { + netconfClientJsch.disconnect(); + } + } catch(Exception e) { + e.printStackTrace(); + } + } +} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-features/pom.xml b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-features/pom.xml new file mode 100644 index 000000000..e94bdba56 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-features/pom.xml @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <parent> + <artifactId>appc-netconf-adapter</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>appc-netconf-adapter-features</artifactId> + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-netconf-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>features-mdsal</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </dependency> + + <!-- dependency for opendaylight-karaf-empty for use by testing --> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>opendaylight-karaf-empty</artifactId> + <type>zip</type> + </dependency> + + <!-- <dependency>--> + <!-- Required for launching the feature tests --> + <!-- <groupId>org.opendaylight.yangtools</groupId> + <artifactId>features-test</artifactId> + <scope>test</scope> + </dependency>--> + + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>features-yangtools</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <!-- launches the feature test, which validates that your karaf feature + can be installed inside of a karaf container. It doesn't validate that your + functionality works correctly, just that you have all of the dependent bundles + defined correctly. --> + <!-- <plugin> --> + <!-- <groupId>org.apache.maven.plugins</groupId> --> + <!-- <artifactId>maven-surefire-plugin</artifactId> --> + <!-- <version>2.16</version> --> + <!-- <configuration> --> + <!-- <systemPropertyVariables> --> + <!-- <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId> --> + <!-- <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId> --> + <!-- <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version> --> + <!-- </systemPropertyVariables> --> + <!-- <dependenciesToScan> --> + <!-- <dependency>org.opendaylight.yangtools:features-test</dependency> --> + <!-- </dependenciesToScan> --> + <!-- </configuration> --> + <!-- </plugin> --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-features/src/main/resources/features.xml b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-features/src/main/resources/features.xml new file mode 100644 index 000000000..bfb4b8090 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-features/src/main/resources/features.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="appc-netconf-adapter-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + + <repository>mvn:org.opendaylight.mdsal/features-mdsal/${features-mdsal.version}/xml/features</repository> + + <feature name='appc-netconf-adapter' description="appc-netconf-adapter" version='${project.version}'> + <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> + <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> + <bundle>mvn:org.openecomp.appc/appc-dmaap-adapter-bundle/${project.version}</bundle> + <bundle start-level="83" start="true">mvn:org.openecomp.appc/appc-netconf-adapter-bundle/${project.version}</bundle> + </feature> + +</features> diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-installer/pom.xml b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-installer/pom.xml new file mode 100644 index 000000000..141a1e254 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-installer/pom.xml @@ -0,0 +1,130 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-netconf-adapter</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>appc-netconf-adapter-installer</artifactId> + <name>NETCONF Adapter - Karaf Installer</name> + <packaging>pom</packaging> + + <properties> + <application.name>appc-netconf-adapter</application.name> + <features.boot>appc-netconf-adapter</features.boot> + <features.repositories>mvn:org.openecomp.appc/appc-netconf-adapter-features/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-netconf-adapter-features</artifactId> + <classifier>features</classifier> + <type>xml</type> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-netconf-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>false</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>true</attach> + <finalName>${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <excludeGroupIds>org.opendaylight</excludeGroupIds> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals> + <!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-installer/src/assembly/assemble_installer_zip.xml b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..9fbaad8c5 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>adapter</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-installer/src/assembly/assemble_mvnrepo_zip.xml b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..1ac5a82bc --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,47 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>adapter</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + +</assembly> diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-installer/src/main/resources/scripts/install-feature.sh b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..1d769fada --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/appc-netconf-installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,40 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +#!/bin/bash + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -n -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot} diff --git a/app-c/appc/appc-adapters/appc-netconf-adapter/pom.xml b/app-c/appc/appc-adapters/appc-netconf-adapter/pom.xml new file mode 100644 index 000000000..5ef2cd3e3 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-netconf-adapter/pom.xml @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <parent> + <artifactId>appc-adapters</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>appc-netconf-adapter</artifactId> + <name>NETCONF adapter</name> + <packaging>pom</packaging> + + <properties> + <feature.netconf.connector.version>1.0.1-Beryllium-SR1</feature.netconf.connector.version> + </properties> + + <reporting> + <plugins> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <additionalDependencies> + <additionalDependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4</artifactId> + <version>${antlr.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4-runtime</artifactId> + <version>4.3</version> + </additionalDependency> + </additionalDependencies> + </configuration> + <reportSets> + <reportSet> + <reports> + <report>javadoc-no-fork</report> + <report>test-javadoc-no-fork</report> + </reports> + </reportSet> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jxr-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-changelog-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>dual-report</id> + <configuration> + <type>range</type> + <range>30</range> + </configuration> + <reports> + <report>changelog</report> + <report>file-activity</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>taglist-maven-plugin</artifactId> + <version>2.4</version> + </plugin> + </plugins> + </reporting> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-netconf-adapter-features</artifactId> + <classifier>features</classifier> + <type>xml</type> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-netconf-adapter-provider</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + </dependencyManagement> + + <modules> + <module>appc-netconf-adapter-bundle</module> + <module>appc-netconf-adapter-features</module> + <module>appc-netconf-installer</module> + </modules> + + +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-adapters/appc-rest-adapter/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/.gitignore b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/.gitignore new file mode 100644 index 000000000..755cdc373 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/.gitignore @@ -0,0 +1,3 @@ +/bin/ +/target/ +/.settings/ diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/pom.xml b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/pom.xml new file mode 100644 index 000000000..662fd00a2 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/pom.xml @@ -0,0 +1,230 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-rest-adapter</artifactId> + <version>1.0.0</version> + </parent> + + <artifactId>appc-rest-adapter-bundle</artifactId> + <packaging>bundle</packaging> + <name>rest Adapter - bundle</name> + + <dependencies> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + <!-- http://mvnrepository.com/artifact/commons-logging/commons-logging --> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>1.2</version> + </dependency> + <!-- http://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore --> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore</artifactId> + <version>4.4.4</version> + </dependency> + + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>4.5.1</version> + </dependency> + <dependency> + <groupId>org.bouncycastle</groupId> + <artifactId>bcpkix-jdk15on</artifactId> + </dependency> + <dependency> + <groupId>org.bouncycastle</groupId> + <artifactId>bcprov-jdk15on</artifactId> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + <classifier>jar-with-dependencies</classifier> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>javax</groupId> + <artifactId>javaee-api</artifactId> + <version>7.0</version> + </dependency> +<!-- <dependency> --> +<!-- <groupId>jce</groupId> --> +<!-- <artifactId>jce</artifactId> --> +<!-- <version>1_2-do</version> --> +<!-- <scope>compile</scope> --> +<!-- </dependency> --> + + <dependency> + <groupId>com.att.cdp</groupId> + <artifactId>cdp-pal-common</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>com.att.cdp</groupId> + <artifactId>cdp-pal-openstack</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>javax.ws.rs</groupId> + <artifactId>javax.ws.rs-api</artifactId> + </dependency> + + <!-- Jersey support needed for OpenStack connector and API version logic --> + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-client</artifactId> + </dependency> + + <dependency> + <groupId>org.json</groupId> + <artifactId>json</artifactId> + </dependency> + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-json</artifactId> + </dependency> + + <dependency> + <groupId>javax.xml.bind</groupId> + <artifactId>jaxb-api</artifactId> + <version>2.1</version> + </dependency> + + <dependency> + <groupId>javax.xml</groupId> + <artifactId>jaxp-api</artifactId> + <version>1.4.2</version> + </dependency> + + <!-- Needed to run test cases --> + <dependency> + <groupId>org.glassfish.jersey.core</groupId> + <artifactId>jersey-common</artifactId> + <version>2.9.1</version> + </dependency> + + <dependency> + <groupId>org.codehaus.jackson</groupId> + <artifactId>jackson-jaxrs</artifactId> + <version>1.9.12</version> + </dependency> + + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>4.5.1</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>compile</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>equinoxSDK381</groupId> + <artifactId>org.eclipse.osgi</artifactId> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + </dependency> + + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + <version>5.1.31</version> + <type>jar</type> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>com.vmware</groupId> + <artifactId>vijava</artifactId> + <version>5.1</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>xerces</groupId> + <artifactId>xerces</artifactId> + <version>2.4.0</version> + <scope>provided</scope> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>appc-rest-adapter</Bundle-SymbolicName> + <Bundle-Activator>org.openecomp.appc.adapter.rest.RestActivator</Bundle-Activator> + <Export-Package>org.openecomp.appc.adapter.rest</Export-Package> + <Import-Package>org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.bind.*,javax.naming.*</Import-Package> + <Embed-Dependency>*;scope=compile|runtime;artifactId=!sli-common|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + + <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation> + </configuration> + </plugin> + </plugins> + </build> +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/RestActivator.java b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/RestActivator.java new file mode 100644 index 000000000..d1515c418 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/RestActivator.java @@ -0,0 +1,143 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.rest; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.rest.impl.RestAdapterImpl; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.i18n.Msg; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +/** + * This activator is used to initialize and terminate the connection pool to one or more providers. + * <p> + * The CDP abstraction layer supports multiple types of providers, with each provider supporting multiple tenants. The + * "connection" to a specific tenant on a specific provider is represented by a "context" object. These context objects + * are authenticated to a specific tenant on the provider, but can be reused from one request to another. Contexts are + * slow to set up and are resource intensive, so they are cached. However, the contexts for a specific tenant on a + * specific provider must be cached separately. + * </p> + * <p> + * Activation of the bundle creates an empty cache which is organized first by provider type, then by tenant name, with + * the contents being an empty pool of contexts for that provider/tenant combination. The pool is created on first use, + * and retained for as long as the bundle is active. + * </p> + * <p> + * When the bundle is deactivated, the cache is torn down with all contexts being closed. + * </p> + */ +public class RestActivator implements BundleActivator { + + /** + * The bundle registration + */ + private ServiceRegistration registration = null; + + /** + * The reference to the actual implementation object that implements the services + */ + private RestAdapter adapter; + + /** + * The logger to be used + */ + // private static final Logger LOG = LoggerFactory.getLogger(RestActivator.class); + private static final EELFLogger logger = EELFManager.getInstance().getLogger(RestActivator.class); + + /** + * The configuration object used to configure this bundle + */ + private Configuration configuration; + + /** + * Called when this bundle is started so the Framework can perform the bundle-specific activities necessary to start + * this bundle. This method can be used to register services or to allocate any resources that this bundle needs. + * <p> + * This method must complete and return to its caller in a timely manner. + * </p> + * + * @param context + * The execution context of the bundle being started. + * @throws java.lang.Exception + * If this method throws an exception, this bundle is marked as stopped and the Framework will remove + * this bundle's listeners, unregister all services registered by this bundle, and release all services + * used by this bundle. + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + logger.info("Starting bundle " + getName()); + + configuration = ConfigurationFactory.getConfiguration(); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.COMPONENT_INITIALIZING, appName, "rest adapter"); + adapter = new RestAdapterImpl(configuration.getProperties()); + if (registration == null) { + logger.info(Msg.REGISTERING_SERVICE, appName, adapter.getAdapterName(), + RestAdapter.class.getSimpleName()); + registration = context.registerService(RestAdapter.class, adapter, null); + } + + logger.info(Msg.COMPONENT_INITIALIZED, appName, "REST adapter"); + } + + /** + * Called when this bundle is stopped so the Framework can perform the bundle-specific activities necessary to stop + * the bundle. In general, this method should undo the work that the BundleActivator.start method started. There + * should be no active threads that were started by this bundle when this bundle returns. A stopped bundle must not + * call any Framework objects. + * <p> + * This method must complete and return to its caller in a timely manner. + * </p> + * + * @param context + * The execution context of the bundle being stopped. + * @throws java.lang.Exception + * If this method throws an exception, the bundle is still marked as stopped, and the Framework will + * remove the bundle's listeners, unregister all services registered by the bundle, and release all + * services used by the bundle. * + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + logger.info("Stopping bundle " + getName()); + + if (registration != null) { + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.COMPONENT_TERMINATING, appName, "REST adapter"); + logger.info(Msg.UNREGISTERING_SERVICE, appName, adapter.getAdapterName()); + registration.unregister(); + registration = null; + logger.info(Msg.COMPONENT_TERMINATED, appName, "REST adapter"); + } + } + + public String getName() { + return "APPC IaaS adapter"; + } + +} diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/RestAdapter.java b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/RestAdapter.java new file mode 100644 index 000000000..0d4a19709 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/RestAdapter.java @@ -0,0 +1,205 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.rest; + +import java.util.Map; + +import org.openecomp.appc.exceptions.APPCException; +import com.att.cdp.zones.model.Server; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + +/** + * This interface defines the operations that the provider adapter exposes. + * <p> + * This interface defines static constant property values that can be used to configure the adapter. These constants are + * prefixed with the name PROPERTY_ to indicate that they are configuration properties. These properties are read from + * the configuration file for the adapter and are used to define the providers, identity service URLs, and other + * information needed by the adapter to interface with an IaaS provider. + * </p> + */ +public interface RestAdapter extends SvcLogicJavaPlugin { + + /** + * The type of provider to be accessed to locate and operate on a virtual machine instance. This is used to load the + * correct provider support through the CDP IaaS abstraction layer and can be OpenStackProvider, BareMetalProvider, + * or any other supported provider type. + */ + static final String PROPERTY_PROVIDER_TYPE = "org.openecomp.appc.provider.type"; + + /** + * The adapter maintains a cache of providers organized by the name of the provider, not its type. This is + * equivalent to the system or installation name. All regions within the same installation are assumed to be the + * same type. + */ + static final String PROPERTY_PROVIDER_NAME = "org.openecomp.appc.provider.name"; + + /** + * The fully-qualified URL of the instance to be manipulated as it is known to the provider. + */ + static final String PROPERTY_INSTANCE_URL = "org.openecomp.appc.instance.url"; + + /** + * The fully-qualified URL of the instance to be manipulated as it is known to the provider. + */ + static final String PROPERTY_IDENTITY_URL = "org.openecomp.appc.identity.url"; + + /** + * This method is used to restart an existing virtual machine given the fully qualified URL of the machine. + * <p> + * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters + * passed to the method are passed as properties in a map. This method expects the following properties to be + * defined: + * <dl> + * <dt>org.openecomp.appc.provider.type</dt> + * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS + * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported + * provider types are legal.</dd> + * <dt>org.openecomp.appc.instance.url</dt> + * <dd>The fully qualified URL of the instance to be restarted, as it is known to the provider (i.e., the self-link + * URL of the server)</dd> + * </dl> + * </p> + * + * @param properties + * A map of name-value pairs that supply the parameters needed by this method. The properties needed are + * defined above. + * @param context + * The service logic context of the graph being executed. + * @return The <code>Server</code> object that represents the VM being restarted. The returned server object can be + * inspected for the final state of the server once the restart has been completed. The method does not + * return until the restart has either completed or has failed. + * @throws APPCException + * If the server cannot be restarted for some reason + */ + // Server restartServer(Map<String, String> properties, SvcLogicContext context) throws APPCException; + + /** + * This method is used to stop the indicated server + * <p> + * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters + * passed to the method are passed as properties in a map. This method expects the following properties to be + * defined: + * <dl> + * <dt>org.openecomp.appc.provider.type</dt> + * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS + * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported + * provider types are legal.</dd> + * <dt>org.openecomp.appc.instance.url</dt> + * <dd>The fully qualified URL of the instance to be stopped, as it is known to the provider (i.e., the self-link + * URL of the server)</dd> + * </dl> + * </p> + * + * @param properties + * A map of name-value pairs that supply the parameters needed by this method. The properties needed are + * defined above. + * @param context + * The service logic context of the graph being executed. + * @return The <code>Server</code> object that represents the VM being stopped. The returned server object can be + * inspected for the final state of the server once the stop has been completed. The method does not return + * until the stop has either completed or has failed. + * @throws APPCException + * If the server cannot be stopped for some reason + */ + //Server stopServer(Map<String, String> properties, SvcLogicContext context) throws APPCException; + + /** + * This method is used to start the indicated server + * <p> + * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters + * passed to the method are passed as properties in a map. This method expects the following properties to be + * defined: + * <dl> + * <dt>org.openecomp.appc.provider.type</dt> + * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS + * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported + * provider types are legal.</dd> + * <dt>org.openecomp.appc.instance.url</dt> + * <dd>The fully qualified URL of the instance to be started, as it is known to the provider (i.e., the self-link + * URL of the server)</dd> + * </dl> + * </p> + * + * @param properties + * A map of name-value pairs that supply the parameters needed by this method. The properties needed are + * defined above. + * @param context + * The service logic context of the graph being executed. + * @return The <code>Server</code> object that represents the VM being started. The returned server object can be + * inspected for the final state of the server once the start has been completed. The method does not return + * until the start has either completed or has failed. + * @throws APPCException + * If the server cannot be started for some reason + */ + // Server startServer(Map<String, String> properties, SvcLogicContext context) throws APPCException; + + /** + * This method is used to rebuild the indicated server + * <p> + * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters + * passed to the method are passed as properties in a map. This method expects the following properties to be + * defined: + * <dl> + * <dt>org.openecomp.appc.provider.type</dt> + * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS + * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported + * provider types are legal.</dd> + * <dt>org.openecomp.appc.instance.url</dt> + * <dd>The fully qualified URL of the instance to be rebuilt, as it is known to the provider (i.e., the self-link + * URL of the server)</dd> + * </dl> + * </p> + * + * @param properties + * A map of name-value pairs that supply the parameters needed by this method. The properties needed are + * defined above. + * @param context + * The service logic context of the graph being executed. + * @return The <code>Server</code> object that represents the VM being rebuilt. The returned server object can be + * inspected for the final state of the server once the rebuild has been completed. The method does not + * return until the rebuild has either completed or has failed. + * @throws APPCException + * If the server cannot be rebuilt for some reason + */ + // Server rebuildServer(Map<String, String> properties, SvcLogicContext context) throws APPCException; + + /** + * Returns the symbolic name of the adapter + * + * @return The adapter name + */ + String getAdapterName(); + + // Server evacuateServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + //Server migrateServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + void commonGet(Map<String, String> params, SvcLogicContext ctx) ; + + void commonPost(Map<String, String> params, SvcLogicContext ctx) ; + + void commonPut(Map<String, String> params, SvcLogicContext ctx) ; + + void commonDelete(Map<String, String> params, SvcLogicContext ctx) ; + +} diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/impl/RequestContext.java b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/impl/RequestContext.java new file mode 100644 index 000000000..c4b852317 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/impl/RequestContext.java @@ -0,0 +1,251 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.adapter.rest.impl; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.sdnc.sli.SvcLogicContext; + +/** + * This class is used to track and maintain recovery and time-to-live information for a request as it is being + * processed. + */ +public class RequestContext { + /** + * The number of seconds of wait time between successive attempts to connect to the provider. This is used to + * recover from provider outages or failures. It is not used to recover from logical errors, such as an invalid + * request, server not found, etc. + */ + private Integer retryDelay; + + /** + * The number of times we will attempt to connect to the provider. This is used to recover from provider outages or + * failures. It is not used to recover from logical errors, such as an invalid request, server not found, etc. + */ + private Integer retryLimit; + + /** + * The total time, in milliseconds, that the provider can have to process this request. If the accumulated time + * exceeds the time to live, then the request is failed with a timeout exception, regardless of the state of the + * provider. Note that the caller may supply this as a value in seconds, in which case it must be converted to + * milliseconds for the request context. + */ + private Long timeToLive; + + /** + * The accumulated time, in milliseconds, that has been used so far to process the request. This is compared to the + * time to live each time it is updated. If the accumulated time exceeds the time to live, then the request is + * failed with a timeout exception, regardless of the state of the provider. + */ + private long accumulatedTime; + + /** + * The total number of retries attempted so far + */ + private int attempt; + + /** + * The time when the stopwatch was started + */ + private long startTime = -1; + + /** + * The service logic (DG) context from the SLI + */ + private SvcLogicContext svcLogicContext; + + /** + * The configuration + */ + private Configuration configuration = ConfigurationFactory.getConfiguration(); + + /** + * Set to true whenever the retry limit has been exceeded, reset to false when reset() is called. + */ + private boolean retryFailed; + + /** + * Creates the request context + * + * @param context + * The service logic (SLI) context associated with the current DG + */ + public RequestContext(SvcLogicContext context) { + setSvcLogicContext(context); + } + + /** + * @return The retry delay, in seconds. If zero, then no retry is to be performed + */ + public int getRetryDelay() { + if (retryDelay == null) { + int value = configuration.getIntegerProperty(Constants.PROPERTY_RETRY_DELAY); + retryDelay = Integer.valueOf(value); + } + + return retryDelay.intValue(); + } + + /** + * This method is a helper that allows the caller to delay for the retry interval time and not have to handle the + * thread interruption, timer handling, etc. + */ + public void delay() { + long time = getRetryDelay() * 1000L; + long future = System.currentTimeMillis() + time; + if (time != 0) { + while (System.currentTimeMillis() < future && time > 0) { + try { + Thread.sleep(time); + } catch (InterruptedException e) { + /* + * This is rare, but it can happen if another thread interrupts us while we are sleeping. In that + * case, the thread is resumed before the delay time has actually expired, so re-calculate the + * amount of delay time needed and reenter the sleep until we get to the future time. + */ + time = future - System.currentTimeMillis(); + } + } + } + } + + /** + * @return The number of retries that are allowed per connection + */ + public int getRetryLimit() { + if (retryLimit == null) { + int value = configuration.getIntegerProperty(Constants.PROPERTY_RETRY_LIMIT); + retryLimit = Integer.valueOf(value); + } + + return retryLimit.intValue(); + } + + /** + * Check and count the connection attempt. + * + * @return True if the connection should be attempted. False indicates that the number of retries has been exhausted + * and it should NOT be attempted. + */ + public boolean attempt() { + if (retryFailed || attempt >= getRetryLimit()) { + retryFailed = true; + return false; + } + attempt++; + + return true; + } + + /** + * @return The number of retry attempts so far + */ + public int getAttempts() { + return attempt; + } + + /** + * @return True if the retry limit has been exceeded, false otherwise + */ + public boolean isFailed() { + return retryFailed; + } + + /** + * This method both checks the time to live to see if it has been exceeded and accumulates the total time used so + * far. + * <p> + * Each time this method is called it accumulates the total duration since the last time it was called to the total + * time accumulator. It then checks the total time to the time to live and if greater, it returns false. As long as + * the total time used is less than or equal to the time to live limit, the method returns true. It is important to + * call this method at the very beginning of the process so that all parts of the process are tracked. + * </p> + * + * @return True if the total time to live has not been exceeded. False indicates that the total time to live has + * been exceeded and no further processing should be performed. + */ + public boolean isAlive() { + long now = System.currentTimeMillis(); + if (startTime == -1) { + startTime = now; + return true; + } + accumulatedTime += (now - startTime); + startTime = now; + if (accumulatedTime > timeToLive) { + return false; + } + return true; + } + + /** + * @return The total amount of time used, in milliseconds. + */ + public long getTotalDuration() { + return accumulatedTime; + } + + /** + * This method is called to reset the retry counters. It has no effect on the time to live accumulator. + */ + public void reset() { + attempt = 0; + } + + /** + * Sets the time to live to the value, expressed in seconds + * + * @param time + * The time to live, in seconds + */ + public void setTimeToLiveSeconds(int time) { + setTimeToLiveMS(time * 1000L); + } + + /** + * Sets the time to live to the value, expressed in milliseconds + * + * @param time + * The time to live, in milliseconds + */ + public void setTimeToLiveMS(long time) { + this.timeToLive = time; + } + + /** + * @return The service logic context associated with this request + */ + public SvcLogicContext getSvcLogicContext() { + return svcLogicContext; + } + + /** + * @param svcLogicContext + * The service logic context to be associated with this request + */ + public void setSvcLogicContext(SvcLogicContext svcLogicContext) { + this.svcLogicContext = svcLogicContext; + } +} diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/impl/RequestFailedException.java b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/impl/RequestFailedException.java new file mode 100644 index 000000000..eff1597c1 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/impl/RequestFailedException.java @@ -0,0 +1,244 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.adapter.rest.impl; + +import org.glassfish.grizzly.http.util.HttpStatus; +import com.att.cdp.zones.model.Server; + +/** + * This class is used to capture the exact cause and point of failure for the processing of a request. It is then used + * to encode the reason for the failure, status code, and anything else that needs to be captured and reported for + * diagnostic purposes. + */ +public class RequestFailedException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * The operation that was being requested or performed at the time of the failure. + */ + private String operation; + + /** + * A message that details the reason for the failure + */ + private String reason; + + /** + * The server that was being operated upon + */ + private Server server; + + /** + * The id of the server being operated upon if the server object is not available (such as the server was not found) + */ + private String serverId; + + /** + * The most appropriate Http Status code that reflects the error + */ + private HttpStatus status; + + /** + * + */ + public RequestFailedException() { + // intentionally empty + } + + /** + * @param message + * The error message + */ + public RequestFailedException(String message) { + super(message); + } + + /** + * Construct the request failed exception with the operation being performed, reason for the failure, http status + * code that is most appropriate, and the server we were processing. + * + * @param operation + * The operation being performed + * @param reason + * The reason that the operation was failed + * @param status + * The http status code that is most appropriate + * @param server + * The server that we were processing + */ + @SuppressWarnings("nls") + public RequestFailedException(String operation, String reason, HttpStatus status, Server server) { + super(operation + ":" + reason); + this.operation = operation; + this.reason = reason; + this.status = status; + this.server = server; + if (server != null) { + this.serverId = server.getId(); + } + } + + /** + * Construct the request failed exception with the operation being performed, reason for the failure, http status + * code that is most appropriate, and the server we were processing. + * + * @param ex + * The exception that we are wrapping + * @param operation + * The operation being performed + * @param reason + * The reason that the operation was failed + * @param status + * The http status code that is most appropriate + * @param server + * The server that we were processing + */ + @SuppressWarnings("nls") + public RequestFailedException(Throwable ex, String operation, String reason, HttpStatus status, Server server) { + super(operation + ":" + reason, ex); + this.operation = operation; + this.reason = reason; + this.status = status; + this.server = server; + if (server != null) { + this.serverId = server.getId(); + } + } + + /** + * @param message + * The error message + * @param cause + * A nested exception + */ + public RequestFailedException(String message, Throwable cause) { + super(message, cause); + } + + /** + * @param message + * The error message + * @param cause + * A nested exception + * @param enableSuppression + * whether or not suppression is enabled or disabled + * @param writableStackTrace + * whether or not the stack trace should be writable + */ + public RequestFailedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + /** + * @param cause + * the cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or unknown.) + */ + public RequestFailedException(Throwable cause) { + super(cause); + } + + /** + * @return The operation being performed + */ + public String getOperation() { + return operation; + } + + /** + * @return The reason for the failure + */ + public String getReason() { + return reason; + } + + /** + * @return The server being operated upon + */ + public Server getServer() { + return server; + } + + /** + * @return The id of the server being operated upon + */ + public String getServerId() { + return serverId; + } + + /** + * @return The status code from the operation + */ + public HttpStatus getStatus() { + return status; + } + + /** + * @param operation + * The operation being performed + */ + public void setOperation(String operation) { + this.operation = operation; + } + + /** + * @param reason + * The reason for the failure + */ + public void setReason(String reason) { + this.reason = reason; + } + + /** + * @param server + * The server being operated upon + */ + public void setServer(Server server) { + this.server = server; + if (server != null) { + setServerId(server.getId()); + } + } + + /** + * @param serverId + * The id of the server being operated upon + */ + public void setServerId(String serverId) { + this.serverId = serverId; + } + + /** + * @param status + * The status of the request + */ + public void setStatus(HttpStatus status) { + this.status = status; + } + +} diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/impl/RestAdapterImpl.java b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/impl/RestAdapterImpl.java new file mode 100644 index 000000000..82aad7d6f --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/impl/RestAdapterImpl.java @@ -0,0 +1,491 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.rest.impl; + +import java.net.URI; +import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.regex.Pattern; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.rest.RestAdapter; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.exceptions.UnknownProviderException; +import org.openecomp.appc.i18n.Msg; +import org.openecomp.appc.pool.Pool; +import org.openecomp.appc.pool.PoolExtensionException; +import org.openecomp.appc.util.StructuredPropertyHelper; +import org.openecomp.appc.util.StructuredPropertyHelper.Node; +import com.att.cdp.exceptions.ContextConnectionException; +import com.att.cdp.exceptions.ResourceNotFoundException; +import com.att.cdp.exceptions.TimeoutException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.pal.util.StringHelper; +import com.att.cdp.zones.ComputeService; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.ImageService; +import com.att.cdp.zones.Provider; +import com.att.cdp.zones.model.Image; +import com.att.cdp.zones.model.Server; +import com.att.cdp.zones.model.Server.Status; +import com.att.cdp.zones.model.ServerBootSource; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; +import org.openecomp.sdnc.sli.SvcLogicContext; + +import org.glassfish.grizzly.http.util.HttpStatus; +import org.slf4j.MDC; + +import java.net.InetAddress; +import java.util.Locale; +import java.util.UUID; +import static com.att.eelf.configuration.Configuration.*; + +import org.apache.http.*; +import org.apache.http.client.*; +import org.apache.http.client.methods.*; +import org.apache.http.impl.client.*; +import org.apache.http.util.EntityUtils; +import java.io.IOException; +import org.apache.http.entity.StringEntity; + +import java.net.InetAddress; +import org.json.*; + +/** + * This class implements the {@link RestAdapter} interface. This interface + * defines the behaviors that our service provides. + */ +public class RestAdapterImpl implements RestAdapter { + + /** + * The constant used to define the adapter name in the mapped diagnostic + * context + */ + + + @SuppressWarnings("nls") + public static final String MDC_ADAPTER = "adapter"; + + /** + * The constant used to define the service name in the mapped diagnostic + * context + */ + @SuppressWarnings("nls") + public static final String MDC_SERVICE = "service"; + + /** + * The constant for the status code for a failed outcome + */ + @SuppressWarnings("nls") + public static final String OUTCOME_FAILURE = "failure"; + + /** + * The constant for the status code for a successful outcome + */ + @SuppressWarnings("nls") + public static final String OUTCOME_SUCCESS = "success"; + + /** + * A constant for the property token "provider" used in the structured + * property specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER = "provider"; + + /** + * A constant for the property token "identity" used in the structured + * property specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_IDENTITY = "identity"; + + /** + * A constant for the property token "name" used in the structured property + * specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_NAME = "name"; + + /** + * A constant for the property token "tenant" used in the structured + * property specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_TENANT = "tenant"; + + /** + * A constant for the property token "tenant name" used in the structured + * property specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_TENANT_NAME = "name"; + + /** + * A constant for the property token "password" used in the structured + * property specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_TENANT_PASSWORD = "password"; // NOSONAR + + /** + * A constant for the property token "userid" used in the structured + * property specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_TENANT_USERID = "userid"; + + /** + * A constant for the property token "type" used in the structured property + * specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_TYPE = "type"; + + /** + * The name of the service to restart a server + */ + @SuppressWarnings("nls") + public static final String PING_SERVICE = "pingServer"; + + /** + * The logger to be used + */ + private static final EELFLogger logger = EELFManager.getInstance().getLogger(RestAdapterImpl.class); + + /** + * The constant for a left parenthesis + */ + private static final char LPAREN = '('; + + /** + * The constant for a new line control code + */ + private static final char NL = '\n'; + + /** + * The constant for a single quote + */ + private static final char QUOTE = '\''; + + /** + * The constant for a right parenthesis + */ + private static final char RPAREN = ')'; + + /** + * The constant for a space + */ + private static final char SPACE = ' '; + + /** + * A reference to the adapter configuration object. + */ + private Configuration configuration; + + /** + * A cache of providers that are predefined. + */ + // private Map<String /* provider name */, ProviderCache> providerCache; + + /** + * This default constructor is used as a work around because the activator + * wasnt getting called + */ + /** + * A cache of providers that are predefined. + */ + // private Map<String /* provider name */, ProviderCache> providerCache; + + /** + * This default constructor is used as a work around because the activator + * wasnt getting called + */ + public RestAdapterImpl() { + initialize(); + + } + + /** + * This constructor is used primarily in the test cases to bypass + * initialization of the adapter for isolated, disconnected testing + * + * @param initialize + * True if the adapter is to be initialized, can false if not + */ + public RestAdapterImpl(boolean initialize) { + configuration = ConfigurationFactory.getConfiguration(); + if (initialize) { + initialize(); + + } + } + + /** + * @param props + * not used + */ + public RestAdapterImpl(Properties props) { + initialize(); + + } + + /** + * Returns the symbolic name of the adapter + * + * @return The adapter name + * @see org.openecomp.appc.adapter.rest.RestAdapter#getAdapterName() + */ + @Override + public String getAdapterName() { + return configuration.getProperty(Constants.PROPERTY_ADAPTER_NAME); + } + + public HttpRequestBase addHeaders(HttpRequestBase method,String headers){ + if(headers.length()==0) + { + return method; + }else{ + JSONObject JsonHeaders= new JSONObject(headers); + Iterator keys = JsonHeaders.keys(); + while(keys.hasNext()) { + String String1 = (String)keys.next(); + String String2 = JsonHeaders.getString(String1); + method.addHeader(String1,String2); + } + return method; + } + } + + + public void commonGet(Map<String, String> params, SvcLogicContext ctx) { + logger.info("Run get method"); + String haveHeader="false"; + String tUrl=params.get("org.openecomp.appc.instance.URI"); + haveHeader=params.get("org.openecomp.appc.instance.haveHeader"); + String headers=params.get("org.openecomp.appc.instance.headers"); + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + try { + HttpGet httpGet = new HttpGet(tUrl); + + if(haveHeader.equals("true")) + { + JSONObject JsonHeaders= new JSONObject(headers); + Iterator keys = JsonHeaders.keys(); + while(keys.hasNext()) { + String String1 = (String)keys.next(); + String String2 = JsonHeaders.getString(String1); + httpGet.addHeader(String1,String2); + } + + } + + HttpClient httpClient = HttpClients.createDefault(); + HttpResponse response = null; + response = httpClient.execute(httpGet); + int responseCode=response.getStatusLine().getStatusCode(); + HttpEntity entity = response.getEntity(); + String responseOutput=EntityUtils.toString(entity); + doSuccess(rc,responseCode,responseOutput); + } catch (Exception ex) { + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, ex.toString()); + } + } + + + public void commonDelete(Map<String, String> params, SvcLogicContext ctx) { + logger.info("Run Delete method"); + String haveHeader="false"; + String tUrl=params.get("org.openecomp.appc.instance.URI"); + haveHeader=params.get("org.openecomp.appc.instance.haveHeader"); + String headers=params.get("org.openecomp.appc.instance.headers"); + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + try { + HttpDelete httpDelete = new HttpDelete(tUrl); + if(haveHeader.equals("true")) + { + JSONObject JsonHeaders= new JSONObject(headers); + Iterator keys = JsonHeaders.keys(); + while(keys.hasNext()) { + String String1 = (String)keys.next(); + String String2 = JsonHeaders.getString(String1); + httpDelete.addHeader(String1,String2); + } + + } + HttpClient httpClient = HttpClients.createDefault(); + HttpResponse response = null; + response = httpClient.execute(httpDelete); + int responseCode=response.getStatusLine().getStatusCode(); + HttpEntity entity = response.getEntity(); + String responseOutput=EntityUtils.toString(entity); + doSuccess(rc,responseCode,responseOutput); + } catch (Exception ex) { + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, ex.toString()); + } + } + + + + public void commonPost(Map<String, String> params, SvcLogicContext ctx) { + logger.info("Run post method"); + String haveHeader="false"; + String tUrl=params.get("org.openecomp.appc.instance.URI"); + String body=params.get("org.openecomp.appc.instance.requestBody"); + haveHeader=params.get("org.openecomp.appc.instance.haveHeader"); + String headers=params.get("org.openecomp.appc.instance.headers"); + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + try { + HttpPost httpPost = new HttpPost(tUrl); + if(haveHeader.equals("true")) + { + JSONObject JsonHeaders= new JSONObject(headers); + Iterator keys = JsonHeaders.keys(); + while(keys.hasNext()) { + String String1 = (String)keys.next(); + String String2 = JsonHeaders.getString(String1); + httpPost.addHeader(String1,String2); + } + + } + StringEntity bodyParams =new StringEntity (body,"UTF-8"); + httpPost.setEntity(bodyParams); + HttpClient httpClient = HttpClients.createDefault(); + HttpResponse response = null; + response = httpClient.execute(httpPost); + int responseCode=response.getStatusLine().getStatusCode(); + HttpEntity entity = response.getEntity(); + String responseOutput=EntityUtils.toString(entity); + doSuccess(rc,responseCode,responseOutput); + } catch (Exception ex) { + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, ex.toString()); + } + } + + public void commonPut(Map<String, String> params, SvcLogicContext ctx) { + logger.info("Run put method"); + String haveHeader="false"; + String tUrl=params.get("org.openecomp.appc.instance.URI"); + String body=params.get("org.openecomp.appc.instance.requestBody"); + haveHeader=params.get("org.openecomp.appc.instance.haveHeader"); + String headers=params.get("org.openecomp.appc.instance.headers"); + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + try { + HttpPut httpPut = new HttpPut(tUrl); + if(haveHeader.equals("true")) + { + JSONObject JsonHeaders= new JSONObject(headers); + Iterator keys = JsonHeaders.keys(); + while(keys.hasNext()) { + String String1 = (String)keys.next(); + String String2 = JsonHeaders.getString(String1); + httpPut.addHeader(String1,String2); + } + + } + StringEntity bodyParams =new StringEntity (body,"UTF-8"); + httpPut.setEntity(bodyParams); + HttpClient httpClient = HttpClients.createDefault(); + HttpResponse response = null; + response = httpClient.execute(httpPut); + int responseCode=response.getStatusLine().getStatusCode(); + HttpEntity entity = response.getEntity(); + String responseOutput=EntityUtils.toString(entity); + if(responseCode == 200){ + doSuccess(rc,responseCode,responseOutput); + } else { + doFailure(rc, HttpStatus.getHttpStatus(responseCode), response.getStatusLine().getReasonPhrase()); + } + } + catch (Exception ex) { + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, ex.toString()); + } +/* } catch (Exception ex) { + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, ex.getMessage()); + }*/ + } + + @SuppressWarnings("static-method") + private void doFailure(RequestContext rc, HttpStatus code, String message) { + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + String msg = (message == null) ? code.getReasonPhrase() : message; + if (msg.contains("\n")) { + msg = msg.substring(msg.indexOf("\n")); + } + + String status; + try { + status = Integer.toString(code.getStatusCode()); + } catch (Exception e) { + status = "500"; + } + svcLogic.setStatus(OUTCOME_FAILURE); + svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_CODE, status); + svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE, msg); + svcLogic.setAttribute("org.openecomp.rest.result.code", status); + svcLogic.setAttribute("org.openecomp.rest.result.message", msg); + } + + + /** + * @param rc + * The request context that manages the state and recovery of the + * request for the life of its processing. + */ + @SuppressWarnings("static-method") + private void doSuccess(RequestContext rc, int code, String message) { + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + svcLogic.setStatus(OUTCOME_SUCCESS); + svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_CODE, Integer.toString(HttpStatus.OK_200.getStatusCode())); + svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE, message); + svcLogic.setAttribute("org.openecomp.rest.agent.result.code",Integer.toString(code)); + svcLogic.setAttribute("org.openecomp.rest.agent.result.message",message); + svcLogic.setAttribute("org.openecomp.rest.result.code",Integer.toString(HttpStatus.OK_200.getStatusCode())); + } + + + /** + * initialize the provider adapter by building the context cache + */ + private void initialize() { + configuration = ConfigurationFactory.getConfiguration(); + + logger.info("init rest adapter!!!!!"); + } + +} diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..3d4f9b373 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,93 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# +# Default properties for the APP-C Provider Adapter +# +# ------------------------------------------------------------------------------------------------- +# +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + +appc.application.name=APPC + +# +# Define the message resource bundle name to be loaded +org.openecomp.appc.resources=org/openecomp/appc/i18n/MessageResources +# +# The name of the adapter. +org.openecomp.appc.provider.adaptor.name=org.openecomp.appc.appc_provider_adapter +# +# Set up the logging environment +# +org.openecomp.appc.logging.file=org/openecomp/appc/logback.xml +org.openecomp.appc.logging.path=${user.home};etc;../etc +org.openecomp.appc.logger=org.openecomp.appc +org.openecomp.appc.security.logger=org.openecomp.appc.security +# +# The minimum and maximum provider/tenant context pool sizes. Min=1 means that as soon +# as the provider/tenant is referenced a Context is opened and added to the pool. Max=0 +# means that the upper bound on the pool is unbounded. +org.openecomp.appc.provider.min.pool=1 +org.openecomp.appc.provider.max.pool=0 + +# +# The following properties are used to configure the retry logic for connection to the +# IaaS provider(s). The retry delay property is the amount of time, in seconds, the +# application waits between retry attempts. The retry limit is the number of retries +# that are allowed before the request is failed. +org.openecomp.appc.provider.retry.delay = 30 +org.openecomp.appc.provider.retry.limit = 10 + +# +# The trusted hosts list for SSL access when a certificate is not provided. +# +provider.trusted.hosts=* +# +# The amount of time, in seconds, to wait for a server state change (start->stop, stop->start, etc). +# If the server does not change state to a valid state within the alloted time, the operation +# fails. +org.openecomp.appc.server.state.change.timeout=300 +# +# The amount of time to wait, in seconds, between subsequent polls to the OpenStack provider +# to refresh the status of a resource we are waiting on. +# +org.openecomp.appc.openstack.poll.interval=20 +# +# The connection information to connect to the provider we are using. These properties +# are "structured" properties, in that the name is a compound name, where the nodes +# of the name can be ordered (1, 2, 3, ...). All of the properties with the same ordinal +# position are defining the same entity. For example, provider1.type and provider1.name +# are defining the same provider, whereas provider2.name and provider2.type are defining +# the values for a different provider. Any number of providers can be defined in this +# way. +# +# Don't change these 2 right now since they are hard coded in the DG +#provider1.type=appc +#provider1.name=appc + +#These you can change +#provider1.identity=appc +#provider1.tenant1.name=appc +#provider1.tenant1.userid=appc +#provider1.tenant1.password=appc diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/test/java/org/openecomp/appc/adapter/rest/impl/TestRestAdapterImpl.java b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/test/java/org/openecomp/appc/adapter/rest/impl/TestRestAdapterImpl.java new file mode 100644 index 000000000..daa379413 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/test/java/org/openecomp/appc/adapter/rest/impl/TestRestAdapterImpl.java @@ -0,0 +1,161 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.rest.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.MDC; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.rest.RestAdapter; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.exceptions.UnknownProviderException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.zones.ComputeService; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.ContextFactory; +import com.att.cdp.zones.model.Server; +import com.att.cdp.zones.model.Server.Status; +import org.openecomp.sdnc.sli.SvcLogicContext; + + +/** + * Test the ProviderAdapter implementation. + */ + +@Ignore +public class TestRestAdapterImpl { + + @SuppressWarnings("nls") + private static final String PROVIDER_NAME = "APPC"; + + @SuppressWarnings("nls") + private static final String PROVIDER_TYPE = "OpenStackProvider"; + + private static String IDENTITY_URL; + + private static String PRINCIPAL; + + private static String CREDENTIAL; + + private static String TENANT_NAME; + + private static String TENANT_ID; + + private static String USER_ID; + + private static String REGION_NAME; + + private static String SERVER_URL; + + private static Class<?> providerAdapterImplClass; + private static Class<?> configurationFactoryClass; + private static Field providerCacheField; + private static Field configField; + + private RestAdapterImpl adapter; + + + @SuppressWarnings("nls") + @BeforeClass + public static void once() throws NoSuchFieldException, SecurityException, NoSuchMethodException { + + } + + @Before + public void setup() throws IllegalArgumentException, IllegalAccessException { + + adapter = new RestAdapterImpl(); + } + + @Test + public void testCommonGet() throws IOException, IllegalStateException, IllegalArgumentException, + ZoneException, APPCException { + + Map<String, String> params = new HashMap<>(); + params.put("org.openecomp.appc.instance.URI", "http://example.com:8080/about/health"); + params.put("org.openecomp.appc.instance.haveHeader","false"); + SvcLogicContext svcContext = new SvcLogicContext(); + adapter.commonGet(params, svcContext); + String statusCode=svcContext.getAttribute("org.openecomp.rest.agent.result.code"); + assertEquals("200",statusCode); + } + + @Test + public void testCommonPost() throws IOException, IllegalStateException, IllegalArgumentException, + ZoneException, APPCException { + + Map<String, String> params = new HashMap<>(); + params.put("org.openecomp.appc.instance.URI", "http://example.com:8081/posttest"); + params.put("org.openecomp.appc.instance.haveHeader","false"); + params.put("org.openecomp.appc.instance.requestBody", "{\"name\":\"MyNode\", \"width\":200, \"height\":100}"); + SvcLogicContext svcContext = new SvcLogicContext(); + adapter.commonPost(params, svcContext); + String statusCode=svcContext.getAttribute("org.openecomp.rest.agent.result.code"); + assertEquals("200",statusCode); + } + + @Test + public void testCommonPut() throws IOException, IllegalStateException, IllegalArgumentException, + ZoneException, APPCException { + + Map<String, String> params = new HashMap<>(); + params.put("org.openecomp.appc.instance.URI", "http://example.com:8081/puttest"); + params.put("org.openecomp.appc.instance.haveHeader","false"); + params.put("org.openecomp.appc.instance.requestBody", "{\"name\":\"MyNode2\", \"width\":300, \"height\":300}"); + SvcLogicContext svcContext = new SvcLogicContext(); + adapter.commonPut(params, svcContext); + String statusCode=svcContext.getAttribute("org.openecomp.rest.agent.result.code"); + assertEquals("200",statusCode); + } + + @Test + public void testCommonDelete() throws IOException, IllegalStateException, IllegalArgumentException, + ZoneException, APPCException { + + Map<String, String> params = new HashMap<>(); + params.put("org.openecomp.appc.instance.URI", "http://example.com:8081/deletetest"); + params.put("org.openecomp.appc.instance.haveHeader","false"); + SvcLogicContext svcContext = new SvcLogicContext(); + adapter.commonDelete(params, svcContext); + String statusCode=svcContext.getAttribute("org.openecomp.rest.agent.result.code"); + assertEquals("200",statusCode); + } + + +} diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/test/java/org/openecomp/appc/test/ExecutorHarness.java b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/test/java/org/openecomp/appc/test/ExecutorHarness.java new file mode 100644 index 000000000..c21435d2e --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/test/java/org/openecomp/appc/test/ExecutorHarness.java @@ -0,0 +1,180 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + +package org.openecomp.appc.test; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.openecomp.appc.test.InterceptLogger; + +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + +/** + * This class is used as a test harness to wrap the call to an executor node. + */ + +public class ExecutorHarness { + + /** + * The executor to be tested + */ + private SvcLogicJavaPlugin executor; + + /** + * The collection of all exec methods found on the class + */ + private Map<String, Method> methods; + + /** + * The field of the class being tested that contains the reference to the logger to be used. This is modified to + * point to our interception logger for the test. + */ + private Field contextLogger; + + /** + * The interception logger that buffers all messages logged and allows us to look at them as part of the test case. + */ + private InterceptLogger logger; + + /** + * Create the harness and initialize it + * + * @throws SecurityException + * If a security manager, s, is present and any of the following conditions is met: + * <ul> + * <li>invocation of s.checkMemberAccess(this, Member.DECLARED) denies access to the declared field</li> + * <li>the caller's class loader is not the same as or an ancestor of the class loader for the current + * class and invocation of s.checkPackageAccess() denies access to the package of this class</li> + * </ul> + * @throws NoSuchFieldException + * if a field with the specified name is not found. + * @throws IllegalAccessException + * if this Field object is enforcing Java language access control and the underlying field is either + * inaccessible or final. + * @throws IllegalArgumentException + * if the specified object is not an instance of the class or interface declaring the underlying field + * (or a subclass or implementor thereof), or if an unwrapping conversion fails. + */ + @SuppressWarnings("nls") + public ExecutorHarness() throws NoSuchFieldException, SecurityException, IllegalArgumentException, + IllegalAccessException { + methods = new HashMap<>(); + new SvcLogicContext(); + + Class<?> contextClass = SvcLogicContext.class; + contextLogger = contextClass.getDeclaredField("LOG"); + contextLogger.setAccessible(true); + logger = new InterceptLogger(); + contextLogger.set(null, logger); + } + + /** + * Convenience constructor + * + * @param executor + * The executor to be tested by the harness + * @throws SecurityException + * If a security manager, s, is present and any of the following conditions is met: + * <ul> + * <li>invocation of s.checkMemberAccess(this, Member.DECLARED) denies access to the declared field</li> + * <li>the caller's class loader is not the same as or an ancestor of the class loader for the current + * class and invocation of s.checkPackageAccess() denies access to the package of this class</li> + * </ul> + * @throws NoSuchFieldException + * if a field with the specified name is not found. + * @throws IllegalAccessException + * if this Field object is enforcing Java language access control and the underlying field is either + * inaccessible or final. + * @throws IllegalArgumentException + * if the specified object is not an instance of the class or interface declaring the underlying field + * (or a subclass or implementor thereof), or if an unwrapping conversion fails. + */ + public ExecutorHarness(SvcLogicJavaPlugin executor) throws NoSuchFieldException, SecurityException, + IllegalArgumentException, IllegalAccessException { + this(); + setExecutor(executor); + } + + /** + * @param executor + * The java plugin class to be executed + */ + public void setExecutor(SvcLogicJavaPlugin executor) { + this.executor = executor; + scanExecutor(); + } + + /** + * @return The java plugin class to be executed + */ + public SvcLogicJavaPlugin getExecutor() { + return executor; + } + + /** + * @return The set of all methods that meet the signature requirements + */ + public List<String> getExecMethodNames() { + List<String> names = new ArrayList<>(); + names.addAll(methods.keySet()); + return names; + } + + /** + * Returns an indication if the named method is a valid executor method that could be called from a DG execute node + * + * @param methodName + * The method name to be validated + * @return True if the method name meets the signature requirements, false if the method either does not exist or + * does not meet the requirements. + */ + public boolean isExecMethod(String methodName) { + return methods.containsKey(methodName); + } + + /** + * This method scans the executor class hierarchy to locate all methods that match the required signature of the + * executor and records these methods in a map. + */ + private void scanExecutor() { + methods.clear(); + Class<?> executorClass = executor.getClass(); + Method[] publicMethods = executorClass.getMethods(); + for (Method method : publicMethods) { + if (method.getReturnType().equals(Void.class)) { + Class<?>[] paramTypes = method.getParameterTypes(); + if (paramTypes.length == 2) { + if (Map.class.isAssignableFrom(paramTypes[0]) + && SvcLogicContext.class.isAssignableFrom(paramTypes[1])) { + methods.put(method.getName(), method); + } + } + } + } + } +} diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/test/java/org/openecomp/appc/test/InterceptLogger.java b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/test/java/org/openecomp/appc/test/InterceptLogger.java new file mode 100644 index 000000000..acb122914 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/test/java/org/openecomp/appc/test/InterceptLogger.java @@ -0,0 +1,452 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.test; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Marker; + +import ch.qos.logback.classic.Level; + +/** + * This class is used as an intercept logger that can be used in testing to intercept and record all messages that are + * logged, thus allowing a junit test case to examine the log output and make assertions. + */ +public class InterceptLogger implements org.slf4j.Logger { + + /** + * This inner class represents an intercepted log event. + */ + public class LogRecord { + private Level level; + private String message; + private long timestamp; + private Throwable t; + + public LogRecord(Level level, String message) { + setLevel(level); + setTimestamp(System.currentTimeMillis()); + setMessage(message); + } + + public LogRecord(Level level, String message, Throwable t) { + this(level, message); + setThrowable(t); + } + + /** + * @return the value of level + */ + public Level getLevel() { + return level; + } + + /** + * @return the value of message + */ + public String getMessage() { + return message; + } + + /** + * @return the value of timestamp + */ + public long getTimestamp() { + return timestamp; + } + + /** + * @param level + * the value for level + */ + public void setLevel(Level level) { + this.level = level; + } + + /** + * @param message + * the value for message + */ + public void setMessage(String message) { + this.message = message; + } + + /** + * @param timestamp + * the value for timestamp + */ + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + /** + * @return the value of t + */ + public Throwable getThrowable() { + return t; + } + + /** + * @param t + * the value for t + */ + public void setThrowable(Throwable t) { + this.t = t; + } + + } + + /** + * The list of all intercepted log events + */ + private List<LogRecord> events; + + /** + * Create the intercept logger + */ + public InterceptLogger() { + events = new ArrayList<LogRecord>(1000); + } + + /** + * @return Returns all intercepted log events + */ + public List<LogRecord> getLogRecords() { + return events; + } + + /** + * Clears all log events + */ + public void clear() { + events.clear(); + } + + @Override + public void debug(Marker marker, String msg) { + debug(msg); + } + + @Override + public void debug(Marker marker, String format, Object arg) { + debug(MessageFormat.format(format, arg)); + } + + @Override + public void debug(Marker marker, String format, Object... arguments) { + debug(MessageFormat.format(format, arguments)); + } + + @Override + public void debug(Marker marker, String format, Object arg1, Object arg2) { + debug(MessageFormat.format(format, arg1, arg2)); + } + + @Override + public void debug(Marker marker, String msg, Throwable t) { + debug(msg, t); + } + + @Override + public void debug(String msg) { + events.add(new LogRecord(Level.DEBUG, msg)); + } + + @Override + public void debug(String format, Object arg) { + events.add(new LogRecord(Level.DEBUG, MessageFormat.format(format, arg))); + } + + @Override + public void debug(String format, Object... arguments) { + events.add(new LogRecord(Level.DEBUG, MessageFormat.format(format, arguments))); + } + + @Override + public void debug(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.DEBUG, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void debug(String msg, Throwable t) { + events.add(new LogRecord(Level.DEBUG, msg, t)); + } + + @Override + public void error(Marker marker, String msg) { + error(msg); + } + + @Override + public void error(Marker marker, String format, Object arg) { + error(format, arg); + } + + @Override + public void error(Marker marker, String format, Object... arguments) { + error(format, arguments); + } + + @Override + public void error(Marker marker, String format, Object arg1, Object arg2) { + error(format, arg1, arg2); + } + + @Override + public void error(Marker marker, String msg, Throwable t) { + events.add(new LogRecord(Level.ERROR, msg, t)); + } + + @Override + public void error(String msg) { + events.add(new LogRecord(Level.ERROR, msg)); + } + + @Override + public void error(String format, Object arg) { + events.add(new LogRecord(Level.ERROR, MessageFormat.format(format, arg))); + } + + @Override + public void error(String format, Object... arguments) { + events.add(new LogRecord(Level.ERROR, MessageFormat.format(format, arguments))); + } + + @Override + public void error(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.ERROR, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void error(String msg, Throwable t) { + events.add(new LogRecord(Level.ERROR, msg, t)); + } + + @Override + public String getName() { + return null; + } + + @Override + public void info(Marker marker, String msg) { + info(msg); + } + + @Override + public void info(Marker marker, String format, Object arg) { + info(format, arg); + } + + @Override + public void info(Marker marker, String format, Object... arguments) { + info(format, arguments); + } + + @Override + public void info(Marker marker, String format, Object arg1, Object arg2) { + info(format, arg1, arg2); + } + + @Override + public void info(Marker marker, String msg, Throwable t) { + events.add(new LogRecord(Level.INFO, msg, t)); + } + + @Override + public void info(String msg) { + events.add(new LogRecord(Level.INFO, msg)); + } + + @Override + public void info(String format, Object arg) { + events.add(new LogRecord(Level.INFO, MessageFormat.format(format, arg))); + } + + @Override + public void info(String format, Object... arguments) { + events.add(new LogRecord(Level.INFO, MessageFormat.format(format, arguments))); + } + + @Override + public void info(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.INFO, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void info(String msg, Throwable t) { + events.add(new LogRecord(Level.INFO, msg, t)); + } + + @Override + public boolean isDebugEnabled() { + return true; + } + + @Override + public boolean isDebugEnabled(Marker marker) { + return true; + } + + @Override + public boolean isErrorEnabled() { + return true; + } + + @Override + public boolean isErrorEnabled(Marker marker) { + return true; + } + + @Override + public boolean isInfoEnabled() { + return true; + } + + @Override + public boolean isInfoEnabled(Marker marker) { + return true; + } + + @Override + public boolean isTraceEnabled() { + return true; + } + + @Override + public boolean isTraceEnabled(Marker marker) { + return true; + } + + @Override + public boolean isWarnEnabled() { + return true; + } + + @Override + public boolean isWarnEnabled(Marker marker) { + return true; + } + + @Override + public void trace(Marker marker, String msg) { + trace(msg); + } + + @Override + public void trace(Marker marker, String format, Object arg) { + trace(format, arg); + } + + @Override + public void trace(Marker marker, String format, Object... argArray) { + trace(format, argArray); + } + + @Override + public void trace(Marker marker, String format, Object arg1, Object arg2) { + trace(format, arg1, arg2); + } + + @Override + public void trace(Marker marker, String msg, Throwable t) { + trace(msg, t); + } + + @Override + public void trace(String msg) { + events.add(new LogRecord(Level.TRACE, msg)); + } + + @Override + public void trace(String format, Object arg) { + events.add(new LogRecord(Level.TRACE, MessageFormat.format(format, arg))); + } + + @Override + public void trace(String format, Object... arguments) { + events.add(new LogRecord(Level.TRACE, MessageFormat.format(format, arguments))); + } + + @Override + public void trace(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.TRACE, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void trace(String msg, Throwable t) { + events.add(new LogRecord(Level.TRACE, msg, t)); + } + + @Override + public void warn(Marker marker, String msg) { + warn(msg); + } + + @Override + public void warn(Marker marker, String format, Object arg) { + warn(format, arg); + } + + @Override + public void warn(Marker marker, String format, Object... arguments) { + warn(format, arguments); + } + + @Override + public void warn(Marker marker, String format, Object arg1, Object arg2) { + warn(format, arg1, arg2); + } + + @Override + public void warn(Marker marker, String msg, Throwable t) { + events.add(new LogRecord(Level.WARN, msg, t)); + } + + @Override + public void warn(String msg) { + events.add(new LogRecord(Level.WARN, msg)); + } + + @Override + public void warn(String format, Object arg) { + events.add(new LogRecord(Level.WARN, MessageFormat.format(format, arg))); + } + + @Override + public void warn(String format, Object... arguments) { + events.add(new LogRecord(Level.WARN, MessageFormat.format(format, arguments))); + } + + @Override + public void warn(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.WARN, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void warn(String msg, Throwable t) { + events.add(new LogRecord(Level.WARN, msg, t)); + } +} diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/test/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/test/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..996730239 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/test/resources/org/openecomp/appc/default.properties @@ -0,0 +1,113 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# +# Default properties for the APP-C Provider Adapter +# +# ------------------------------------------------------------------------------------------------- +# +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + +appc.application.name=APPC + +# +# Define the message resource bundle name to be loaded +org.openecomp.appc.resources=org/openecomp/appc/i18n/MessageResources +# +# The name of the adapter. +org.openecomp.appc.provider.adaptor.name=org.openecomp.appc.appc_provider_adapter +# +# Set up the logging environment +# +org.openecomp.appc.logging.file=org/openecomp/appc/logback.xml +org.openecomp.appc.logging.path=${user.home};etc;../etc +org.openecomp.appc.logger=org.openecomp.appc +org.openecomp.appc.security.logger=org.openecomp.appc.security +# +# The minimum and maximum provider/tenant context pool sizes. Min=1 means that as soon +# as the provider/tenant is referenced a Context is opened and added to the pool. Max=0 +# means that the upper bound on the pool is unbounded. +org.openecomp.appc.provider.min.pool=1 +org.openecomp.appc.provider.max.pool=0 + +# +# The following properties are used to configure the retry logic for connection to the +# IaaS provider(s). The retry delay property is the amount of time, in seconds, the +# application waits between retry attempts. The retry limit is the number of retries +# that are allowed before the request is failed. +org.openecomp.appc.provider.retry.delay = 30 +org.openecomp.appc.provider.retry.limit = 10 + +# +# The trusted hosts list for SSL access when a certificate is not provided. +# +provider.trusted.hosts=* +# +# The amount of time, in seconds, to wait for a server state change (start->stop, stop->start, etc). +# If the server does not change state to a valid state within the alloted time, the operation +# fails. +org.openecomp.appc.server.state.change.timeout=300 +# +# The amount of time to wait, in seconds, between subsequent polls to the OpenStack provider +# to refresh the status of a resource we are waiting on. +# +org.openecomp.appc.openstack.poll.interval=20 +# +# The connection information to connect to the provider we are using. These properties +# are "structured" properties, in that the name is a compound name, where the nodes +# of the name can be ordered (1, 2, 3, ...). All of the properties with the same ordinal +# position are defining the same entity. For example, provider1.type and provider1.name +# are defining the same provider, whereas provider2.name and provider2.type are defining +# the values for a different provider. Any number of providers can be defined in this +# way. +# + + +### ### +### Properties commented out below provided in appc.properties ### +### ### + +# Don't change these 2 right now since they are hard coded in the DG +#provider1.type=appc +#provider1.name=appc + +#These you can change +#provider1.identity=appc +#provider1.tenant1.name=appc +#provider1.tenant1.userid=appc +#provider1.tenant1.password=appc + +# After a change to the provider make sure to recheck these values with an api call to provider1.identity/tokens +test.expected-regions=1 +test.expected-endpoints=1 + +#Your OpenStack IP +#test.ip=192.168.1.2 +# Your OpenStack Platform's Keystone Port (default is 5000) +#test.port=5000 +#test.tenantid=abcde12345fghijk6789lmnopq123rst +#test.vmid=abc12345-1234-5678-890a-abcdefg12345 +# Port 8774 below is default port for OpenStack's Nova API Service +#test.url=http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345 + diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-features/.gitignore b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-features/.gitignore new file mode 100644 index 000000000..615a76bbc --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-features/.gitignore @@ -0,0 +1,4 @@ +/target/ +/bin/ +/classes/ +/.settings/ diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-features/pom.xml b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-features/pom.xml new file mode 100644 index 000000000..05352e56b --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-features/pom.xml @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-rest-adapter</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>appc-rest-adapter-features</artifactId> + <name>Rest Adaptor - Features</name> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-rest-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>features-mdsal</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </dependency> + + <!-- dependency for opendaylight-karaf-empty for use by testing --> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>opendaylight-karaf-empty</artifactId> + <type>zip</type> + </dependency> + +<!-- <dependency> --> +<!-- Required for launching the feature tests --> +<!-- <groupId>org.opendaylight.yangtools</groupId> --> +<!-- <artifactId>features-test</artifactId> --> +<!-- <scope>test</scope> --> +<!-- </dependency> --> + + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>features-yangtools</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <!-- launches the feature test, which validates that your karaf feature + can be installed inside of a karaf container. It doesn't validate that your + functionality works correctly, just that you have all of the dependent bundles + defined correctly. --> + <!-- <plugin> --> + <!-- <groupId>org.apache.maven.plugins</groupId> --> + <!-- <artifactId>maven-surefire-plugin</artifactId> --> + <!-- <version>2.16</version> --> + <!-- <configuration> --> + <!-- <systemPropertyVariables> --> + <!-- <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId> --> + <!-- <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId> --> + <!-- <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version> --> + <!-- </systemPropertyVariables> --> + <!-- <dependenciesToScan> --> + <!-- <dependency>org.opendaylight.yangtools:features-test</dependency> --> + <!-- </dependenciesToScan> --> + <!-- </configuration> --> + <!-- </plugin> --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-features/src/main/resources/features.xml b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-features/src/main/resources/features.xml new file mode 100644 index 000000000..e3fab488d --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-features/src/main/resources/features.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="appc-rest-adapter-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + + <repository>mvn:org.opendaylight.mdsal/features-mdsal/${features-mdsal.version}/xml/features</repository> + + <feature name='appc-rest-adapter' description="appc-rest-adapter" version='${project.version}'> + <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> + <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> + <feature>sdnc-sli</feature> + <bundle>mvn:org.openecomp.appc/appc-rest-adapter-bundle/${project.version}</bundle> + </feature> + +</features> diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-installer/.gitignore b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-installer/.gitignore new file mode 100644 index 000000000..731eb433c --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-installer/.gitignore @@ -0,0 +1,2 @@ +/target/ +/.settings/ diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-installer/pom.xml b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-installer/pom.xml new file mode 100644 index 000000000..26970bfc0 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-installer/pom.xml @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-rest-adapter</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>appc-rest-adapter-installer</artifactId> + <name>rest Adapter - Karaf Installer</name> + <packaging>pom</packaging> + + <properties> + <application.name>appc-rest-adapter</application.name> + <features.boot>appc-rest-adapter</features.boot> + <features.repositories>mvn:org.openecomp.appc/appc-rest-adapter-features/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-rest-adapter-features</artifactId> + <classifier>features</classifier> + <type>xml</type> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-rest-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>false</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>true</attach> + <finalName>${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <excludeGroupIds>org.opendaylight</excludeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals> + <!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-installer/src/assembly/assemble_installer_zip.xml b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..9fbaad8c5 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>adapter</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..1ac5a82bc --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,47 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>adapter</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + +</assembly> diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-installer/src/main/resources/scripts/install-feature.sh b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..1d769fada --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/appc-rest-adapter-installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,40 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +#!/bin/bash + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -n -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot} diff --git a/app-c/appc/appc-adapters/appc-rest-adapter/pom.xml b/app-c/appc/appc-adapters/appc-rest-adapter/pom.xml new file mode 100644 index 000000000..c98c6ccd9 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-rest-adapter/pom.xml @@ -0,0 +1,125 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-adapters</artifactId> + <version>1.0.0</version> + </parent> + + <artifactId>appc-rest-adapter</artifactId> + <name>rest Adaptor</name> + <description>Abstraction to connect to and utilize the services of cloud providers such as OpenStack or VMWare.</description> + <packaging>pom</packaging> + + <reporting> + <plugins> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <additionalDependencies> + <additionalDependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4</artifactId> + <version>${antlr.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4-runtime</artifactId> + <version>4.3</version> + </additionalDependency> + </additionalDependencies> + </configuration> + <reportSets> + <reportSet> + <reports> + <report>javadoc-no-fork</report> + <report>test-javadoc-no-fork</report> + </reports> + </reportSet> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jxr-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-changelog-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>dual-report</id> + <configuration> + <type>range</type> + <range>30</range> + </configuration> + <reports> + <report>changelog</report> + <report>file-activity</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>taglist-maven-plugin</artifactId> + <version>2.4</version> + </plugin> + </plugins> + </reporting> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-rest-adapter-features</artifactId> + <classifier>features</classifier> + <type>xml</type> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-rest-adapter-provider</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + + </dependencyManagement> + + <modules> + <module>appc-rest-adapter-bundle</module> + <module>appc-rest-adapter-features</module> + <module>appc-rest-adapter-installer</module> + </modules> +</project> diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-adapters/appc-ssh-adapter/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/pom.xml b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/pom.xml new file mode 100644 index 000000000..0a402669b --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/pom.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-ssh-adapter</artifactId> + <version>1.0.0</version> + </parent> + + <artifactId>appc-ssh-adapter-api</artifactId> + <packaging>bundle</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Export-Package>org.openecomp.appc.adapter.ssh</Export-Package> + <Embed-Dependency>!dblib-provider</Embed-Dependency> + </instructions> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <executions> + <execution> + <id>attach-javadocs</id> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/Constants.java b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/Constants.java new file mode 100644 index 000000000..9a160dbff --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/Constants.java @@ -0,0 +1,141 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.ssh; + +public class Constants { + + private Constants(){} + +// public static final String CONFIGURE_PATH = "/restconf/config/opendaylight-inventory:nodes/node/"; +// public static final String CONNECT_PATH = "/restconf/config/opendaylight-inventory:nodes/node/controller-config/yang-ext:mount/config:modules"; +// public static final String CHECK_CONNECTION_PATH = "/restconf/operational/opendaylight-inventory:nodes/node/"; +// public static final String DISCONNECT_PATH = "/restconf/config/opendaylight-inventory:nodes/node/controller-config/yang-ext:mount/config:modules/module/odl-sal-netconf-connector-cfg:sal-netconf-connector/"; +// +// public static final String CONTROLLER_IP = "127.0.0.1"; +// public static final int CONTROLLER_PORT = 8181; +// public static final String PROTOCOL = "http"; +// +// public static final String VF_LICENSE = "VF_LICENSE"; + + // tables and fields + public static final String NETCONF_SCHEMA = "sdnctl"; + public static final String SDNCTL_SCHEMA = "sdnctl"; + public static final String DEVICE_AUTHENTICATION_TABLE_NAME = "DEVICE_AUTHENTICATION"; + public static final String CONFIGFILES_TABLE_NAME = "CONFIGFILES"; + public static final String DEVICE_INTERFACE_LOG_TABLE_NAME = "DEVICE_INTERFACE_LOG"; + public static final String FILE_CONTENT_TABLE_FIELD_NAME = "FILE_CONTENT"; + public static final String FILE_NAME_TABLE_FIELD_NAME = "FILE_NAME"; + public static final String USER_NAME_TABLE_FIELD_NAME = "USER_NAME"; + public static final String PASSWORD_TABLE_FIELD_NAME = "PASSWORD"; + public static final String PORT_NUMBER_TABLE_FIELD_NAME = "PORT_NUMBER"; + public static final String VNF_TYPE_TABLE_FIELD_NAME = "VNF_TYPE"; + public static final String SERVICE_INSTANCE_ID_FIELD_NAME = "SERVICE_INSTANCE_ID"; + public static final String REQUEST_ID_FIELD_NAME = "REQUEST_ID"; + public static final String CREATION_DATE_FIELD_NAME = "CREATION_DATE"; + public static final String LOG_FIELD_NAME = "LOG"; + public static final String ASDC_ARTIFACTS_TABLE_NAME = "ASDC_ARTIFACTS"; + + // input fields names + public static final String PAYLOAD = "payload"; + + + public static final String PARAM_IN_connection_details = "connection-details"; + public static final String SKIP_EXECUTION_INSTALLER_BIN_FILE = "Skip-execution-installer-bin-file"; + public static final String SKIP_DEPLOY = "Skip-deploy"; + public static final String UPGRADE_VERSION = "upgrade-version"; + + //command to get number of UP hosts + public static final String STATE_COMMAND = "/opt/jnetx/skyfall-scp/asp-state.sh | grep -o UP | wc -l"; + public static final int STATE_COMMAND_RESULT = 18; + //commands to check FE hosts + public static final String FE_STATE_TRUE_TEST_COMMAND = "ssh -t -q fe1 /opt/omni/bin/swmml -e display-platform-status | grep -o TRUE | wc -l"; + public static final int FE_STATE_TRUE_TEST_RESULT = 22; + public static final String FE_STATE_FALSE_TEST_COMMAND = "ssh -t -q fe1 /opt/omni/bin/swmml -e display-platform-status | grep -o FALSE | wc -l"; + public static final int FE_STATE_FALSE_TEST_RESULT = 2; + public static final String FE_OPERATIONAL_TEST_COMMAND = "ssh -t -q fe1 /opt/omni/bin/swmml -e display-platform-status | grep -o 'NOT FULLY OPERATIONAL' | wc -l"; + public static final int FE_OPERATIONAL_TEST_RESULT = 2; + //rsync command + public static final String RSYNC_COMMAND = "yes n | /opt/jnetx/skyfall-scp/asp-rsync.sh --check | grep -o 'is active' | wc -l"; + public static final int RSYNC_COMMAND_RESULT = 9; + + public static final String PARAM_IN_TIMEOUT = "timeout"; + public static final String PARAM_IN_FILE_URL = "source-file-url"; + public static final String DOWNLOAD_COMMAND = "wget -N %s"; + + // pre-define jnetx VM names + public static final String[] VM_NAMES = {"fe1", "fe2", "be1", "be2", "be3", "be4", "be5", "smp1", "smp2"}; + + public static final String DEFAULT_DISK_SPACE = "10240000"; + public static final String DF_COMMAND_TEMPLATE = "ssh %s df | grep vda1 | grep -v grep | tr -s ' '|cut -d ' ' -f4"; + + public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; + + + // constants fo DG +// public static final String VNF_TYPE_FIELD_NAME = "org.openecomp.appc.vftype"; +// public static final String VNF_VERSION_FIELD_NAME = "org.openecomp.appc.vfversion"; +// public static final String VNF_RESOURCE_VERSION_FIELD_NAME = "org.openecomp.appc.resource-version"; +// public static final String TARGET_VNF_TYPE = "target-vnf-type"; +// public static final String FILE_CONTENT_FIELD_NAME = "file-content"; + public static final String CONNECTION_DETAILS_FIELD_NAME = "connection-details"; +// public static final String CONFIGURATION_FILE_FIELD_NAME = "configuration-file-name"; + public static final String VNF_HOST_IP_ADDRESS_FIELD_NAME = "vnf-host-ip-address"; +// public static final String UPGRADE_VERSION = "upgrade-version"; + public static final String DG_ERROR_FIELD_NAME = "org.openecomp.appc.dg.error"; +// public static final String RESOURCEKEY = "resourceKey"; +// public static final String REQ_ID_FIELD_NAME = "org.openecomp.appc.reqid"; +// public static final String API_VERSION_FIELD_NAME = "org.openecomp.appc.apiversion"; +// public static final String MODEL_ENTITLMENT_POOL_UUID_NAME = "model.entitlement.pool.uuid"; +// public static final String MODEL_LICENSE_KEY_UUID_NAME = "model.license.key.uuid"; +// public static final String ENTITLMENT_POOL_UUID_NAME = "entitlement.pool.uuid"; +// public static final String LICENSE_KEY_UUID_NAME = "license.key.uuid"; +// public static final String IS_ACQUIRE_LICENSE_REQUIRE ="is.acquire-license.require"; +// public static final String IS_RELEASE_LICENSE_REQUIRE ="is.release-license.require"; +// +// public static final String AAI_ENTITLMENT_POOL_UUID_NAME = "aai.input.data.entitlement-assignment-group-uuid"; +// public static final String AAI_LICENSE_KEY_UUID_NAME = "aai.input.data.license-assignment-group-uuid"; +// public static final String AAI_LICENSE_KEY_VALUE = "aai.input.data.license-key"; +// public static final String IS_AAI_ENTITLEMENT_UPDATE_REQUIRE = "is.aai-entitlement-update.require"; +// public static final String IS_AAI_LICENSE_UPDATE_REQUIRE = "is.aai-license-update.require"; +// public static final String IS_ACQUIRE_ENTITLEMENT_REQUIRE ="is.acquire-entitlement.require"; +// public static final String IS_RELEASE_ENTITLEMENT_REQUIRE ="is.release-entitlement.require"; +// +// public enum ASDC_ARTIFACTS_FIELDS { +// SERVICE_UUID, +// DISTRIBUTION_ID, +// SERVICE_NAME, +// SERVICE_DESCRIPTION, +// RESOURCE_UUID, +// RESOURCE_INSTANCE_NAME, +// RESOURCE_NAME, +// RESOURCE_VERSION, +// RESOURCE_TYPE, +// ARTIFACT_UUID, +// ARTIFACT_TYPE, +// ARTIFACT_VERSION, +// ARTIFACT_DESCRIPTION, +// INTERNAL_VERSION, +// CREATION_DATE, +// ARTIFACT_NAME, +// ARTIFACT_CONTENT +// } +} diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshAdapter.java b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshAdapter.java new file mode 100644 index 000000000..3d305877b --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshAdapter.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.ssh; + +/** + * Factory class for creating SshConnection instances. + */ +public interface SshAdapter { + + /** + * Creates instance of SshConnection. + * + * @param host remote host to open SSH connection to + * @param port remote SSH port + * @param username SSH connection user name + * @param password SSH connection password + * @return instance of SshConnection + */ + SshConnection getConnection(String host, int port, String username, String password); +} diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshConnection.java b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshConnection.java new file mode 100644 index 000000000..0b3275f5d --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshConnection.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.ssh; + +import java.io.OutputStream; + +/** + * Provides utility method(s) to call commands on remote host via SSH. + */ +public interface SshConnection { + + /** + * Connect to SSH server. + */ + void connect(); + + /** + * Disconnect from SSH server. + */ + void disconnect(); + + /** + * Exec remote command over SSH. Return command execution status. + * Command output is written to out or err stream. + * + * @param cmd command to execute + * @param out content of sysout will go to this stream + * @param err content of syserr will go to this stream + * @return command execution status + */ + int execCommand(String cmd, OutputStream out, OutputStream err); + + /** + * Exec remote command over SSH with pseudo-tty. Return command execution status. + * Command output is written to out stream only as pseudo-tty writes to one stream only. + * + * @param cmd command to execute + * @param out content of sysout will go to this stream + * @return command execution status + */ + int execCommandWithPty(String cmd, OutputStream out); + + /** + * Set the command execution timeout + * @param timeout time in milliseconds + */ + void setExecTimeout(long timeout); +} diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshConnectionDetails.java b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshConnectionDetails.java new file mode 100644 index 000000000..a1fa97422 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshConnectionDetails.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.ssh; + +/** + * Provides details required for connecting to device. + */ +public class SshConnectionDetails { + + private static int DEFAULT_PORT = 22; + + private String host; + private int port = DEFAULT_PORT; + private String username; + private String password; + + public SshConnectionDetails() { + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + +} diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshDataAccessException.java b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshDataAccessException.java new file mode 100644 index 000000000..2d7f8333d --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshDataAccessException.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.ssh; + + + +public class SshDataAccessException extends RuntimeException { + + private static final long serialVersionUID = -155423437162622414L; + + public SshDataAccessException(){ + } + + public SshDataAccessException(String message){ + super(message); + } + + public SshDataAccessException(Throwable cause){ + super(cause); + } + + public SshDataAccessException(String message , Throwable cause){ + super(message , cause); + } + +} diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshDataAccessService.java b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshDataAccessService.java new file mode 100644 index 000000000..2d8119899 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshDataAccessService.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.ssh; + +import org.openecomp.sdnc.sli.resource.dblib.DbLibService; + + +@SuppressWarnings("JavaDoc") +public interface SshDataAccessService { + + /** + * + * @param schema + */ + void setSchema(String schema); + + /** + *@param dbLibService + */ + void setDbLibService(DbLibService dbLibService); + + /** + * + * @param xmlID + * @return + * @throws SshDataAccessException + */ + String retrieveConfigFileName(String xmlID) throws SshDataAccessException; + + /** + * + * @param vnfType + * @param connectionDetails + * @return + * @throws SshException + */ + boolean retrieveConnectionDetails(String vnfType, SshConnectionDetails connectionDetails) throws SshDataAccessException; + +} diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshException.java b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshException.java new file mode 100644 index 000000000..7a0c1fb99 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshException.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.ssh; + +public class SshException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** + * Constructor with message. + * + * @param message exception message + */ + public SshException(String message) { + super(message); + } + + /** + * Constructor with message and cause exception. + * + * @param message exception message + * @param cause exception cause + */ + public SshException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-features/pom.xml b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-features/pom.xml new file mode 100644 index 000000000..39ac425d9 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-features/pom.xml @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <parent> + <artifactId>appc-ssh-adapter</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>appc-ssh-adapter-features</artifactId> + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-ssh-adapter-api</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-ssh-adapter-sshd</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-features/src/main/resources/features.xml b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-features/src/main/resources/features.xml new file mode 100644 index 000000000..6f565dc09 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-features/src/main/resources/features.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="appc-ssh-adapter-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + <feature name='appc-ssh-adapter' description="appc-ssh-adapter" version='${project.version}'> + <bundle>mvn:org.openecomp.appc/appc-ssh-adapter-api/${project.version}</bundle> + <bundle>mvn:org.openecomp.appc/appc-ssh-adapter-sshd/${project.version}</bundle> + </feature> +</features> diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/pom.xml b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/pom.xml new file mode 100644 index 000000000..54b7ea428 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/pom.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-ssh-adapter</artifactId> + <version>1.0.0</version> + </parent> + + <artifactId>appc-ssh-adapter-sshd</artifactId> + <packaging>bundle</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-ssh-adapter-api</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.sshd</groupId> + <artifactId>sshd-core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.att.eelf</groupId> + <artifactId>eelf-core</artifactId> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Export-Service>org.openecomp.appc.adapter.ssh.SshAdapter</Export-Service> + <Private-Package>org.openecomp.appc.adapter.ssh.impl.*</Private-Package> + <Import-Package>!org.apache.log,!org.apache.commons.logging,!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.jasypt.*,*</Import-Package> + <Embed-Dependency>!dblib-provider,appc-common,jasypt,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/java/org/openecomp/appc/adapter/ssh/sshd/SshAdapterSshd.java b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/java/org/openecomp/appc/adapter/ssh/sshd/SshAdapterSshd.java new file mode 100644 index 000000000..44a6fb4ce --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/java/org/openecomp/appc/adapter/ssh/sshd/SshAdapterSshd.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.ssh.sshd; + +import org.openecomp.appc.adapter.ssh.SshAdapter; +import org.openecomp.appc.adapter.ssh.SshConnection; + +public class SshAdapterSshd implements SshAdapter { + + @Override + public SshConnection getConnection(String host, int port, String username, String password) { + return new SshConnectionSshd(host, port, username, password); + } +} diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/java/org/openecomp/appc/adapter/ssh/sshd/SshConnectionSshd.java b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/java/org/openecomp/appc/adapter/ssh/sshd/SshConnectionSshd.java new file mode 100644 index 000000000..4d8b83b6f --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/java/org/openecomp/appc/adapter/ssh/sshd/SshConnectionSshd.java @@ -0,0 +1,172 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.ssh.sshd; + +import org.apache.sshd.ClientChannel; +import org.apache.sshd.ClientSession; +import org.apache.sshd.SshClient; +import org.apache.sshd.client.channel.ChannelExec; +import org.apache.sshd.client.future.AuthFuture; +import org.apache.sshd.client.future.OpenFuture; +import org.apache.sshd.common.KeyPairProvider; +import org.apache.sshd.common.keyprovider.FileKeyPairProvider; +import org.openecomp.appc.adapter.ssh.SshConnection; +import org.openecomp.appc.adapter.ssh.SshException; +import org.openecomp.appc.encryption.EncryptionTool; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import java.io.OutputStream; +import java.security.KeyPair; + +/** + * Implementation of SshConnection interface based on Apache MINA SSHD library. + */ +class SshConnectionSshd implements SshConnection { + + private static final EELFLogger logger = EELFManager.getInstance().getApplicationLogger(); + + private static final long AUTH_TIMEOUT = 60000; + private static final long EXEC_TIMEOUT = 120000; + + private String host; + private int port; + private String username; + private String password; + private long timeout = EXEC_TIMEOUT; + private String keyFile; + private SshClient sshClient; + private ClientSession clientSession; + + public SshConnectionSshd(String host, int port, String username, String password, String keyFile) { + this.host = host; + this.port = port; + this.username = username; + this.password = password; + this.keyFile = keyFile; + } + + public SshConnectionSshd(String host, int port, String username, String password) { + this(host, port, username, password, null); + } + + public SshConnectionSshd(String host, int port, String keyFile) { + this(host, port, null, null, keyFile); + } + + @Override + public void connect() { + sshClient = SshClient.setUpDefaultClient(); + sshClient.start(); + try { + clientSession = sshClient.connect(EncryptionTool.getInstance().decrypt(username), host, port).await().getSession(); + if(password != null) { + clientSession.addPasswordIdentity(EncryptionTool.getInstance().decrypt(password)); + } + if(keyFile != null) { + KeyPairProvider keyPairProvider = new FileKeyPairProvider(new String[]{keyFile}); + KeyPair keyPair = keyPairProvider.loadKeys().iterator().next(); + clientSession.addPublicKeyIdentity(keyPair); + } + AuthFuture authFuture = clientSession.auth(); + authFuture.await(AUTH_TIMEOUT); + if(!authFuture.isSuccess()) { + throw new SshException("Error establishing ssh connection to [" + username + "@" + host + ":" + port + "]. Authentication failed."); + } + } catch(RuntimeException e) { + throw e; + } catch(Exception e) { + throw new SshException("Error establishing ssh connection to [" + username + "@" + host + ":" + port + "].", e); + } + if(logger.isDebugEnabled()) { + logger.debug("SSH: connected to [" + toString() + "]"); + } + } + + @Override + public void disconnect() { + try { + if(logger.isDebugEnabled()) { + logger.debug("SSH: disconnecting from [" + toString() + "]"); + } + clientSession.close(false); + } finally { + if(sshClient != null) { + sshClient.stop(); + } + } + } + + @Override + public void setExecTimeout(long timeout) { + this.timeout = timeout; + } + + @Override + public int execCommand(String cmd, OutputStream out, OutputStream err) { + return execCommand(cmd, out, err, false); + } + + @Override + public int execCommandWithPty(String cmd, OutputStream out) { + return execCommand(cmd, out, out, true); + } + + private int execCommand(String cmd, OutputStream out, OutputStream err, boolean usePty) { + try { + if(logger.isDebugEnabled()) { + logger.debug("SSH: executing command"); + } + ChannelExec client = clientSession.createExecChannel(cmd); + client.setUsePty(usePty); // use pseudo-tty? + client.setOut(out); + client.setErr(err); + OpenFuture openFuture = client.open(); + int exitStatus = 0; + try { + client.waitFor(ClientChannel.CLOSED, timeout); + openFuture.verify(); + Integer exitStatusI = client.getExitStatus(); + if(exitStatusI == null) { + throw new SshException("Error executing command [" + cmd + "] over SSH [" + username + "@" + host + ":" + port + "]. Operation timed out."); + } + exitStatus = exitStatusI; + } finally { + client.close(false); + } + return exitStatus; + } catch(RuntimeException e) { + throw e; + } catch(Exception t) { + throw new SshException("Error executing command [" + cmd + "] over SSH [" + username + "@" + host + ":" + port + "]", t); + } + } + + @Override + public String toString() { + String address = host; + if(username != null) { + address = username + '@' +address; + } + return address; + } +} diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/java/org/openecomp/appc/adapter/ssh/sshd/SshdDataAccessService.java b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/java/org/openecomp/appc/adapter/ssh/sshd/SshdDataAccessService.java new file mode 100644 index 000000000..a12e2be93 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/java/org/openecomp/appc/adapter/ssh/sshd/SshdDataAccessService.java @@ -0,0 +1,106 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.ssh.sshd; + +import javax.sql.rowset.CachedRowSet; + +import org.openecomp.appc.adapter.ssh.Constants; +import org.openecomp.appc.adapter.ssh.SshConnectionDetails; +import org.openecomp.appc.adapter.ssh.SshDataAccessException; +import org.openecomp.appc.adapter.ssh.SshDataAccessService; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.resource.dblib.DbLibService; + +import java.sql.SQLException; +import java.util.ArrayList; + + + +public class SshdDataAccessService implements SshDataAccessService { + + private String schema = Constants.NETCONF_SCHEMA; + private DbLibService dbLibService; + + @Override + public void setSchema(String schema) { + this.schema = schema; + } + + @Override + public void setDbLibService(DbLibService dbLibService) { + this.dbLibService = dbLibService; + } + + @Override + public boolean retrieveConnectionDetails(String vnfType, SshConnectionDetails connectionDetails) throws SshDataAccessException { + + boolean recordFound = false; + + String queryString = "select " + Constants.USER_NAME_TABLE_FIELD_NAME + "," + Constants.PASSWORD_TABLE_FIELD_NAME + "," + Constants.PORT_NUMBER_TABLE_FIELD_NAME + " " + + "from " + Constants.DEVICE_AUTHENTICATION_TABLE_NAME + " " + + "where " + Constants.VNF_TYPE_TABLE_FIELD_NAME + " = ?"; + + ArrayList<String> argList = new ArrayList<>(); + argList.add(vnfType); + + try { + + final CachedRowSet data = dbLibService.getData(queryString, argList, schema); + if (data.first()) { + recordFound = true; + connectionDetails.setUsername(data.getString(Constants.USER_NAME_TABLE_FIELD_NAME)); + connectionDetails.setPassword(data.getString(Constants.PASSWORD_TABLE_FIELD_NAME)); + connectionDetails.setPort(data.getInt(Constants.PORT_NUMBER_TABLE_FIELD_NAME)); + } + + } catch (SQLException e) { + throw new SshDataAccessException(e); + } + + return recordFound; + } + + @Override + public String retrieveConfigFileName(String xmlID) throws SshDataAccessException { + String fileContent; + + String queryString = "select " + Constants.FILE_CONTENT_TABLE_FIELD_NAME + " " + + "from " + Constants.CONFIGFILES_TABLE_NAME + " " + + "where " + Constants.FILE_NAME_TABLE_FIELD_NAME + " = ?"; + + ArrayList<String> argList = new ArrayList<>(); + argList.add(xmlID); + + try { + + final CachedRowSet data = dbLibService.getData(queryString, argList, schema); + fileContent = data.getString(Constants.FILE_CONTENT_TABLE_FIELD_NAME); + + } catch (SQLException e) { + throw new SshDataAccessException(e); + } + + return fileContent; + } + + +} diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..f9d10868a --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + + <bean id="sshdBean" class="org.openecomp.appc.adapter.ssh.sshd.SshAdapterSshd" scope="singleton"/> + <service id="sshAdapter" interface="org.openecomp.appc.adapter.ssh.SshAdapter" ref="sshdBean"/> + + <reference id="dbLibServiceRef" availability="mandatory" activation="eager" interface="org.openecomp.sdnc.sli.resource.dblib.DbLibService" /> + <bean id="sshdDAServiceBean" class="org.openecomp.appc.adapter.ssh.sshd.SshdDataAccessService" scope="singleton"> + <property name="dbLibService" ref="dbLibServiceRef" /> + </bean> + + <service id="sshDAService" interface="org.openecomp.appc.adapter.ssh.SshDataAccessService" ref="sshdDAServiceBean"/> + +</blueprint> diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/test/java/org/openecomp/appc/adapter/ssh/sshd/SshAdapterSample.java b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/test/java/org/openecomp/appc/adapter/ssh/sshd/SshAdapterSample.java new file mode 100644 index 000000000..197915de8 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/test/java/org/openecomp/appc/adapter/ssh/sshd/SshAdapterSample.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.ssh.sshd; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; + +import org.openecomp.appc.adapter.ssh.SshAdapter; +import org.openecomp.appc.adapter.ssh.SshConnection; +import org.openecomp.appc.adapter.ssh.sshd.SshAdapterSshd; + +public class SshAdapterSample { + + public static void main(String[] args) { + String host = "hostname"; + int port = 22; + String username = "user"; + String password = "secret"; + String command = "ls"; + + SshAdapter sshAdapter = new SshAdapterSshd(); + SshConnection sshConnection = sshAdapter.getConnection(host, port, username, password); + sshConnection.connect(); + try { + OutputStream stdout = new ByteArrayOutputStream(); + OutputStream stderr = new ByteArrayOutputStream(); + int status = sshConnection.execCommand(command, stdout, stderr); + if(status == 0) { + System.out.println("Command executed successfully. Output:\n" + stdout.toString()); + } else { + System.err.println("Command returned status " + status + ". Error:\n" + stderr.toString()); + } + } finally { + sshConnection.disconnect(); + } + } +} diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/test/java/org/openecomp/appc/adapter/ssh/sshd/SshAdapterTest.java b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/test/java/org/openecomp/appc/adapter/ssh/sshd/SshAdapterTest.java new file mode 100644 index 000000000..1d7d06df2 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/test/java/org/openecomp/appc/adapter/ssh/sshd/SshAdapterTest.java @@ -0,0 +1,247 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.ssh.sshd; + +import org.apache.sshd.SshServer; +import org.apache.sshd.common.NamedFactory; +import org.apache.sshd.common.util.OsUtils; +import org.apache.sshd.server.Command; +import org.apache.sshd.server.CommandFactory; +import org.apache.sshd.server.PasswordAuthenticator; +import org.apache.sshd.server.PublickeyAuthenticator; +import org.apache.sshd.server.command.ScpCommandFactory; +import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider; +import org.apache.sshd.server.session.ServerSession; +import org.apache.sshd.server.sftp.SftpSubsystem; +import org.apache.sshd.server.shell.ProcessShellFactory; +import org.hamcrest.CoreMatchers; +import org.junit.*; +import org.junit.rules.ExpectedException; +import org.openecomp.appc.adapter.ssh.SshAdapter; +import org.openecomp.appc.adapter.ssh.SshConnection; +import org.openecomp.appc.adapter.ssh.SshException; +import org.openecomp.appc.adapter.ssh.sshd.SshAdapterSshd; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.BindException; +import java.security.PublicKey; +import java.util.Collections; +import java.util.EnumSet; + +public class SshAdapterTest { + + private static final boolean START_SERVER = true; + private static final String SSH_HOST = "localhost"; + private static final int SSH_PORT = 2222; + private static final String SSH_USERNAME = "test"; + private static final String SSH_PASSWORD = "test"; + private static final String F_TEST_CMD = "ping -%c 4 %s"; + + private int sshPort = SSH_PORT; + private SshServer sshd; + private SshAdapter sshAdapter = new SshAdapterSshd(); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testExecute() { + String cmd = String.format(F_TEST_CMD, OsUtils.isUNIX() ? 'c' : 'n', "localhost"); + SshConnection sshConnection = connect(SSH_USERNAME, SSH_PASSWORD); + try { + System.out.println("SSH client connected. Server port [" + sshPort + "]. [" + getClass().getName() + "#" + System.identityHashCode(this) + "]"); + ByteArrayOutputStream stdout = new ByteArrayOutputStream(); + ByteArrayOutputStream stderr = new ByteArrayOutputStream(); + int status = execCmd(sshConnection, cmd, stdout, stderr, false); + Assert.assertEquals(stdout.toString() + ". " + stderr.toString(), 0, status); + } finally { + disconnect(sshConnection); + } + } + + @Test + public void testExecuteWithPty() { + String cmd = String.format(F_TEST_CMD, OsUtils.isUNIX() ? 'c' : 'n', "localhost"); + SshConnection sshConnection = connect(SSH_USERNAME, SSH_PASSWORD); + try { + System.out.println("SSH client connected. Server port [" + sshPort + "]. [" + getClass().getName() + "#" + System.identityHashCode(this) + "]"); + ByteArrayOutputStream stdout = new ByteArrayOutputStream(); + int status = execCmd(sshConnection, cmd, stdout, null, true); + Assert.assertEquals(stdout.toString() + ". " + stdout.toString(), 0, status); + } finally { + disconnect(sshConnection); + } + } + + @Test + public void testExecuteInvalidCommand() { + String cmd = String.format(F_TEST_CMD, OsUtils.isUNIX() ? 'c' : 'n', "nosuchhost"); + SshConnection sshConnection = connect(SSH_USERNAME, SSH_PASSWORD); + try { + ByteArrayOutputStream stdout = new ByteArrayOutputStream(); + ByteArrayOutputStream stderr = new ByteArrayOutputStream(); + int status = execCmd(sshConnection, cmd, stdout, stderr, false); + Assert.assertNotEquals(stdout.toString() + ". " + stderr.toString(), 0, status); + } finally { + disconnect(sshConnection); + } + } + + @Test + public void testWrongUsername() { + thrown.expect(SshException.class); + thrown.expectMessage(CoreMatchers.containsString("Authentication failed")); + disconnect(connect("WrongUsername", SSH_PASSWORD)); + } + + @Test + public void testWrongPassword() { + thrown.expect(SshException.class); + thrown.expectMessage(CoreMatchers.containsString("Authentication failed")); + disconnect(connect(SSH_USERNAME, "WrongPassword")); + } + + @Before + public void beforeTest() throws IOException { + if (START_SERVER) { + startServer(); + } + } + + @After + public void afterTest() throws InterruptedException { + stopServer(); + } + + private SshConnection connect(String username, String password) { + SshConnection sshConnection = sshAdapter.getConnection(SSH_HOST, sshPort, username, password); + sshConnection.connect(); + System.out.println("SSH client connected. Server port [" + sshPort + "]. [" + getClass().getName() + "#" + System.identityHashCode(this) + "]"); + return sshConnection; + } + + private void disconnect(SshConnection sshConnection) { + sshConnection.disconnect(); + System.out.println("SSH client disconnected. Server port [" + sshPort + "]. [" + getClass().getName() + "#" + System.identityHashCode(this) + "]"); + } + + private int execCmd(SshConnection sshConnection, String cmd, OutputStream stdout, OutputStream stderr, boolean usePty) { + System.out.println("=> Running command [" + cmd + "] over SSH"); + int status; + if (usePty) { + status = sshConnection.execCommandWithPty(cmd, stdout); + } else { + status = sshConnection.execCommand(cmd, stdout, stderr); + } + System.out.println("=> Command [" + cmd + "] status is [" + status + "], stdout is [" + String.valueOf(stdout) + "], stderr is [" + String.valueOf(stderr) + "]"); + return status; + } + + private void startServer() throws IOException { + sshd = SshServer.setUpDefaultServer(); + sshd.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(new SftpSubsystem.Factory())); + sshd.setCommandFactory(new ScpCommandFactory(new CommandFactory() { + + public Command createCommand(String command) { + EnumSet<ProcessShellFactory.TtyOptions> ttyOptions; + if (OsUtils.isUNIX()) { + ttyOptions = EnumSet.of(ProcessShellFactory.TtyOptions.ONlCr); + } else { + ttyOptions = EnumSet.of(ProcessShellFactory.TtyOptions.Echo, ProcessShellFactory.TtyOptions.ICrNl, ProcessShellFactory.TtyOptions.ONlCr); + } + return new ProcessShellFactory(command.split(" "), ttyOptions).create(); + } + })); + if (OsUtils.isUNIX()) { + sshd.setShellFactory(new ProcessShellFactory(new String[]{"/bin/sh", "-i", "-l"}, + EnumSet.of(ProcessShellFactory.TtyOptions.ONlCr))); + } else { + sshd.setShellFactory(new ProcessShellFactory(new String[]{"cmd.exe "}, + EnumSet.of(ProcessShellFactory.TtyOptions.Echo, ProcessShellFactory.TtyOptions.ICrNl, ProcessShellFactory.TtyOptions.ONlCr))); + } +// if(SecurityUtils.isBouncyCastleRegistered()) { +// sshd.setKeyPairProvider(new PEMGeneratorHostKeyProvider(System.getProperty("java.io.tmpdir") + "/key.pem")); +// } else { + sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(System.getProperty("java.io.tmpdir") + "/key.ser")); +// } + sshd.setPasswordAuthenticator(new PasswordAuthenticator() { + + @Override + public boolean authenticate(String username, String password, ServerSession session) { + return (SSH_USERNAME.equals(username) && SSH_PASSWORD.equals(password)); + } + }); + sshd.setPublickeyAuthenticator(new PublickeyAuthenticator() { + + public boolean authenticate(String username, PublicKey key, ServerSession session) { + return true; + } + }); + sshd.getProperties().put(SshServer.WELCOME_BANNER, "Welcome to SSHD\n"); + startServer0(); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // ignore + } + } + + private void startServer0() throws IOException { + boolean serverStarted = false; + IOException exception = null; + while (!serverStarted && (sshPort < Integer.MAX_VALUE)) { + try { + System.out.println("Starting SSH server on port [" + sshPort + "]. [" + getClass().getName() + "#" + System.identityHashCode(this) + "]"); + sshd.setPort(sshPort); + sshd.start(); + serverStarted = true; + } catch (BindException e) { + System.err.println("Cannot start SSH server on port [" + sshPort + "]. " + e.getMessage()); + if (exception == null) { + // store first thrown exception - will be thrown if cannot start the server + exception = e; + } + sshPort++; + } + } + if (!serverStarted) { + throw exception; + } + System.out.println("SSH server started on port [" + sshPort + "]. [" + getClass().getName() + "#" + System.identityHashCode(this) + "]"); + } + + private void stopServer() { + try { + if (sshd != null) { + sshd.stop(true); + System.out.println("SSH server stopped on port [" + sshPort + "]. [" + getClass().getName() + "#" + System.identityHashCode(this) + "]"); + } + } catch (InterruptedException e) { + System.err.println("=> Error stopping SSH server."); + e.printStackTrace(); + } finally { + sshd = null; + } + } +} diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/pom.xml b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/pom.xml new file mode 100644 index 000000000..0c66afd21 --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/pom.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-ssh-adapter</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-ssh-adapter-tests</artifactId> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-ssh-adapter-api</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/src/main/java/org/openecomp/appc/adapter/ssh/SshAdapterMock.java b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/src/main/java/org/openecomp/appc/adapter/ssh/SshAdapterMock.java new file mode 100644 index 000000000..c0ccdfaee --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/src/main/java/org/openecomp/appc/adapter/ssh/SshAdapterMock.java @@ -0,0 +1,75 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.ssh; + +import java.util.ArrayList; +import java.util.List; + +import org.openecomp.appc.adapter.ssh.SshAdapter; +import org.openecomp.appc.adapter.ssh.SshConnection; + +public class SshAdapterMock implements SshAdapter { + + private List<SshConnectionMock> connectionMocks = new ArrayList<>(); + + private int returnStatus; + private String returnStdout; + private String returnStderr; + + @Override + public SshConnection getConnection(String host, int port, String username, String password) { + SshConnectionMock sshConnectionMock = new SshConnectionMock(host, port, username, password); + sshConnectionMock.setReturnStatus(returnStatus); + sshConnectionMock.setReturnStdout(returnStdout); + sshConnectionMock.setReturnStderr(returnStderr); + connectionMocks.add(sshConnectionMock); + return sshConnectionMock; + } + + public List<SshConnectionMock> getConnectionMocks() { + return connectionMocks; + } + + public int getReturnStatus() { + return returnStatus; + } + + public void setReturnStatus(int returnStatus) { + this.returnStatus = returnStatus; + } + + public String getReturnStdout() { + return returnStdout; + } + + public void setReturnStdout(String returnStdout) { + this.returnStdout = returnStdout; + } + + public String getReturnStderr() { + return returnStderr; + } + + public void setReturnStderr(String returnStderr) { + this.returnStderr = returnStderr; + } +} diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/src/main/java/org/openecomp/appc/adapter/ssh/SshConnectionMock.java b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/src/main/java/org/openecomp/appc/adapter/ssh/SshConnectionMock.java new file mode 100644 index 000000000..3194edcfb --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/src/main/java/org/openecomp/appc/adapter/ssh/SshConnectionMock.java @@ -0,0 +1,155 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.adapter.ssh; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import org.openecomp.appc.adapter.ssh.SshConnection; + +public class SshConnectionMock implements SshConnection { + + private static final int DEF_SUCCESS_STATUS = 0; + + private String host; + private int port; + private String username; + private String password; + private long timeout; + + private int returnStatus = DEF_SUCCESS_STATUS; + private String returnStdout; + private String returnStderr; + + private int connectCallCount = 0; + private int disconnectCallCount = 0; + private List<String> executedCommands = new ArrayList<>(); + + public SshConnectionMock(String host, int port, String username, String password) { + this.host = host; + this.port = port; + this.username = username; + this.password = password; + } + + @Override + public void connect() { + connectCallCount++; + } + + @Override + public void disconnect() { + disconnectCallCount++; + } + + @Override + public int execCommand(String cmd, OutputStream out, OutputStream err) { + return execCommand(cmd, out, err, false); + } + + @Override + public int execCommandWithPty(String cmd, OutputStream out) { + return execCommand(cmd, out, out, true); + } + + private int execCommand(String cmd, OutputStream out, OutputStream err, boolean usePty) { + executedCommands.add(cmd); + try { + if((out != null) && (returnStdout != null)) { + out.write(returnStdout.getBytes()); + } + } catch(IOException e) { + throw new RuntimeException("Error writing to stdout output stream", e); + } + try { + if((err != null) && (returnStderr != null)) { + err.write(returnStderr.getBytes()); + } + } catch(IOException e) { + throw new RuntimeException("Error writing to stderr output stream", e); + } + return returnStatus; + } + + @Override + public void setExecTimeout(long timeout) { + this.timeout = timeout; + } + + public long getExecTimeout() { + return timeout; + } + + public String getHost() { + return host; + } + + public int getPort() { + return port; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public int getConnectCallCount() { + return connectCallCount; + } + + public int getDisconnectCallCount() { + return disconnectCallCount; + } + + public List<String> getExecutedCommands() { + return executedCommands; + } + + public int getReturnStatus() { + return returnStatus; + } + + public void setReturnStatus(int returnStatus) { + this.returnStatus = returnStatus; + } + + public String getReturnStdout() { + return returnStdout; + } + + public void setReturnStdout(String returnStdout) { + this.returnStdout = returnStdout; + } + + public String getReturnStderr() { + return returnStderr; + } + + public void setReturnStderr(String returnStderr) { + this.returnStderr = returnStderr; + } +} diff --git a/app-c/appc/appc-adapters/appc-ssh-adapter/pom.xml b/app-c/appc/appc-adapters/appc-ssh-adapter/pom.xml new file mode 100644 index 000000000..af3d503fc --- /dev/null +++ b/app-c/appc/appc-adapters/appc-ssh-adapter/pom.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <parent> + <artifactId>appc-adapters</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>appc-ssh-adapter</artifactId> + <packaging>pom</packaging> + + <modules> + <module>appc-ssh-adapter-api</module> + <module>appc-ssh-adapter-tests</module> + <module>appc-ssh-adapter-sshd</module> + <module>appc-ssh-adapter-features</module> + </modules> +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-adapters/pom.xml b/app-c/appc/appc-adapters/pom.xml new file mode 100644 index 000000000..67ee81bfc --- /dev/null +++ b/app-c/appc/appc-adapters/pom.xml @@ -0,0 +1,21 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-adapters</artifactId> + <name>APPC Adapters</name> + <description>Adapter bundles for app-c</description> + <packaging>pom</packaging> + + <modules> + <module>appc-chef-adapter</module> + <module>appc-rest-adapter</module> + <module>appc-iaas-adapter</module> + <module>appc-dmaap-adapter</module> + <module>appc-netconf-adapter</module> + <module>appc-ssh-adapter</module> + </modules> +</project> diff --git a/app-c/appc/appc-asdc-listener/.gitignore b/app-c/appc/appc-asdc-listener/.gitignore new file mode 100644 index 000000000..c82c130d9 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/.gitignore @@ -0,0 +1,21 @@ +# Target dirs in all projects +**/target/* + +# Generated models and features +/model/bin/* +/features/bin/* + +# MANIFEST.MF is updated on every clean install +MANIFEST.MF + +# Karaf Assembly + + +*.prefs +.classpath +.project +/.settings/ + +logs/ +debug-logs/ +/target/ diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/.gitignore b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/.gitignore new file mode 100644 index 000000000..09e3bc9b2 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/etc/asdc-client.jks b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/etc/asdc-client.jks Binary files differnew file mode 100644 index 000000000..eb0a0d35a --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/etc/asdc-client.jks diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/etc/asdcclientstore.jks b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/etc/asdcclientstore.jks Binary files differnew file mode 100644 index 000000000..5dc006db0 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/etc/asdcclientstore.jks diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/log4j.properties b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/log4j.properties new file mode 100644 index 000000000..abdf8675a --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/log4j.properties @@ -0,0 +1,17 @@ +log4j.rootCategory=DEBUG, CONSOLE, LOGFILE + +log4j.logger.com.att=TRACE, CONSOLE, LOGFILE + +# CONSOLE is set to be a ConsoleAppender using a PatternLayout. +log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender +log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout +log4j.appender.CONSOLE.layout.ConversionPattern=%p %d{yyyy-MM-dd HH:mm:ss.SSS Z} %c{1} - %m%n + +# LOGFILE is set to be a File appender using a PatternLayout. +log4j.appender.LOGFILE=org.apache.log4j.RollingFileAppender +log4j.appender.LOGFILE.File=logs/wordnik.log +log4j.appender.LOGFILE.Append=true +log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout +log4j.appender.LOGFILE.layout.ConversionPattern=%p %d{yyyy-MM-dd HH:mm:ss.SSS Z} %c{1} - %m%n +log4j.appender.LOGFILE.MaxFileSize=10MB +log4j.appender.LOGFILE.MaxBackupIndex=10 diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/pom.xml b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/pom.xml new file mode 100644 index 000000000..666456446 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/pom.xml @@ -0,0 +1,175 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <artifactId>appc-asdc-listener</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + + <properties> + <snakeyaml.version>1.12</snakeyaml.version> + </properties> + + <artifactId>appc-asdc-listener-bundle</artifactId> + <packaging>bundle</packaging> + + <dependencies> + + <dependency> + <groupId>equinoxSDK381</groupId> + <artifactId>org.eclipse.osgi</artifactId> + </dependency> + + <dependency> + <groupId>org.json</groupId> + <artifactId>json</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.openecomp.sdc</groupId> + <artifactId>sdc-distribution-client</artifactId> + <version>1.1.2</version> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dmaap-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.yaml</groupId> + <artifactId>snakeyaml</artifactId> + <version>${snakeyaml.version}</version> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>com.att.eelf</groupId> + <artifactId>eelf-core</artifactId> + </dependency> + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-core</artifactId> + </dependency> + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + </dependency> + <dependency> + <groupId>com.att.nsa</groupId> + <artifactId>saClientLibrary</artifactId> + </dependency> + <dependency> + <groupId>com.att.nsa</groupId> + <artifactId>cambriaClient</artifactId> + </dependency> + <dependency> + <groupId>org.functionaljava</groupId> + <artifactId>functionaljava</artifactId> + <version>4.2</version> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore</artifactId> + <version>4.4.1</version> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>4.4.1</version> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-license-manager-api</artifactId> + <!-- <version>${project.version}</version> --> + <version>1.0.0</version> + </dependency> + + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + </dependency> + </dependencies> + + + <build> + <plugins> + + <!-- ================================================== --> + <!-- Set the JDK compiler version. --> + <!-- ================================================== --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <!-- <inherited>true</inherited> --> + <configuration> + <source>1.7</source> + <target>1.7</target> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>org.openecomp.appc.sdc.listener</Bundle-SymbolicName> + <!--Bundle-Activator>org.openecomp.appc.sdc.listener.AppcAsdcListenerActivator</Bundle-Activator --> + <Export-Package>org.openecomp.appc.sdc.listener</Export-Package> + <Import-Package> + org.openecomp.appc.licmgr, + org.openecomp.appc.adapter.dmaap, + !ch.qos.*, + !com.att.*, + !fj.*, + !groovy.lang, + !javax.jms, + !javax.mail.*, + !org.apache.log4j.*, + !org.codehaus.commons.compiler, + !org.codehaus.groovy.*, + !org.codehaus.janino, + !org.jasypt.*, + !org.yaml.snakeyaml.*, + !com.ibm.icu.text, + !org.apache.log, + !com.sun.faces.spi, + * + </Import-Package> + <Embed-Dependency> + sdc-distribution-client, appc-common, + appc-dmaap-adapter-bundle, appc-license-manager-api, + snakeyaml, + logback-core, + logback-classic, eelf-core, + saClientLibrary, + cambriaClient, + functionaljava, + httpcore,httpclient, + gson;scope=compile|runtime;inline=false + </Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcCallback.java b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcCallback.java new file mode 100644 index 000000000..651ea282c --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcCallback.java @@ -0,0 +1,121 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.sdc.listener; + +import java.net.URI; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.commons.lang3.concurrent.BasicThreadFactory; +import org.openecomp.appc.adapter.dmaap.EventSender; + +import org.openecomp.sdc.api.IDistributionClient; +import org.openecomp.sdc.api.consumer.INotificationCallback; +import org.openecomp.sdc.api.notification.IArtifactInfo; +import org.openecomp.sdc.api.notification.INotificationData; +import org.openecomp.sdc.api.notification.IResourceInstance; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +public class AsdcCallback implements INotificationCallback { + + private final EELFLogger logger = EELFManager.getInstance().getLogger(AsdcCallback.class); + + private URI storeUri; + private IDistributionClient client; + + private EventSender eventSender = null; + + private ThreadPoolExecutor executor; + private int threadCount = 10; + + private AtomicBoolean isRunning = new AtomicBoolean(false); + + + public AsdcCallback(URI storeUri, IDistributionClient client) { + this.storeUri = storeUri; + this.client = client; + + // Create the thread pool + executor = new ThreadPoolExecutor(threadCount, threadCount, 1, TimeUnit.SECONDS, + new ArrayBlockingQueue<Runnable>(threadCount * 2)); + + // Custom Named thread factory + BasicThreadFactory threadFactory = new BasicThreadFactory.Builder().namingPattern("Appc-Listener-%d").build(); + executor.setThreadFactory(threadFactory); + + isRunning.set(true); + } + + @Override + public void activateCallback(INotificationData data) { + if (null == eventSender) { + try { + BundleContext bctx = FrameworkUtil.getBundle(EventSender.class).getBundleContext(); + ServiceReference sref = bctx.getServiceReference(EventSender.class); + eventSender = (EventSender) bctx.getService(sref); + } catch (Throwable t) { + logger.error("AsdcCallback failed on initializing EventSender", t); + } + } + + if (isRunning.get()) { + for (IResourceInstance resource : data.getResources()) { + for (IArtifactInfo artifact : resource.getArtifacts()) { + logger.info(Util.toAsdcStoreDocumentInput(data, resource, artifact, "abc")); + if (executor.getQueue().size() >= threadCount) { + // log warning about job backlog + } + executor.submit(new DownloadAndStoreOp(client, eventSender, data, resource, artifact, storeUri)); + } + } + } else { + // TODO - return a failed result so asdc knows we are shut down + } + } + + public void stop() { + stop(10); + } + + public void stop(int waitSec) { + isRunning.set(false); + logger.info(String.format("Stopping the ASDC listener and waiting up to %ds for %d pending jobs", waitSec, + executor.getQueue().size())); + boolean cleanShutdown = false; + executor.shutdown(); + try { + cleanShutdown = executor.awaitTermination(waitSec, TimeUnit.SECONDS); + executor.shutdownNow(); // In case of timeout + } catch (InterruptedException e) { + e.printStackTrace(); + } + logger.info(String.format("Attempting to shutdown cleanly: %s", cleanShutdown ? "SUCCESS" : "FAILURE")); + logger.info("Shutdown complete."); + } + +} diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcConfig.java b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcConfig.java new file mode 100644 index 000000000..e73b90695 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcConfig.java @@ -0,0 +1,182 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.sdc.listener; + +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.openecomp.sdc.api.consumer.IConfiguration; +import org.openecomp.sdc.utils.ArtifactTypeEnum; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +public class AsdcConfig implements IConfiguration { + + private String host; + private String consumer; + private String consumerId; + private String env; + private String keystorePath; + private String keystorePass; + private int pollingInterval; // Time between listening sessions + private int pollingTimeout; // Time to listen for (dmaap timeout url param)/1000 + private List<String> types = new ArrayList<>(1); + private String user; + private String pass; + + private URI storeOp; + + Properties props; + + private final EELFLogger logger = EELFManager.getInstance().getLogger(AsdcConfig.class); + + public AsdcConfig(Properties props) throws Exception { + this.props = props; + init(); + } + + private void init() throws Exception { + if (props != null) { + // Keystore for ca cert + keystorePath = props.getProperty("appc.asdc.keystore.path"); + keystorePass = props.getProperty("appc.asdc.keystore.pass"); + + // ASDC host + host = props.getProperty("appc.asdc.host"); + env = props.getProperty("appc.asdc.env"); + user = props.getProperty("appc.asdc.user"); + pass = props.getProperty("appc.asdc.pass"); + + // DMaaP properties + consumer = props.getProperty("appc.asdc.consumer"); + consumerId = props.getProperty("appc.asdc.consumer.id"); + + pollingInterval = Integer.valueOf(props.getProperty("interval", "60")); + + // Client uses cambriaClient-0.2.4 which throws non relevant (wrong) + // exceptions with times > 30s + pollingTimeout = Integer.valueOf(props.getProperty("timeout", "25")); + + // Anything less than 60 and we risk 429 Too Many Requests + if (pollingInterval < 60) { + pollingInterval = 60; + } + + if (pollingInterval > pollingInterval) { + logger.warn(String.format( + "Message acknowledgement may be delayed by %ds in the ADSC listener. [Listening Time: %s, Poll Period: %s]", + pollingInterval - pollingTimeout, pollingTimeout, pollingInterval)); + } + + logParams(); + + // Download type + types.add("APPC_CONFIG"); + types.add("VF_LICENSE"); + + storeOp = new URI(props.getProperty("appc.asdc.provider.url")); + } + } + + @Override + public boolean activateServerTLSAuth() { + return false; + } + + @Override + public String getAsdcAddress() { + return host; + } + + @Override + public String getConsumerGroup() { + return consumer; + } + + @Override + public String getConsumerID() { + return consumerId; + } + + @Override + public String getEnvironmentName() { + return env; + } + + @Override + public String getKeyStorePassword() { + return keystorePass; + } + + @Override + public String getKeyStorePath() { + return keystorePath; + } + + @Override + public String getPassword() { + return pass; + } + + @Override + public int getPollingInterval() { + return pollingInterval; + } + + @Override + public int getPollingTimeout() { + return pollingTimeout; + } + + @Override + public List<String> getRelevantArtifactTypes() { + return types; + } + + @Override + public String getUser() { + return user; + } + + public URI getStoreOpURI() { + return storeOp; + } + + /** + * Logs the relevant parameters + */ + public void logParams() { + Map<String, String> params = new HashMap<String, String>(); + params.put("ASDC Host", getAsdcAddress()); + params.put("ASDC Environment", getEnvironmentName()); + params.put("Consumer Name", getConsumerGroup()); + params.put("Consumer ID", getConsumerID()); + params.put("Poll Active Wait", String.valueOf(getPollingInterval())); + params.put("Poll Timeout", String.valueOf(getPollingTimeout())); + + logger.info(String.format("ASDC Params: %s", params)); + } +} diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcListener.java b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcListener.java new file mode 100644 index 000000000..2d6192749 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcListener.java @@ -0,0 +1,131 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.sdc.listener; + +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.sdc.api.IDistributionClient; +import org.openecomp.sdc.api.results.IDistributionClientResult; +import org.openecomp.sdc.impl.DistributionClientFactory; +import org.openecomp.sdc.utils.DistributionActionResultEnum; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + + +public class AsdcListener { + + /** + * The bundle context + */ + private IDistributionClient client; + private AsdcCallback callback; + private AsdcConfig config; + private CountDownLatch latch; + + + private final EELFLogger logger = EELFManager.getInstance().getLogger(AsdcListener.class); + + @SuppressWarnings("unused") + public void start() throws Exception { + logger.info("Starting bundle ASDC Listener"); + Configuration configuration = ConfigurationFactory.getConfiguration(); + Properties props = configuration.getProperties(); + + config = new AsdcConfig(props); + + client = DistributionClientFactory.createDistributionClient(); + callback = new AsdcCallback(config.getStoreOpURI(), client); + + latch = new CountDownLatch(1); + + new Thread(new Runnable() { + @Override + public void run() { + initialRegistration(config); + + IDistributionClientResult result = client.init(config, callback); + + if (result.getDistributionActionResult() == DistributionActionResultEnum.SUCCESS) { + client.start(); + } else { + logger.error(String.format("Could not register ASDC client. %s - %s", result.getDistributionActionResult(), + result.getDistributionMessageResult())); + } + + latch.countDown(); + } + }).start(); + } + + @SuppressWarnings("unused") + public void stop() throws InterruptedException { + logger.info("Stopping ASDC Listener"); + latch.await(10, TimeUnit.SECONDS); + + if (callback != null) { + callback.stop(); + } + if (client != null) { + client.stop(); + + } + logger.info("ASDC Listener stopped successfully"); + } + + private boolean initialRegistration(AsdcConfig config) { + try { + final String jsonTemplate = "{\"consumerName\": \"%s\",\"consumerSalt\": \"%s\",\"consumerPassword\":\"%s\"}"; + String saltedPassStr = org.openecomp.tlv.sdc.security.Passwords.hashPassword(config.getPassword()); + if (saltedPassStr == null || !saltedPassStr.contains(":")) { + return false; + } + + String[] saltedPass = saltedPassStr.split(":"); + String json = String.format(jsonTemplate, config.getUser(), saltedPass[0], saltedPass[1]); + + Map<String, String> headers = new HashMap<>(); + // TODO - Replace the header below to sdc's requirements. What should the new value be + headers.put("HTTP_CSP_ID", "test"); + + // TODO - How to format the url. Always same endpoint or ports? + String host = config.getAsdcAddress(); + URL url = new URL( + String.format("http%s://%s/sdc2/rest/v1/consumers", host.contains("443") ? "s" : "", host)); + + logger.info(String.format("Attempting to register user %s on %s with salted pass of %s", config.getUser(), + url, saltedPass[1])); + + ProviderResponse result = ProviderOperations.post(url, json, headers); + return result.getStatus() == 200; + } catch (Exception e) { + logger.error("Error performing initial registration with ASDC server. User may not be able to connect", e); + return false; + } + } +} diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/DownloadAndStoreOp.java b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/DownloadAndStoreOp.java new file mode 100644 index 000000000..fcc5e7dda --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/DownloadAndStoreOp.java @@ -0,0 +1,227 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.sdc.listener; + +import org.openecomp.appc.adapter.dmaap.EventSender; +import org.openecomp.appc.adapter.dmaap.DmaapDestination; +import org.openecomp.appc.adapter.dmaap.event.EventHeader; +import org.openecomp.appc.adapter.dmaap.event.EventMessage; +import org.openecomp.appc.adapter.dmaap.event.EventStatus; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.licmgr.Constants; +import org.openecomp.appc.licmgr.LicenseManager; +import org.openecomp.sdc.api.IDistributionClient; +import org.openecomp.sdc.api.notification.IArtifactInfo; +import org.openecomp.sdc.api.notification.INotificationData; +import org.openecomp.sdc.api.notification.IResourceInstance; +import org.openecomp.sdc.api.results.IDistributionClientDownloadResult; +import org.openecomp.sdc.utils.DistributionActionResultEnum; +import org.openecomp.sdc.utils.DistributionStatusEnum; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +import static org.openecomp.appc.licmgr.Constants.ASDC_ARTIFACTS_FIELDS.*; + +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URI; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings("JavaDoc") +public class DownloadAndStoreOp implements Runnable { + + public static final String PAYLOAD_CHARSET = "UTF-8"; + + private static final String DATE_FORMAT = "yyyy/MM/dd HH:mm:ss"; + + private final EELFLogger logger = EELFManager.getInstance().getLogger(DownloadAndStoreOp.class); + + private IDistributionClient client; + private EventSender eventSender; + + private INotificationData notification; + private IResourceInstance resource; + private IArtifactInfo artifact; + + private URI storeUri; + + public DownloadAndStoreOp(IDistributionClient client, EventSender eventSender, INotificationData notification, IResourceInstance resource, + IArtifactInfo artifact, URI storeUri) { + this.client = client; + this.eventSender = eventSender; + this.notification = notification; + this.resource = resource; + this.artifact = artifact; + this.storeUri = storeUri; + } + + @Override + public void run() { + logger.info(String.format("Attempting to download artifact %s", artifact)); + // Download artifact + IDistributionClientDownloadResult download = client.download(artifact); + logger.info(String.format("Download of artifact %s completed with status %s", artifact.getArtifactUUID(), download)); + + // Notify of download status + if (download.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) { + client.sendDownloadStatus(Util.buildDistributionStatusMessage(client, notification, artifact, + DistributionStatusEnum.DOWNLOAD_ERROR), download.getDistributionMessageResult()); + sendDCAEEvent(notification.getDistributionID(), notification.getServiceName(), notification.getServiceVersion(), "Download is failed."); + return; + } + + client.sendDownloadStatus(Util.buildDistributionStatusMessage(client, notification, artifact, DistributionStatusEnum.DOWNLOAD_OK)); + + String data = null; + try { + if (download.getArtifactPayload() != null) { + data = new String(download.getArtifactPayload(), PAYLOAD_CHARSET); + } + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + boolean providerSuccess = false; + String providerReason = "Unknown Error"; + // Send data to provider + if (data != null && artifact != null) { + switch(artifact.getArtifactType()) { + case "APPC_CONFIG": + String postData = Util.toAsdcStoreDocumentInput(notification, resource, artifact, data); + try { + ProviderResponse result = ProviderOperations.post(storeUri.toURL(), postData, null); + if (result.getStatus() == 200) { + providerSuccess = Util.parseResponse(result.getBody()); + providerReason = "Success"; + } + } catch (MalformedURLException | APPCException e) { + providerReason = e.getMessage(); + e.printStackTrace(); + } + break; + + case "VF_LICENSE": + BundleContext bctx = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); + ServiceReference srefLicenseService = bctx.getServiceReference(LicenseManager.class); + LicenseManager licenseService = (LicenseManager) bctx.getService(srefLicenseService); + + Map<String, String> artifactPayload = prepareArtifactPayloadParamsMap(data); + + String vnfType = artifactPayload.get(RESOURCE_NAME.name()); + String version = artifactPayload.get(RESOURCE_VERSION.name()); + String packageArtifactID = artifactPayload.get(ARTIFACT_UUID.name()); + String packageArtifactVersion = artifactPayload.get(INTERNAL_VERSION.name()); + + try { + if (null == vnfType || null == version || null == packageArtifactID || null == packageArtifactVersion || vnfType.isEmpty() || version.isEmpty() || packageArtifactID.isEmpty() || packageArtifactVersion.isEmpty()) { + throw new APPCException(String.format("Missing information in ASDC request. Details: resource_type='%s', resource_version='%s', artifactID='%s', artifactVersion='%s'", vnfType, version, packageArtifactID, packageArtifactVersion)); + } + + Map<String, String> existingArtifactPayload = licenseService.retrieveLicenseModelData(vnfType, version); + + if (existingArtifactPayload.isEmpty()) { // new resource + licenseService.storeArtifactPayload(artifactPayload); + } else { // duplicate + logger.warn(String.format("Artifact of type '%s' already deployed for resource_type='%s' and resource_version='%s'", Constants.VF_LICENSE, vnfType, version)); + } + + providerSuccess = true; + + } catch (Exception e) { + providerSuccess = false; + providerReason = e.getMessage(); + } + break; + + default: + throw new UnsupportedOperationException("Artifact type " + artifact.getArtifactType() + " is not supported"); + } + + } + + // Notify of provider's response + if (providerSuccess) { + client.sendDeploymentStatus( + Util.buildDistributionStatusMessage(client, notification, artifact, DistributionStatusEnum.DEPLOY_OK)); + } else { + client.sendDeploymentStatus(Util.buildDistributionStatusMessage(client, notification, artifact, + DistributionStatusEnum.DEPLOY_ERROR), providerReason); + sendDCAEEvent(notification.getDistributionID(), notification.getServiceName(), notification.getServiceVersion(), providerReason); + } + + } + + /** + * Prepares Artifact Payload params map + * @param data + * @return Map<String,String> + */ + private Map<String, String> prepareArtifactPayloadParamsMap(String data) { + Map<String, String> paramsMap = new HashMap<>(); + + paramsMap.put(SERVICE_UUID.name(), this.notification.getServiceUUID()); + paramsMap.put(DISTRIBUTION_ID.name(), this.notification.getDistributionID()); + paramsMap.put(SERVICE_NAME.name(), this.notification.getServiceName()); + paramsMap.put(SERVICE_DESCRIPTION.name(), this.notification.getServiceDescription()); + paramsMap.put(RESOURCE_UUID.name(), this.resource.getResourceUUID()); + paramsMap.put(RESOURCE_INSTANCE_NAME.name(), this.resource.getResourceInstanceName()); + paramsMap.put(RESOURCE_NAME.name(), this.resource.getResourceName()); + paramsMap.put(RESOURCE_VERSION.name(), this.resource.getResourceVersion()); + paramsMap.put(RESOURCE_TYPE.name(), this.resource.getResourceType()); + paramsMap.put(ARTIFACT_UUID.name(), this.artifact.getArtifactUUID()); + paramsMap.put(ARTIFACT_TYPE.name(), this.artifact.getArtifactType()); + paramsMap.put(ARTIFACT_VERSION.name(), this.artifact.getArtifactVersion()); + paramsMap.put(ARTIFACT_DESCRIPTION.name(), this.artifact.getArtifactDescription()); + paramsMap.put(CREATION_DATE.name(), getCurrentDateTime()); + paramsMap.put(ARTIFACT_NAME.name(), this.artifact.getArtifactName()); + paramsMap.put(ARTIFACT_CONTENT.name(), data); + + return paramsMap; + } + + + private String getCurrentDateTime() { + DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); + Date date = new Date(); + return dateFormat.format(date); + } + + private void sendDCAEEvent(String distributionID, String serviceName, String serviceVersion, String errorMessage) { + if (null == eventSender) return; + String errorDescription = String.format("ASDC distribution of service '%s', version '%s' is failed with reason: '%s'", + serviceName, serviceVersion, errorMessage); + + EventMessage eventMessage = new EventMessage( + new EventHeader((new java.util.Date()).toString(), serviceVersion, distributionID), + new EventStatus(401, errorDescription)); + + eventSender.sendEvent(DmaapDestination.DCAE, eventMessage); + } + +} diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/ProviderOperations.java b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/ProviderOperations.java new file mode 100644 index 000000000..5a805205a --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/ProviderOperations.java @@ -0,0 +1,208 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.sdc.listener; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.Socket; +import java.net.URL; +import java.net.UnknownHostException; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Map; +import java.util.Map.Entry; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.HttpVersion; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; +import org.apache.http.protocol.HTTP; +import org.openecomp.appc.exceptions.APPCException; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +public class ProviderOperations { + + private static final EELFLogger LOG = EELFManager.getInstance().getLogger(ProviderOperations.class); + + private static String basic_auth; + + public static ProviderResponse post(URL url, String json, Map<String, String> adtl_headers) throws APPCException { + if (json == null) { + throw new APPCException("Provided message was null"); + } + + HttpPost post = null; + try { + post = new HttpPost(url.toExternalForm()); + post.setHeader("Content-Type", "application/json"); + post.setHeader("Accept", "application/json"); + + // Set Auth + if (basic_auth != null) { + post.setHeader("Authorization", "Basic " + basic_auth); + } + + if (adtl_headers != null) { + for (Entry<String, String> header : adtl_headers.entrySet()) { + post.setHeader(header.getKey(), header.getValue()); + } + } + + StringEntity entity = new StringEntity(json); + entity.setContentType("application/json"); + post.setEntity(new StringEntity(json)); + } catch (UnsupportedEncodingException e) { + throw new APPCException(e); + } + + HttpClient client = getHttpClient(url); + + int httpCode = 0; + String respBody = null; + try { + HttpResponse response = client.execute(post); + httpCode = response.getStatusLine().getStatusCode(); + respBody = IOUtils.toString(response.getEntity().getContent()); + return new ProviderResponse(httpCode, respBody); + } catch (IOException e) { + throw new APPCException(e); + } + } + + /** + * Sets the basic authentication header for the given user and password. If either entry is null then set basic auth + * to null + * + * @param user + * The user with optional domain name (for AAF) + * @param password + * The password for the user + * @return The new value of the basic auth string that will be used in the request headers + */ + public static String setAuthentication(String user, String password) { + if (user != null && password != null) { + String authStr = user + ":" + password; + basic_auth = new String(Base64.encodeBase64(authStr.getBytes())); + } else { + basic_auth = null; + } + return basic_auth; + } + + @SuppressWarnings("deprecation") + private static HttpClient getHttpClient(URL url) throws APPCException { + HttpClient client; + if (url.getProtocol().equals("https")) { + try { + KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); + trustStore.load(null, null); + MySSLSocketFactory sf = new MySSLSocketFactory(trustStore); + sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); + + HttpParams params = new BasicHttpParams(); + HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); + HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); + + SchemeRegistry registry = new SchemeRegistry(); + registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + registry.register(new Scheme("https", sf, 443)); + registry.register(new Scheme("https", sf, 8443)); + registry.register(new Scheme("http", sf, 8181)); + + ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); + client = new DefaultHttpClient(ccm, params); + } catch (Exception e) { + client = new DefaultHttpClient(); + } + } else if (url.getProtocol().equals("http")) { + client = new DefaultHttpClient(); + } else { + throw new APPCException( + "The provider.topology.url property is invalid. The url did not start with http[s]"); + } + return client; + } + + @SuppressWarnings("deprecation") + public static class MySSLSocketFactory extends SSLSocketFactory { + private SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); + + public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, + KeyStoreException, UnrecoverableKeyException { + super(truststore); + + TrustManager tm = new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; + } + }; + + sslContext.init(null, new TrustManager[] { + tm + }, null); + } + + @Override + public Socket createSocket(Socket socket, String host, int port, boolean autoClose) + throws IOException, UnknownHostException { + return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); + } + + @Override + public Socket createSocket() throws IOException { + return sslContext.getSocketFactory().createSocket(); + } + } + +} diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/ProviderResponse.java b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/ProviderResponse.java new file mode 100644 index 000000000..7e5ea1228 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/ProviderResponse.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.sdc.listener; + +public class ProviderResponse { + + private int status; + private String body; + + public ProviderResponse(int status, String body) { + this.status = status; + this.body = body; + } + + public String getBody() { + return body; + } + + public int getStatus() { + return status; + } + +} diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/Util.java b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/Util.java new file mode 100644 index 000000000..46efba438 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/Util.java @@ -0,0 +1,122 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.sdc.listener; + +import org.json.JSONException; +import org.json.JSONObject; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdc.api.IDistributionClient; +import org.openecomp.sdc.api.consumer.IDistributionStatusMessage; +import org.openecomp.sdc.api.notification.IArtifactInfo; +import org.openecomp.sdc.api.notification.INotificationData; +import org.openecomp.sdc.api.notification.IResourceInstance; +import org.openecomp.sdc.utils.DistributionStatusEnum; + +public class Util { + + // TODO - Use the yang builder instead + public static String toAsdcStoreDocumentInput(INotificationData notification, IResourceInstance resource, + IArtifactInfo artifact, String data) { + JSONObject json = new JSONObject(); + + JSONObject requestInfo = new JSONObject(); + requestInfo.put("request-id", notification.getServiceUUID()); + requestInfo.put("request-action", "StoreAsdcDocumentRequest"); + requestInfo.put("source", "ASDC"); + + JSONObject docParams = new JSONObject(); + docParams.put("service-uuid", notification.getServiceUUID()); + docParams.put("distribution-id", notification.getDistributionID()); + docParams.put("service-name", notification.getServiceName()); + docParams.put("service-description", notification.getServiceDescription()); + docParams.put("service-artifacts", "[]"); + docParams.put("resource-uuid", resource.getResourceUUID()); + docParams.put("resource-instance-name", resource.getResourceInstanceName()); + docParams.put("resource-name", resource.getResourceName()); + docParams.put("resource-version", resource.getResourceVersion()); + docParams.put("resource-type", resource.getResourceType()); + docParams.put("artifact-uuid", artifact.getArtifactUUID()); + docParams.put("artifact-name", artifact.getArtifactName()); + docParams.put("artifact-type", artifact.getArtifactType()); + docParams.put("artifact-version", artifact.getArtifactVersion()); + docParams.put("artifact-description", artifact.getArtifactDescription()); + docParams.put("artifact-contents", data); + + json.put("request-information", requestInfo); + json.put("document-parameters", docParams); + + return String.format("{\"input\": %s}", json.toString()); + } + + public static boolean parseResponse(String input) throws APPCException { + JSONObject result, output, response; + try { + result = new JSONObject(input); + output = result.getJSONObject("output"); + response = output.getJSONObject("config-document-response"); + String id = response.getString("request-id"); + String status = response.getString("status"); + if (status.equals(DistributionStatusEnum.DEPLOY_OK.toString())) { + return true; + } else { + String error = response.optString("error-reason"); + String msg = error.isEmpty() ? "No Reason Provided" : error; + throw new APPCException(msg); + } + } catch (JSONException jse) { + throw new APPCException("Did not get valid json from provider.", jse); + } + } + + public static IDistributionStatusMessage buildDistributionStatusMessage(final IDistributionClient client, + final INotificationData data, final IArtifactInfo relevantArtifact, final DistributionStatusEnum status) { + IDistributionStatusMessage statusMessage = new IDistributionStatusMessage() { + + @Override + public long getTimestamp() { + long currentTimeMillis = System.currentTimeMillis(); + return currentTimeMillis; + } + + @Override + public DistributionStatusEnum getStatus() { + return status; + } + + @Override + public String getDistributionID() { + return data.getDistributionID(); + } + + @Override + public String getConsumerID() { + return client.getConfiguration().getConsumerID(); + } + + @Override + public String getArtifactURL() { + return relevantArtifact.getArtifactURL(); + } + }; + return statusMessage; + } +} diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/tlv/sdc/security/Passwords.java b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/tlv/sdc/security/Passwords.java new file mode 100644 index 000000000..39d809352 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/tlv/sdc/security/Passwords.java @@ -0,0 +1,167 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.tlv.sdc.security; + +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.Random; + +/** + * A copy from the org.openecomp.sdc:security-utils artifact that works with java 7. + */ +public class Passwords { + + private static final Random RANDOM = new SecureRandom(); + private static final int SALT = 0; + private static final int HASH = 1; + private static final String HASH_ALGORITHM = "SHA-256"; + + /** + * static utility class + */ + private Passwords() { + } + + /** + * the method calculates a hash with a generated salt for the given password + * + * @param password + * @return a "salt:hash" value + */ + public static String hashPassword(String password) { + byte[] salt = getNextSalt(); + byte byteData[] = hash(salt, password.getBytes()); + if (byteData != null) { + return toHex(salt) + ":" + toHex(byteData); + } + return null; + + } + + /** + * the method checks if the given password matches the calculated hash + * + * @param password + * @param expectedHash + * @return + */ + public static boolean isExpectedPassword(String password, String expectedHash) { + String[] params = expectedHash.split(":"); + return isExpectedPassword(password, params[SALT], params[HASH]); + } + + /** + * the method checks if the given password matches the calculated hash + * + * @param password + * @param salt + * @param hash + * the hash generated using the salt + * @return true if the password matched the hash + */ + public static boolean isExpectedPassword(String password, String salt, String hash) { + byte[] saltBytes = fromHex(salt); + byte[] hashBytes = fromHex(hash); + + byte byteData[] = hash(saltBytes, password.getBytes()); + if (byteData != null) { + return Arrays.equals(byteData, hashBytes); + } + return false; + } + + public static void main(String[] args) { + if (args.length > 1 || args.length > 0) { + System.out.println("[" + hashPassword(args[0]) + "]"); + } else { + System.out.println("no passward passed."); + } + + } + + /** + * Returns a random salt to be used to hash a password. + * + * @return a 16 bytes random salt + */ + private static byte[] getNextSalt() { + byte[] salt = new byte[16]; + RANDOM.nextBytes(salt); + return salt; + } + + /** + * hase's the salt and value using the chosen algorithm + * + * @param salt + * @param password + * @return an array of bytes resulting from the hash + */ + private static byte[] hash(byte[] salt, byte[] password) { + MessageDigest md; + byte[] byteData = null; + try { + md = MessageDigest.getInstance(HASH_ALGORITHM); + md.update(salt); + md.update(password); + byteData = md.digest(); + } catch (NoSuchAlgorithmException e) { + System.out.println("in vlide algorithem name"); + } + return byteData; + } + + /** + * Converts a string of hexadecimal characters into a byte array. + * + * @param hex + * the hex string + * @return the hex string decoded into a byte array + */ + private static byte[] fromHex(String hex) { + byte[] binary = new byte[hex.length() / 2]; + for (int i = 0; i < binary.length; i++) { + binary[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16); + } + return binary; + } + + /** + * Converts a byte array into a hexadecimal string. + * + * @param array + * the byte array to convert + * @return a length*2 character string encoding the byte array + */ + private static String toHex(byte[] array) { + BigInteger bi = new BigInteger(1, array); + String hex = bi.toString(16); + int paddingLength = (array.length * 2) - hex.length(); + if (paddingLength > 0) + return String.format("%0" + paddingLength + "d", 0) + hex; + else + return hex; + } +} diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..08b864c63 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- + Starter Blueprint Camel Definition appc-aai-adapter-blueprint +--> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + + + <bean id="AsdcListener" class="org.openecomp.appc.sdc.listener.AsdcListener" init-method="start" destroy-method="stop" scope="singleton" activation="eager"> + </bean> + + <!-- + <bean id="AsdcListenerBean" class="org.openecomp.appc.sdc.listener.impl.AsdcListenerBean" init-method="start" destroy-method="stop" activation="eager" scope="singleton" /> + <service id="AsdcListener" interface="org.openecomp.appc.sdc.listener.AsdcListener" ref="AsdcListenerBean"/> + --> + +</blueprint> + diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/attsdc-packages.yaml b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/attsdc-packages.yaml new file mode 100644 index 000000000..8385dc988 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/attsdc-packages.yaml @@ -0,0 +1,10 @@ +packages: + - org.openecomp.tlv.sdc.ci.tests.execute.general + - org.openecomp.tlv.sdc.ci.tests.execute.user + - org.openecomp.tlv.sdc.ci.tests.execute.property + - org.openecomp.tlv.sdc.ci.tests.execute.lifecycle + - org.openecomp.tlv.sdc.ci.tests.execute.resource + - org.openecomp.tlv.sdc.ci.tests.execute.service + - org.openecomp.tlv.sdc.ci.tests.execute.artifacts + - org.openecomp.tlv.sdc.ci.tests.execute.imports + - org.openecomp.tlv.sdc.ci.tests.execute.category
\ No newline at end of file diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/attsdc.yaml b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/attsdc.yaml new file mode 100644 index 000000000..7e612fe9b --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/attsdc.yaml @@ -0,0 +1,35 @@ +outputFolder: target +reportName: index.html +catalogBeHost: localhost +catalogFeHost: localhost +esHost: localhost +disributionClientHost: localhost +catalogFePort: 8181 +catalogBePort: 8080 +disributionClientPort: 8181 +esPort: 9200 +neoHost: localhost +neoPort: 7474 +neoDBusername: neo4j +neoDBpassword: 123456 + +resourceConfigDir: src/test/resources/CI/tests +componentsConfigDir: src/test/resources/CI/components +importResourceConfigDir: src/test/resources/CI/importResource +importResourceTestsConfigDir: src/test/resources/CI/importResourceTests +errorConfigurationFile: ../catalog-be/src/main/resources/config/error-configuration.yaml + +titanPropertiesFile: src/main/resources/ci/conf/titan.properties + +stopOnClassFailure: false + +#List of non-abstract resources to keep during titan cleanup between tests +#Only 1.0 version will be kept +resourcesNotToDelete: + - tosca.nodes.Compute + - tosca.nodes.Database + - tosca.nodes.ObjectStorage + - tosca.nodes.BlockStorage + - tosca.nodes.LoadBalancer + - org.openecomp.d2.resource.cp.Port + - org.openecomp.d2.resource.vl.Network
\ No newline at end of file diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/log4j.properties b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/log4j.properties new file mode 100644 index 000000000..4b99de0c9 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/log4j.properties @@ -0,0 +1,55 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# Define the root logger with appender file +log4j.rootLogger = DEBUG, FILE, stdout + +# Define the file appender +log4j.appender.FILE=org.apache.log4j.RollingFileAppender +log4j.appender.FILE.File=${targetlog}logs/ci-log.out + +# Define the layout for file appender +log4j.appender.FILE.layout=org.apache.log4j.PatternLayout +log4j.appender.FILE.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} %5p [%10c] : %m%n + +# Set the maximum file size before rollover +log4j.appender.FILE.maxFileSize=5MB + +# Set the the backup index +log4j.appender.FILE.maxBackupIndex=10 + + +############################################################# + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +#log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %5p %10c:%L - %m%n + +log4j.logger.org.apache.cassandra.service.StorageProxy=DEBUG +log4j.logger.com.thinkaurelius.titan.diskstorage.cassandra.CassandraTransaction=INFO, FILE, stdout + +log4j.logger.org.openecomp.tlv.sdc.ci.tests.utils=TRACE, FILE, stdout +log4j.additivity.org.openecomp.tlv.sdc.ci.tests.utils=false + + diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/titan.properties b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/titan.properties new file mode 100644 index 000000000..2aa4b0189 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/conf/titan.properties @@ -0,0 +1,26 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +storage.backend=cassandra +storage.hostname=locahost +storage.port=9160 + +cache.db-cache = false diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/scripts/startTest.sh b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/scripts/startTest.sh new file mode 100644 index 000000000..321476e90 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/ci/scripts/startTest.sh @@ -0,0 +1,109 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +#!/bin/bash + +function usage { + echo "Usage: $0 <jar file>" +} + +function exitOnError() { + if [ $1 -ne 0 ] + then + echo "Failed running task $2" + exit 2 + fi +} + +if [ $# -lt 1 ] +then + usage + exit 2 +fi + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +LOGS_PROP_FILE=file:${FULL_PATH}/conf/log4j.properties +############################################# +TARGET_DIR=${FULL_PATH}/target +CONF_FILE=${FULL_PATH}/conf/attsdc.yaml +DEBUG=true +#MainClass=org.openecomp.tlv.sdc.ci.tests.run.StartTest +MainClass=org.openecomp.test.ClientTest + +JAR_FILE=$1 + +#TARGET_DIR=`echo ${TARGET_DIR} | sed 's/\//\//g'` +#echo $TARGET_DIR + +TESTS_DIR=/opt/app/sdc/ci/resources/tests +COMPONENTS_DIR=/opt/app/sdc/ci/resources/components + +#sed -i 's#\(outputFolder:\).*#\1 '${TARGET_DIR}'#g' $CONF_FILE +#sed -i 's#\(resourceConfigDir:\).*#\1 '${TESTS_DIR}'#g' $CONF_FILE +#sed -i 's#\(componentsConfigDir:\).*#\1 '${COMPONENTS_DIR}'#g' $CONF_FILE +TARGET_LOG_DIR="${TARGET_DIR}/" + +mkdir -p ${TARGET_DIR} +if [ -d ${TARGET_DIR} ] +then + rm -rf ${TARGET_DIR}/* + exitOnError $? "Failed_to_delete_target_dir" +fi + +debug_port=8800 +#JAVA_OPTION="-javaagent:/var/tmp/jacoco/lib/jacocoagent.jar=destfile=jacoco-it.exec" +JAVA_OPTION="" +case "$2" in + -debug) echo "Debug mode, Listen on port $debug_port"; JAVA_OPTION="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=${debug_port}" ;; + "") echo "Standard mode";; + *) echo "USAGE: startTest.sh [-debug]";; +esac + +cmd="java $JAVA_OPTION -DdisplayException=true -Dtargetlog=${TARGET_LOG_DIR} -Dconfig.resource=${CONF_FILE} -Ddebug=${DEBUG} -Dlog4j.configuration=${LOGS_PROP_FILE} -cp $JAR_FILE ${MainClass}" + +#echo $cmd +#console=`$cmd` + +if [ $DEBUG == "true" ] +then + $cmd +else + $cmd >> /dev/null +fi +status=`echo $?` + + + +echo "##################################################" +echo "################# status is ${status} #################" +echo "##################################################" + +exit $status + diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..5742b8945 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,37 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + +# These ASDC properties were provided by the ASDC Op-So team +appc.asdc.keystore.path=etc/asdc-client.jks +appc.asdc.keystore.pass=Aa123456 + +appc.asdc.host=192.168.1.2:8443 +appc.asdc.env=TEST +appc.asdc.user=appc +appc.asdc.pass=appc + +appc.asdc.consumer=TEST +appc.asdc.consumer.id=TEST +appc.asdc.provider.url=http://localhost:8181/restconf/operations/AsdcMessage:configuration-document-request + diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/test/java/org/openecomp/appc/sdc/listener/TestRun.java b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/test/java/org/openecomp/appc/sdc/listener/TestRun.java new file mode 100644 index 000000000..613814ab3 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/test/java/org/openecomp/appc/sdc/listener/TestRun.java @@ -0,0 +1,38 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.sdc.listener; + +import org.junit.Test; + +public class TestRun { + + @Test + public void testRunning() throws Exception { + /* + AppcAsdcListenerActivator a = new AppcAsdcListenerActivator(); + a.start(null); + Thread.sleep(10000); + a.stop(null); + */ + } + +} diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/test/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/test/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..f61cde04c --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-bundle/src/test/resources/org/openecomp/appc/default.properties @@ -0,0 +1,33 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# These ASDC properties were provided by the ASDC Op-So team +appc.asdc.keystore.path=etc/asdc-client.jks +appc.asdc.keystore.pass=Aa123456 + +appc.asdc.host=192.168.1.2:8443 +appc.asdc.env=TEST +appc.asdc.user=appc +appc.asdc.pass=appc + +appc.asdc.consumer=TEST +appc.asdc.consumer.id=TEST +appc.asdc.provider.url=http://localhost:8181/restconf/operations/AsdcMessage:configuration-document-request diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-features/.gitignore b/app-c/appc/appc-asdc-listener/appc-asdc-listener-features/.gitignore new file mode 100644 index 000000000..2992ae832 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-features/.gitignore @@ -0,0 +1,3 @@ +/target/ +/bin/ +/.settings/ diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-features/pom.xml b/app-c/appc/appc-asdc-listener/appc-asdc-listener-features/pom.xml new file mode 100644 index 000000000..c0ca8d190 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-features/pom.xml @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-asdc-listener</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>appc-asdc-listener-features</artifactId> + <name>Event Listener - Features</name> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-asdc-listener-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>features-mdsal</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </dependency> + + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>features-yangtools</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-features/src/main/resources/features.xml b/app-c/appc/appc-asdc-listener/appc-asdc-listener-features/src/main/resources/features.xml new file mode 100644 index 000000000..88a49d483 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-features/src/main/resources/features.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="appc-asdc-listener-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + +<!-- <repository>mvn:org.opendaylight.mdsal/features-mdsal/${odl.mdsal.version}/xml/features</repository> --> + <repository>mvn:org.opendaylight.mdsal/features-mdsal/${features-mdsal.version}/xml/features</repository> + + <feature name='appc-asdc-listener' description="asdc listener" version='${project.version}'> + <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> + <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> + <bundle>mvn:org.openecomp.appc/appc-asdc-listener-bundle/${project.version}</bundle> + </feature> + +</features> diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-installer/.gitignore b/app-c/appc/appc-asdc-listener/appc-asdc-listener-installer/.gitignore new file mode 100644 index 000000000..731eb433c --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-installer/.gitignore @@ -0,0 +1,2 @@ +/target/ +/.settings/ diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-installer/pom.xml b/app-c/appc/appc-asdc-listener/appc-asdc-listener-installer/pom.xml new file mode 100644 index 000000000..8dcd1758e --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-installer/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-asdc-listener</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>appc-asdc-listener-installer</artifactId> + <name>ASDC Listener - Karaf Installer</name> + <packaging>pom</packaging> + + <properties> + <application.name>appc-asdc-listener</application.name> + <features.boot>appc-asdc-listener</features.boot> + <features.repositories>mvn:org.openecomp.appc/appc-asdc-listener-features/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-asdc-listener-features</artifactId> + <version>${project.version}</version> + <classifier>features</classifier> + <type>xml</type> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-asdc-listener-bundle</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>false</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>true</attach> + <finalName>${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <excludeGroupIds>org.opendaylight</excludeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals> + <!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-installer/src/assembly/assemble_installer_zip.xml b/app-c/appc/appc-asdc-listener/appc-asdc-listener-installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..9fbaad8c5 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>adapter</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-installer/src/assembly/assemble_mvnrepo_zip.xml b/app-c/appc/appc-asdc-listener/appc-asdc-listener-installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..1ac5a82bc --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,47 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>adapter</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + +</assembly> diff --git a/app-c/appc/appc-asdc-listener/appc-asdc-listener-installer/src/main/resources/scripts/install-feature.sh b/app-c/appc/appc-asdc-listener/appc-asdc-listener-installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..1d769fada --- /dev/null +++ b/app-c/appc/appc-asdc-listener/appc-asdc-listener-installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,40 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +#!/bin/bash + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -n -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot} diff --git a/app-c/appc/appc-asdc-listener/pom.xml b/app-c/appc/appc-asdc-listener/pom.xml new file mode 100644 index 000000000..6641cf871 --- /dev/null +++ b/app-c/appc/appc-asdc-listener/pom.xml @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc</artifactId> + <version>1.0.0</version> + </parent> + + <artifactId>appc-asdc-listener</artifactId> + <name>ASDC Event Listener</name> + <description>Listener to read and write events from DMaaP (Cambria) or DMaaP.</description> + <packaging>pom</packaging> + + <reporting> + <plugins> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <additionalDependencies> + <additionalDependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4</artifactId> + <version>${antlr.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4-runtime</artifactId> + <version>4.3</version> + </additionalDependency> + </additionalDependencies> + </configuration> + <reportSets> + <reportSet> + <reports> + <report>javadoc-no-fork</report> + <report>test-javadoc-no-fork</report> + </reports> + </reportSet> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jxr-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-changelog-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>dual-report</id> + <configuration> + <type>range</type> + <range>30</range> + </configuration> + <reports> + <report>changelog</report> + <report>file-activity</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>taglist-maven-plugin</artifactId> + <version>2.4</version> + </plugin> + </plugins> + </reporting> + + <modules> + <module>appc-asdc-listener-bundle</module> + <module>appc-asdc-listener-features</module> + <module>appc-asdc-listener-installer</module> + </modules> +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-common/.gitignore b/app-c/appc/appc-common/.gitignore new file mode 100644 index 000000000..637be2b0f --- /dev/null +++ b/app-c/appc/appc-common/.gitignore @@ -0,0 +1,4 @@ +/target/ +.classpath +/bin/ +/.settings/ diff --git a/app-c/appc/appc-common/pom.xml b/app-c/appc/appc-common/pom.xml new file mode 100644 index 000000000..e234e89d2 --- /dev/null +++ b/app-c/appc/appc-common/pom.xml @@ -0,0 +1,210 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-common</artifactId> + <name>APP-C Common</name> + <description>Common library shared across all modules</description> + +<!-- <packaging>bundle</packaging> --> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-core</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + + <!-- Needed for EELF (Event and Error Logging Framework) support --> + <dependency> + <groupId>com.att.eelf</groupId> + <artifactId>eelf-core</artifactId> + </dependency> + + <!-- Needed for encryption --> + <dependency> + <groupId>org.jasypt</groupId> + <artifactId>jasypt</artifactId> + <version>1.9.2</version> +<!-- <classifier>lite</classifier> --> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + </dependency> + + <dependency> + <groupId>javax</groupId> + <artifactId>javaee-api</artifactId> + <version>7.0</version> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>4.5.1</version> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore</artifactId> + <version>${apache.httpcomponents.version}</version> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-core</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-annotations</artifactId> + </dependency> + + </dependencies> + + <build> + <resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + </resource> + <resource> + <directory>src/main/java</directory> + <includes> + <include>**/*.java</include> + </includes> + </resource> + </resources> + + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>appc-common</Bundle-SymbolicName> + <!-- <Export-Package>org.openecomp.appc.provider</Export-Package> --> + <Import-Package>!com.att,!javax.crypto.*, *</Import-Package> + <Embed-Dependency>eelf-core, jasypt</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + </configuration> + </plugin> + + <plugin> + <groupId>com.att.eelf</groupId> + <artifactId>eelf-maven-plugin</artifactId> + <version>${eelf.maven.plugin.version}</version> + <executions> + <execution> + <id>validation</id> + <phase>install</phase> + <goals> + <goal>ValidateApplicationMsgs</goal> + </goals> + <configuration> + <resources> + <resource> + <messageClass>org.openecomp.appc.i18n.Msg</messageClass> + </resource> + </resources> + </configuration> + </execution> + <execution> + <id>generate</id> + <phase>install</phase> + <goals> + <goal>WikiMsgGenerator</goal> + </goals> + <configuration> + <outputDirectory>target/messages</outputDirectory> + <outputFile>messages.html</outputFile> + <resources> + <resource> + <messageClass>org.openecomp.appc.i18n.Msg</messageClass> + <header><![CDATA[<p> <ac:macro ac:name="toc" /> </p>]]></header> + </resource> + </resources> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + </plugin> + + <!-- For embedding dependencies --> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-assembly-plugin</artifactId> + <configuration> + <descriptorRefs> + <descriptorRef>jar-with-dependencies</descriptorRef> + </descriptorRefs> + </configuration> + <executions> + <execution> + <id>make-assembly</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <executions> + <execution> + <phase>install</phase> + <goals> + <goal>shade</goal> + </goals> + <configuration> + <finalName>${project.artifactId}-${project.version}-jar-with-dependencies</finalName> + <artifactSet> + <excludes> + <exclude>junit:junit</exclude> + <exclude>ch.qos.logback:*</exclude> + <exclude>org.slf4j:slf4j-api</exclude> + </excludes> + </artifactSet> + </configuration> + </execution> + </executions> + </plugin> + + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/Constants.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/Constants.java new file mode 100644 index 000000000..134f7ecc2 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/Constants.java @@ -0,0 +1,188 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc; + +/** + * This class contains the definitions of all constant values used in the APPC provider, adapters, and other components. + * These constants define properties, settings, and context variables. The context variables can be referenced from + * within the directed graph(s) to access information placed their by the provider and adapters. + * <p> + * Context properties are set in the graph context by the various adapters and the provider, or by the graph itself. + * These properties may also be accessed by the graph, adapters, or the provider. It is these properties that allow + * communication of state through the directed graph. All context properties have a symbolic name that starts with + * "CONTEXT_". + * </p> + * + */ + +public final class Constants { + + /** + * The name for the error code attribute to be set in the context + */ + @SuppressWarnings("nls") + public static final String ATTRIBUTE_ERROR_CODE = "error_code"; + + /** + * The name for the error message attribute to be set in the context + */ + @SuppressWarnings("nls") + public static final String ATTRIBUTE_ERROR_MESSAGE = "error-message"; + + public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; + + public static final String DG_ATTRIBUTE_STATUS = "SvcLogic.status"; + + /** + * The property that defines the name of the DG service logic to be loaded + */ + public static final String PROPERTY_MODULE_NAME = "appc.service.logic.module.name"; + + /** + * The property that defines the topology restart DG version to be used + */ + public static final String PROPERTY_TOPOLOGY_VERSION = "appc.topology.dg.version"; + + /** + * The method name of the DG that is used to perform topology restart operations + */ + public static final String PROPERTY_TOPOLOGY_METHOD = "appc.topology.dg.method"; + + /** + * The name of the service logic method in the DG to be executed + */ + // public static final String CONFIGURATION_METHOD_NAME = "configuration-operation"; + + /** + * The property that supplies the application name + */ + public static final String PROPERTY_APPLICATION_NAME = "appc.application.name"; + + /** + * The execution mode for the directed graph + */ + public static final String SYNC_MODE = "sync"; + + /** + * The name of the property that contains the service request enumerated value in the graph's context + */ + public static final String CONTEXT_SERVICE = "org.openecomp.appc.service"; + + /** + * The name of the property that contains the VM id value in the graph's context + */ + public static final String CONTEXT_VMID = "org.openecomp.appc.vmid"; + + /** + * The name of the property that contains the VM id value in the graph's context + */ + public static final String CONTEXT_IDENTITY_URL = "org.openecomp.appc.identity.url"; + + /** + * The name of the property that contains the service request id value in the graph's context + */ + public static final String CONTEXT_REQID = "org.openecomp.appc.reqid"; + + /** + * The name of the property that indicates which method of the IaaS adapter to call + */ + public static final String CONTEXT_ACTION = "org.openecomp.appc.action"; + + /** + * The enumerated value for restart of a VM. This is a constant for one possible value of CONTEXT_SERVICE. + */ + public static final String SERVICE_RESTART = "RESTART"; + + /** + * The enumerated value for rebuild of a VM. This is a constant for one possible value of CONTEXT_SERVICE. + */ + public static final String SERVICE_REBUILD = "REBUILD"; + + /** + * The name of the adapter. We get the name from a property file so that it can be changed easily if needed. + */ + public static final String PROPERTY_ADAPTER_NAME = "org.openecomp.appc.provider.adaptor.name"; + + /** + * The minimum number of contexts to cache in each provider/tenant pool + */ + public static final String PROPERTY_MIN_POOL_SIZE = "org.openecomp.appc.provider.min.pool"; + + /** + * The maximum number of contexts to cache in each provider/tenant pool + */ + public static final String PROPERTY_MAX_POOL_SIZE = "org.openecomp.appc.provider.max.pool"; + + /** + * The amount of time, in seconds, that the application waits for a change of state of a server to a known valid + * state before giving up and failing the request. + */ + public static final String PROPERTY_SERVER_STATE_CHANGE_TIMEOUT = "org.openecomp.appc.server.state.change.timeout"; + + /** + * The amount of time, in seconds, between subsequent polls to the openstack provider to update the state of a + * resource + */ + public static final String PROPERTY_OPENSTACK_POLL_INTERVAL = "org.openecomp.appc.openstack.poll.interval"; + + /** + * The amount of time, in seconds, to wait between retry attempts when a connection to a provider fails. + */ + public static final String PROPERTY_RETRY_DELAY = "org.openecomp.appc.provider.retry.delay"; + + /** + * The maximum number of times a connection retry will be attempted before the application fails the request + */ + public static final String PROPERTY_RETRY_LIMIT = "org.openecomp.appc.provider.retry.limit"; + /** + * The amount of time, in seconds, that the application waits for a change of state of a stacj to a known valid + * state before giving up and failing the request. + */ + public static final String PROPERTY_STACK_STATE_CHANGE_TIMEOUT ="org.openecomp.appc.stack.state.change.timeout" ; + + /** + * Private default constructor prevents instantiation + */ + + @SuppressWarnings("nls") + public static final String STATUS_GETTER = "status-getter"; + + + + + @SuppressWarnings("nls") + public static final String VM_FUSION_STATUS_GETTER = "fusion-vm-status-getter"; + + + /** + * The name for the status vm attribute to be set in the context when executing a vmstatuscheck. + */ + + @SuppressWarnings("nls") + public static final String STATUS_OF_VM = "status-vm"; + + private Constants() { + + } +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/concurrent/Signal.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/concurrent/Signal.java new file mode 100644 index 000000000..153dd0bdc --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/concurrent/Signal.java @@ -0,0 +1,228 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.concurrent; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeoutException; + +import org.openecomp.appc.util.StringHelper; + +/** + * This class is used to synchronize signaling of status between threads. + * <p> + * In complex multi-threaded applications it is often necessary to synchronize operations between threads. This is + * especially true in complex algorithms where processing dependencies exist between different threads and the + * synchronization of the operations of those threads is required. This class is a framework to enable multi-thread + * signaling and wait/post logic that makes the thread synchronization easier. + * </p> + * <p> + * Basically, in thread synchronization, one thread is the "waiter" and one or more other threads are the "notifiers". + * The notifiers send signals to the waiter to inform that thread that certain conditions are true, processing has been + * completed, or to inform the waiter of the state of the other thread(s). In the basic java framework, the waiter and + * notifier are simply using the wait/notify mechanism provided, which does not allow for different conditions, state, + * or "signals" to exist. The wait/notify mechanism, in combination with the object mutex, provides basic blocking and + * releasing of a thread's dispatching state. + * </p> + * <p> + * This class builds upon the java wait/notify mechanism and allows for "signals" to be defined. These signals are + * simply string constants that mean something to the waiter and notifier threads. Any number of signals may be defined, + * and it is possible to wait for more than one signal to be received, wait for any one of a set to be received, or to + * test if a signal has been received without blocking. + * </p> + * <p> + * Some operations are blocking operations. These stop the execution of the calling thread until the specified condition + * is true. These blocking methods are all named "wait...", such as {@link #waitFor(String...)} and + * {@link #waitForAny(String...)}. The thread making the call to these blocking methods MUST be the waiter thread (the + * thread registered with the signal object). + * </p> + * <p> + * Some operations are non-blocking. These operations allow for the testing or setting of signal conditions and do not + * block the caller. When calling these methods ({@link #isSignaled(String)}, {@link #signal(String)}, and + * {@link #setTimeout(long)} the waiter thread mutex will be held and may block the waiter thread for the duration of + * the method call. + * </p> + */ +public class Signal { + + /** + * The thread must be the thread of the waiter that is waiting for the signals to be received. It is the recipient + * of the signaled condition. This allows any number of other threads to send signals to the recipient and have the + * recipient synchronize its operation with the receipt of the appropriate signal(s). + */ + private Thread thread; + + /** + * The amount of time to wait for a signal to be receieved. Set to zero to wait forever. + */ + private long timeout = 0L; + + /** + * The collection of all received signals. Note, this need not be a synchronized collection because it will always + * be accessed while holding the mutex of the thread, therefore it is implicitly synchronized. + */ + private List<String> receivedSignals; + + /** + * A signal object must access a thread that is waiting for the receipt of the signal(s). + */ + public Signal(Thread thread) { + this.thread = thread; + receivedSignals = new ArrayList<String>(); + } + + /** + * Checks the waiter to see if it has been signaled + * + * @param signal + * The signal to check for + * @return True if the signal has been received, false otherwise + */ + public boolean isSignaled(String signal) { + synchronized (thread) { + return _signaled(signal); + } + } + + /** + * Sends the indicated signal to the waiter. + * + * @param signal + * The signal that is to be sent to the waiting thread and to notify it to process the signal. + */ + public void signal(String signal) { + synchronized (thread) { + if (!_signaled(signal)) { + receivedSignals.add(signal); + } + thread.notify(); + } + } + + /** + * Blocks the waiting thread until all of the indicated signals have been received, or the wait times out. + * + * @param signals + * The signals to be received. The waiter is blocked forever or until all of the signals are received. + * @throws TimeoutException + * If the wait has timed out waiting for a response + */ + public void waitFor(String... signals) throws TimeoutException { + long limit = System.currentTimeMillis() + timeout; + synchronized (thread) { + while (true) { + boolean complete = true; + for (String signal : signals) { + if (!_signaled(signal)) { + complete = false; + } + } + + if (complete) { + receivedSignals.removeAll(Arrays.asList(signals)); + return; + } + + if (timeout > 0) { + if (System.currentTimeMillis() > limit) { + throw new TimeoutException(String.format("Signals %s not received in the allotted timeout.", + StringHelper.asList(signals))); + } + } + + try { + thread.wait(timeout); + } catch (InterruptedException e) { + /* + * Interrupted exceptions are ignored + */ + } + } + } + } + + /** + * This method blocks the waiter until at least one of the indicated signals have been received. + * + * @param signals + * A list of signals, any one of which will satisfy the wait condition + * @return The signal that satisfied the wait + * @throws TimeoutException + * If none of the signals have been received within the allotted time + */ + public String waitForAny(String... signals) throws TimeoutException { + long limit = System.currentTimeMillis() + timeout; + synchronized (thread) { + while (true) { + for (String signal : signals) { + if (!_signaled(signal)) { + receivedSignals.remove(signal); + return signal; + } + } + + if (timeout > 0) { + if (System.currentTimeMillis() > limit) { + throw new TimeoutException( + String.format("One of signals \"%s\" not received in the allotted timeout.", + StringHelper.asList(signals))); + } + } + + try { + thread.wait(timeout); + } catch (InterruptedException e) { + /* + * Interrupted exceptions are ignored + */ + } + } + } + } + + /** + * This private method is used to handle the check for signaled status. Note that this method assumes the caller + * holds the thread mutex. + * + * @param signals + * The list of signals to check for + * @return True if any one of the signals has been received. + */ + private boolean _signaled(String... signals) { + for (String signal : signals) { + if (receivedSignals.contains(signal)) { + return true; + } + } + return false; + } + + /** + * Sets the timeout value for waiting for signals to be received + * + * @param timeout + */ + public void setTimeout(long timeout) { + this.timeout = timeout; + } +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/configuration/Configuration.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/configuration/Configuration.java new file mode 100644 index 000000000..f64129011 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/configuration/Configuration.java @@ -0,0 +1,240 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.configuration; + +import java.util.Properties; + +import org.slf4j.Logger; + + + +/** + * This interface defines the common configuration support that is available to the application. + * <p> + * Where properties are common to all CDP components (server, coordinator, and EPM), the property symbolic values are + * defined as part of this interface. Where they are unique to each component, they must be defined within that + * component. + * </p> + */ +public interface Configuration { + + String PROPERTY_BOOTSTRAP_FILE_NAME = "org.openecomp.appc.bootstrap.file"; + String DEFAULT_BOOTSTRAP_FILE_NAME = "appc.properties"; + String PROPERTY_BOOTSTRAP_FILE_PATH = "org.openecomp.appc.bootstrap.path"; + String DEFAULT_BOOTSTRAP_FILE_PATH = "${user.home},etc,../etc"; + String PROPERTY_RESOURCE_BUNDLES = "org.openecomp.appc.resources"; + String DEFAULT_RESOURCE_BUNDLES = "org/openecomp/appc/i18n/MessageResources"; + + /** + * This method is called to obtain a property expressed as a boolean value (true or false). The standard rules for + * {@link Boolean#valueOf(String)} are used. + * + * @param key + * The property key + * @return The value of the property expressed as a boolean, or false if it does not exist. + */ + boolean getBooleanProperty(String key); + + /** + * This method is called to obtain a property expressed as a boolean value (true or false). The standard rules for + * {@link Boolean#valueOf(String)} are used. + * + * @param key + * The property key + * @param defaultValue + * The default value to be returned if the property does not exist + * @return The value of the property expressed as a boolean, or false if it does not exist. + */ + boolean getBooleanProperty(String key, boolean defaultValue); + + /** + * Returns the indicated property value expressed as a floating point double-precision value (double). The standard + * rules for {@link Double#valueOf(String)} are used. + * + * @param key + * The property to retrieve + * @return The value of the property, or 0.0 if not found or invalid + */ + double getDoubleProperty(String key); + + /** + * Returns the indicated property value expressed as a floating point double-precision value (double). The standard + * rules for {@link Double#valueOf(String)} are used. + * + * @param key + * The property to retrieve + * @param defaultValue + * The default value to be returned if the property does not exist + * @return The value of the property, or 0.0 if not found or invalid + */ + double getDoubleProperty(String key, double defaultValue); + + /** + * Returns the property indicated expressed as an integer. The standard rules for + * {@link Integer#parseInt(String, int)} using a radix of 10 are used. + * + * @param key + * The property name to retrieve. + * @return The value of the property, or 0 if it does not exist or is invalid. + */ + int getIntegerProperty(String key); + + /** + * Returns the property indicated expressed as an integer. The standard rules for + * {@link Integer#parseInt(String, int)} using a radix of 10 are used. + * + * @param key + * The property name to retrieve. + * @param defaultValue + * The default value to be returned if the property does not exist + * @return The value of the property, or 0 if it does not exist or is invalid. + */ + int getIntegerProperty(String key, int defaultValue); + + /** + * Returns the specified property as a long integer value, if it exists, or zero if it does not. + * + * @param key + * The key of the property desired. + * @return The value of the property expressed as an integer long value, or zero if the property does not exist or + * is not a valid integer long. + */ + long getLongProperty(String key); + + /** + * Returns the specified property as a long integer value, if it exists, or the default value if it does not exist + * or is invalid. + * + * @param key + * The key of the property desired. + * @param defaultValue + * the value to be returned if the property is not valid or does not exist. + * @return The value of the property expressed as an integer long value, or the default value if the property does + * not exist or is not a valid integer long. + */ + long getLongProperty(String key, long defaultValue); + + /** + * This method can be called to retrieve a properties object that is immutable. Any attempt to modify the properties + * object returned will result in an exception. This allows a caller to view the current configuration as a set of + * properties. + * + * @return An unmodifiable properties object. + */ + Properties getProperties(); + + /** + * This method is called to obtain a property as a string value + * + * @param key + * The key of the property + * @return The string value, or null if it does not exist. + */ + String getProperty(String key); + + /** + * This method is called to obtain a property as a string value + * + * @param key + * The key of the property + * @param defaultValue + * The default value to be returned if the property does not exist + * @return The string value, or null if it does not exist. + */ + String getProperty(String key, String defaultValue); + + /** + * Returns true if the named property is defined, false otherwise. + * + * @param key + * The key of the property we are interested in + * @return True if the property exists. + */ + boolean isPropertyDefined(String key); + + /** + * Returns an indication of the validity of the boolean property. A boolean property is considered to be valid only + * if it has the value "true" or "false" (ignoring case). + * + * @param key + * The property to be checked + * @return True if the value is a boolean constant, or false if it does not exist or is not a correct string + */ + boolean isValidBoolean(String key); + + /** + * Returns an indication if the indicated property represents a valid double-precision floating point number. + * + * @param key + * The property to be examined + * @return True if the property is a valid representation of a double, or false if it does not exist or contains + * illegal characters. + */ + boolean isValidDouble(String key); + + /** + * Returns an indication if the property is a valid integer value or not. + * + * @param key + * The key of the property to check + * @return True if the value is a valid integer string, or false if it does not exist or contains illegal + * characters. + */ + boolean isValidInteger(String key); + + /** + * Determines is the specified property exists and is a valid representation of an integer long value. + * + * @param key + * The property to be checked + * @return True if the property is a valid representation of an integer long value, and false if it either does not + * exist or is not valid. + */ + boolean isValidLong(String key); + + /** + * This method allows the caller to set all properties from a provided properties object into the configuration + * property set. + * <p> + * The primary difference between this method and the factory method + * {@link ConfigurationFactory#getConfiguration(Properties)} is that this method does not clear and reload the + * configuration. Rather, this method merges the provided properties object contents into the existing properties, + * replacing any same-named keys with the values from this object. + * </p> + * + * @param properties + * The properties object to copy all properties from + */ + void setProperties(Properties properties); + + /** + * This method allows a caller to insert a new property definition into the configuration object. This allows the + * application to adjust or add to the current configuration. If the property already exists, it is replaced with + * the new value. + * + * @param key + * The key of the property to be defined + * @param value + * The value of the property to be defined + */ + void setProperty(String key, String value); +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/configuration/ConfigurationFactory.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/configuration/ConfigurationFactory.java new file mode 100644 index 000000000..bbfd90de1 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/configuration/ConfigurationFactory.java @@ -0,0 +1,416 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.configuration; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.text.DateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Properties; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; +import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; + +import org.openecomp.appc.i18n.Msg; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; + +/** + * The configuration factory is used to obtain access to an already created and initialized singleton configuration + * object as well as to create and initialize the singleton if not already set up. + * <p> + * This class is responsible for the creation of the configuration object used to manage the configuration of the + * application. The configuration object implementation must implement the <code>Configuration</code> interface. This + * allows for the factory to create different specializations in the future if needed and not break any application + * code. + * </p> + * <p> + * The configuration object is basically a wrapper around a properties object. The configuration is therefore specified + * as a set of properties that are loaded and processed from different sources with different precedences. It is + * important that the configuration object always be able to supply default values for any configuration properties that + * must be supplied, and not rely on the user always supplying these values. This also relieves the application itself + * from having to interpret missing or invalid properties and applying defaults. By having all of the defaults in one + * place, the application code can be simpler (not having to worry about defaults or invalid properties), and the + * defaults can be changed much easier (they are all in one place and not distributed throughout the codebase). + * </p> + * <p> + * Since the configuration is managed as a property object, we can use a characteristic of the <code>Properties</code> + * class to our advantage. Namely, if we put a property into a <code>Properties</code> object that already exists, the + * <code>Properties</code> object replaces it with the new value. This does not affect any other properties that may + * already be defined in the properties object. This gives us the ability to initialize the properties with default + * values for all of the application settings, then override just those that we need to override, possibly from multiple + * sources and in increasing order of precedence. + * </p> + * <p> + * This means that properties are in effect "merged" together from multiple sources in a prescribed precedence order. In + * fact, the precedence order that this factory implements is defined as: + * </p> + * <ol> + * <li>Default values from a system resource file.</li> + * <li>User-supplied properties file, if any.</li> + * <li>Application-supplied properties, if any.</li> + * <li>Command-line properties (if any)</li> + * </ol> + * <p> + * The name and location of the properties file that is loaded can also be set, either in the defaults, overridden by + * the system command line via -D, or as a system environment variable. There are two properties that can be specified + * to define the name and path. These are: + * </p> + * <dl> + * <dt>org.openecomp.appc.bootstrap.file</dt> + * <dd>This property defines the name of the file that will be loaded. If not specified, the default value is + * "appc.properties". This can be specified in either (or both) the default properties or the command line. The command + * line specification will always override.</dd> + * <dt>org.openecomp.appc.bootstrap.path</dt> + * <dd>This is a comma-delimited (,) path of directories to be searched to locate the specified file. The first + * occurrence of the file is the one loaded, and no additional searching is performed. The path can be specified in + * either, or both, the default values and the command line specification. If specified on the command line, the value + * overrides the default values. If omitted, the default path is <code>$/opt/openecomp/appc/data/properties,${user.home},.</code></dd> + * </dl> + * + * @since Mar 18, 2014 + * @version $Id$ + */ +public final class ConfigurationFactory { + + private static final EELFLogger logger = EELFManager.getInstance().getApplicationLogger(); + + /** + * This is a string constant for the comma character. It's intended to be used a common string delimiter. + */ + private static final String COMMA = ","; + + /** + * The default Configuration object that implements the <code>Configuration</code> interface and represents our + * system configuration settings. + */ + private static DefaultConfiguration config = null; + + /** + * The default properties resource to be loaded + */ + private static final String DEFAULT_PROPERTIES = "org/openecomp/appc/default.properties"; + + /** + * This collection allows for special configurations to be created and maintained, organized by some identification + * (such as an object reference to the StackBuilder to which they apply), and then obtained from the configuration + * factory when needed. + */ + private static HashMap<Object, Configuration> localConfigs = new HashMap<Object, Configuration>(); + + /** + * The reentrant shared lock used to serialize access to the properties. + */ + private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + + /** + * This is a constant array of special property names that will be copied from the configuration back to the System + * properties object if they are defined in the configuration AND they do not already exist in the System properties + * object. These are intended as a convenience for setting the AFT properties for the Discovery client where it may + * be difficult or impossible to set VM arguments for the container. + */ + private static final String[] specialProperties = { + "AFT_LATITUDE", "AFT_LONGITUDE", "AFT_ENVIRONMENT", "SCLD_PLATFORM" + }; + + private ConfigurationFactory() { + } + + /** + * This method is used to obtain the common configuration object (as well as set it up if not already). + * + * @return The configuration object implementation + */ + public static Configuration getConfiguration() { + + /* + * First, attempt to access the properties as a read lock holder + */ + ReadLock readLock = lock.readLock(); + readLock.lock(); + try { + + /* + * If the properties don't exist, release the read lock and acquire the write lock. Once we get the write + * lock, we need to re-check to see that the configuration needs to be set up (because another thread may + * have beat us to it). After we get a configuration set up, release the write lock and re-obtain the read + * lock to access the properties. + */ + if (config == null) { + readLock.unlock(); + WriteLock writeLock = lock.writeLock(); + writeLock.lock(); + try { + if (config == null) { + config = new DefaultConfiguration(); + initialize(null); + } + } catch (Exception t) { + logger.error("getConfiguration", t); + } finally { + writeLock.unlock(); + } + readLock.lock(); + } + return config; + } finally { + readLock.unlock(); + } + } + + /** + * This method will obtain the local configuration for the specified object if it exists, or will create it from the + * current global configuration. This allows the configuration to be tailored for a specific process or operation, + * and uniquely identified by some value (such as the object that represents the special use of the configuration). + * + * @param owner + * The owner or identification of the owner of the special configuration + * @return The special configuration object, or a clone of the global configuration so that it can be altered if + * needed. + */ + public static Configuration getConfiguration(final Object owner) { + ReadLock readLock = lock.readLock(); + readLock.lock(); + try { + DefaultConfiguration local = (DefaultConfiguration) localConfigs.get(owner); + if (local == null) { + readLock.unlock(); + WriteLock writeLock = lock.writeLock(); + writeLock.lock(); + try { + local = (DefaultConfiguration) localConfigs.get(owner); + if (local == null) { + DefaultConfiguration global = (DefaultConfiguration) getConfiguration(); + try { + local = (DefaultConfiguration) global.clone(); + } catch (CloneNotSupportedException e) { + logger.error("getConfiguration", e); + } + localConfigs.put(owner, local); + } + } finally { + writeLock.unlock(); + } + readLock.lock(); + } + return local; + } finally { + readLock.unlock(); + } + } + + /** + * This method allows the caller to alter the configuration, supplying the specified configuration properties which + * override the application default values. + * <p> + * The configuration is re-constructed (if already constructed) or created new (if not already created) and the + * default properties are loaded into the configuration. + * </p> + * <p> + * The primary purpose of this method is to allow the application configuration properties to be reset or refreshed + * after the application has already been initialized. This method will lock the configuration for the duration + * while it is being re-built, and should not be called on a regular basis. + * </p> + * + * @param props + * The properties used to configure the application. + * @return Access to the configuration implementation + */ + public static Configuration getConfiguration(final Properties props) { + WriteLock writeLock = lock.writeLock(); + writeLock.lock(); + try { + config = new DefaultConfiguration(); + initialize(props); + return config; + } finally { + writeLock.unlock(); + } + } + + /** + * This method will clear the current configuration and then re-initialize it with the default values, + * application-specific configuration file, user-supplied properties (if any), and then command-line settings. + * <p> + * This method <strong><em>MUST</em></strong> be called holding the configuration lock! + * </p> + * <p> + * This method is a little special in that logging messages generated during the method must be cached and delayed + * until after the logging framework has been initialized. After that, the delayed logging buffer can be dumped to + * the log file and cleared. + * </p> + * + * @param props + * Application-supplied configuration values, if any + */ + private static void initialize(final Properties props) { + DateFormat format = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG); + Date now = new Date(); + logger.info("------------------------------------------------------------------------------"); + + logger.info(Msg.CONFIGURATION_STARTED, format.format(now)); + + /* + * Clear any existing properties + */ + config.clear(); + logger.info(Msg.CONFIGURATION_CLEARED); + + /* + * Load the defaults (if any are present) + */ + InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(DEFAULT_PROPERTIES); + if (in != null) { + logger.info(Msg.LOADING_DEFAULTS, DEFAULT_PROPERTIES); + try { + config.setProperties(in); + } finally { + try { + in.close(); + } catch (IOException e) { + // not much we can do since logger may not be configured yet + e.printStackTrace(System.out); + } + } + for (String key : config.getProperties().stringPropertyNames()) { + logger.info(Msg.PROPERTY_VALUE, key, config.getProperty(key)); + } + } else { + logger.info(Msg.NO_DEFAULTS_FOUND, DEFAULT_PROPERTIES); + } + + /* + * Look for application configuration property file. By default, we will look for the file "cdp.properties" on + * the user home path, then on "./etc" (relative to current path), then on "../etc" (relative to current path). + * If we do not find any property file, then we continue. Otherwise, we load the first property file we find and + * then continue. In order to allow default values for the filename and paths to be searched, we first attempt + * to obtain these from our configuration object (which should be primed with default values and/or overridden + * with application-specified values). We then use the values obtained from that to get any user supplied values + * on the command line. + */ + String filename = + config.getProperty(Configuration.PROPERTY_BOOTSTRAP_FILE_NAME, Configuration.DEFAULT_BOOTSTRAP_FILE_NAME); + filename = System.getProperty(Configuration.PROPERTY_BOOTSTRAP_FILE_NAME, filename); + String env = System.getenv(Configuration.PROPERTY_BOOTSTRAP_FILE_NAME); + if (env != null && env.trim().length() > 0) { + filename = env; + } + + String path = + config.getProperty(Configuration.PROPERTY_BOOTSTRAP_FILE_PATH, Configuration.DEFAULT_BOOTSTRAP_FILE_PATH); + path = System.getProperty(Configuration.PROPERTY_BOOTSTRAP_FILE_PATH, path); + env = System.getenv(Configuration.PROPERTY_BOOTSTRAP_FILE_PATH); + if (env != null && env.trim().length() > 0) { + path = env; + } + + logger.info(Msg.SEARCHING_CONFIGURATION_OVERRIDES, path, filename); + + String[] pathElements = path.split(COMMA); + boolean found = false; + for (String pathElement : pathElements) { + File file = new File(pathElement, filename); + if (file.exists() && file.canRead() && !file.isDirectory()) { + + logger.info(Msg.LOADING_CONFIGURATION_OVERRIDES, file.getAbsolutePath()); + Properties fileProperties = new Properties(); + BufferedInputStream stream = null; + try { + stream = new BufferedInputStream(new FileInputStream(file)); + fileProperties.load(stream); + for (String key : fileProperties.stringPropertyNames()) { + logger.debug(Msg.PROPERTY_VALUE, key, fileProperties.getProperty(key)); + config.setProperty(key, fileProperties.getProperty(key)); + } + found = true; + break; + } catch (IOException e) { + logger.error(EELFResourceManager.format(e)); + } finally { + try { + stream.close(); + } catch (IOException e) { + // not much we can do since logger may not be configured + // yet + e.printStackTrace(System.out); + } + } + } + } + + if (!found) { + logger.warn(Msg.NO_OVERRIDE_PROPERTY_FILE_LOADED, filename, path); + } + + /* + * Apply any application-specified properties + */ + if (props != null) { + logger.info(Msg.LOADING_APPLICATION_OVERRIDES); + for (String key : props.stringPropertyNames()) { + logger.debug(Msg.PROPERTY_VALUE, key, props.getProperty(key)); + config.setProperty(key, props.getProperty(key)); + } + } else { + logger.info(Msg.NO_APPLICATION_OVERRIDES); + } + + /* + * Merge in the System.properties to pick-up any command line arguments (-Dkeyword=value) + */ + logger.info(Msg.MERGING_SYSTEM_PROPERTIES); + config.setProperties(System.getProperties()); + + /* + * As a convenience, copy the "specialProperties" that are not defined in System.properties from the + * configuration back to the system properties object. + */ + for (String key : config.getProperties().stringPropertyNames()) { + for (String specialProperty : specialProperties) { + if (key.equals(specialProperty) && !System.getProperties().containsKey(key)) { + System.setProperty(key, config.getProperty(key)); + logger.info(Msg.SETTING_SPECIAL_PROPERTY, key, config.getProperty(key)); + } + } + } + + /* + * Initialize the resource manager by loading the requested bundles, if any are defined. Resource bundles may be + * specified as a comma-delimited list of names. These resource names are base names of resource bundles, do not + * include the language or country code, or the ".properties" extension. The actual loading of the resource + * bundles is done lazily when requested the first time. If the bundle does not exist, or cannot be loaded, it + * is ignored. + */ + String resourcesList = + config.getProperty(Configuration.PROPERTY_RESOURCE_BUNDLES, Configuration.DEFAULT_RESOURCE_BUNDLES); + String[] resources = resourcesList.split(","); + for (String resource : resources) { + logger.info(Msg.LOADING_RESOURCE_BUNDLE, resource.trim()); + EELFResourceManager.loadMessageBundle(resource.trim()); + } + } +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/configuration/DefaultConfiguration.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/configuration/DefaultConfiguration.java new file mode 100644 index 000000000..7af491724 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/configuration/DefaultConfiguration.java @@ -0,0 +1,578 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.configuration; + + + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.security.CodeSource; +import java.security.ProtectionDomain; +import java.security.Provider; +import java.security.Provider.Service; +import java.security.Security; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.jar.JarFile; +import java.util.jar.Manifest; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.openecomp.appc.encryption.EncryptionTool; +import org.openecomp.appc.util.UnmodifiableProperties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class provides the implementation of the <code>Configuration</code> interface. It is created by the + * ConfigurationFactory and initialized with the configuration values for the process. + * + * @since Mar 18, 2014 + * @version $Id$ + */ +public final class DefaultConfiguration implements Configuration, Cloneable { + + private static final Logger logger = LoggerFactory.getLogger(DefaultConfiguration.class); + + /** + * The framework configuration properties. + */ + private Properties properties = new Properties(); + + /** + * Construct the configuration object. + */ + public DefaultConfiguration() { + } + + /** + * Clears all properties + */ + public void clear() { + properties.clear(); + } + + /** + * @see java.lang.Object#clone() + */ + @Override + protected Object clone() throws CloneNotSupportedException { + DefaultConfiguration clone = (DefaultConfiguration) super.clone(); + + clone.properties = new Properties(this.properties); + clone.properties.putAll(this.properties); + + return clone; + } + + /** + * Decrypts an encrypted value, if it is encrypted, and returns the clear text. Performs no operation on the string + * if it is not encrypted. + * + * @param value + * The value to (optionally) be decrypted + * @return The clear text + */ + @SuppressWarnings("nls") + private static String decrypt(String value) { + if (value != null) { + if (value.startsWith(EncryptionTool.ENCRYPTED_VALUE_PREFIX)) { + try { + return EncryptionTool.getInstance().decrypt(value); + } catch (Throwable e) { + String out = ""; + for (Provider p : Security.getProviders()) { + for (Service s : p.getServices()) { + String algo = s.getAlgorithm(); + out += + String.format("\n==Found Algorithm [ %s ] in provider [ %s ] and service [ %s ]", algo, + p.getName(), s.getClassName()); + } + } + logger.debug(out); + logger.warn(String.format("Could not decrypt the configuration value [%s]", value), e); + } + } + } + return value; + } + + /** + * Decrypts all elements in the properties object + */ + private void decryptAllProperties() { + if (properties != null) { + for (Entry<Object, Object> e : properties.entrySet()) { + if (e.getValue() != null) { + e.setValue(decrypt(e.getValue().toString())); + } + } + } + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + DefaultConfiguration other = (DefaultConfiguration) obj; + + if ((this.properties.size() == other.properties.size()) + && (this.properties.entrySet().containsAll(other.properties.entrySet())) + && (other.properties.entrySet().containsAll(this.properties.entrySet()))) { + return true; + } + + return false; + } + + /** + * This method will use the properties object to expand any variables that may be present in the template provided. + * Variables are represented by the string "${name}", where "name" is the name of a property defined in either the + * current configuration object, or system properties if undefined. If the value cannot be found, the variable is + * removed and an empty string is used to replace the variable. + * + * @param template + * The template to be expanded + * @return The expanded template where each variable is replaced with its value + */ + @SuppressWarnings("nls") + private String expandVariables(String template) { + if (template == null) { + return template; + } + + // Decrypt the template if needed + // template = decrypt(template); DH: Do not assign values to parameters, bad form! Also, Sonar complains + // bitterly + + StringBuffer buffer = new StringBuffer(decrypt(template)); + Pattern pattern = Pattern.compile("\\$\\{([^\\}]+)\\}"); + Matcher matcher = pattern.matcher(buffer); + while (matcher.find()) { + String variable = matcher.group(1); + String value = properties.getProperty(variable); + if (value == null) { + value = System.getProperty(variable); + } + if (value == null) { + value = ""; + } + buffer.replace(matcher.start(), matcher.end(), value); + + matcher.reset(); + } + return buffer.toString().trim(); + } + + /** + * This method is called to obtain a property expressed as a boolean value (true or false). The standard rules for + * Boolean.parseBoolean() are used. + * + * @param key + * The property key + * @return The value of the property expressed as a boolean, or false if it does not exist. + */ + @SuppressWarnings("nls") + @Override + public boolean getBooleanProperty(String key) { + return Boolean.valueOf(getProperty(key, "false")).booleanValue(); + } + + /** + * This method is called to obtain a property expressed as a boolean value (true or false). The standard rules for + * Boolean.valueOf(String) are used. + * + * @param key + * The property key + * @param defaultValue + * The default value to be returned if the property does not exist + * @return The value of the property expressed as a boolean, or false if it does not exist. + * @see org.openecomp.appc.configuration.Configuration#getBooleanProperty(java.lang.String, boolean) + */ + @Override + public boolean getBooleanProperty(String key, boolean defaultValue) { + if (isPropertyDefined(key)) { + return getBooleanProperty(key); + } + return defaultValue; + } + + /** + * Returns the indicated property value expressed as a floating point double-precision value (double). + * + * @param key + * The property to retrieve + * @return The value of the property, or 0.0 if not found + * @see org.openecomp.appc.configuration.Configuration#getDoubleProperty(java.lang.String) + */ + @SuppressWarnings("nls") + @Override + public double getDoubleProperty(String key) { + try { + return Double.valueOf(getProperty(key, "0.0")).doubleValue(); + } catch (NumberFormatException e) { + return 0.0; + } + } + + /** + * This method is called to obtain a property as a string value + * + * @param key + * The key of the property + * @param defaultValue + * The default value to be returned if the property does not exist + * @return The string value, or null if it does not exist. + * @see org.openecomp.appc.configuration.Configuration#getDoubleProperty(java.lang.String, double) + */ + @Override + public double getDoubleProperty(String key, double defaultValue) { + if (isPropertyDefined(key)) { + return getDoubleProperty(key); + } + return defaultValue; + } + + /** + * Returns the property indicated expressed as an integer. The standard rules for + * {@link Integer#parseInt(String, int)} using a radix of 10 are used. + * + * @param key + * The property name to retrieve. + * @returns The value of the property, or 0 if it does not exist or is invalid. + * @see org.openecomp.appc.configuration.Configuration#getIntegerProperty(java.lang.String) + */ + @SuppressWarnings("nls") + @Override + public int getIntegerProperty(String key) { + try { + return Integer.parseInt(getProperty(key, "0"), 10); + } catch (NumberFormatException e) { + return 0; + } + } + + /** + * Returns the property indicated expressed as an integer. The standard rules for Integer.parseInt(String, int) + * using a radix of 10 are used. + * + * @param key + * The property name to retrieve. + * @param defaultValue + * The default value to be returned if the property does not exist + * @return The value of the property, or 0 if it does not exist or is invalid. + * @see org.openecomp.appc.configuration.Configuration#getIntegerProperty(java.lang.String, int) + */ + @Override + public int getIntegerProperty(String key, int defaultValue) { + if (isPropertyDefined(key)) { + return getIntegerProperty(key); + } + return defaultValue; + } + + /** + * Returns the specified property as a long integer value, if it exists, or zero if it does not. + * + * @param key + * The key of the property desired. + * @return The value of the property expressed as an integer long value, or zero if the property does not exist or + * is not a valid integer long. + * @see org.openecomp.appc.configuration.Configuration#getLongProperty(java.lang.String) + */ + @SuppressWarnings("nls") + @Override + public long getLongProperty(String key) { + try { + return Long.parseLong(getProperty(key, "0"), 10); + } catch (NumberFormatException e) { + return 0; + } + } + + /** + * Returns the specified property as a long integer value, if it exists, or the default value if it does not exist + * or is invalid. + * + * @param key + * The key of the property desired. + * @param defaultValue + * the value to be returned if the property is not valid or does not exist. + * @return The value of the property expressed as an integer long value, or the default value if the property does + * not exist or is not a valid integer long. + * @see org.openecomp.appc.configuration.Configuration#getLongProperty(java.lang.String, long) + */ + @Override + public long getLongProperty(String key, long defaultValue) { + if (isPropertyDefined(key)) { + return getLongProperty(key); + } + return defaultValue; + } + + /** + * This method can be called to retrieve a properties object that is immutable. Any attempt to modify the properties + * object returned will result in an exception. This allows a caller to view the current configuration as a set of + * properties. + * + * @return An unmodifiable properties object. + * @see org.openecomp.appc.configuration.Configuration#getProperties() + */ + @Override + public Properties getProperties() { + return new UnmodifiableProperties(properties); + } + + /** + * This method is called to obtain a property as a string value + * + * @param key + * The key of the property + * @return The string value, or null if it does not exist. + */ + @Override + public String getProperty(String key) { + String value = properties.getProperty(key); + if (value == null) { + return null; + } + return expandVariables(value.trim()); + } + + /** + * This method is called to obtain a property as a string value + * + * @param key + * The key of the property + * @param defaultValue + * The default value to be returned if the property does not exist + * @return The string value, or null if it does not exist. + * @see org.openecomp.appc.configuration.Configuration#getProperty(java.lang.String, java.lang.String) + */ + @Override + public String getProperty(String key, String defaultValue) { + if (isPropertyDefined(key)) { + return getProperty(key); + } + + if (defaultValue == null) { + return null; + } + + return expandVariables(defaultValue.trim()); + } + + /** + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return (properties == null ? 0 : properties.hashCode()); + } + + /** + * Returns true if the named property is defined, false otherwise. + * + * @param key + * The key of the property we are interested in + * @return True if the property exists. + */ + @Override + public boolean isPropertyDefined(String key) { + return properties.containsKey(key); + } + + /** + * Returns an indication of the validity of the boolean property. A boolean property is considered to be valid only + * if it has the value "true" or "false" (ignoring case). + * + * @param key + * The property to be checked + * @returns True if the value is a boolean constant, or false if it does not exist or is not a correct string + * @see org.openecomp.appc.configuration.Configuration#isValidBoolean(java.lang.String) + */ + @SuppressWarnings("nls") + @Override + public boolean isValidBoolean(String key) { + String value = getProperty(key); + if (value != null) { + value = value.toLowerCase(); + return value.matches("true|false"); + } + return false; + } + + /** + * Returns an indication if the indicated property represents a valid double-precision floating point number. + * + * @param key + * The property to be examined + * @returns True if the property is a valid representation of a double, or false if it does not exist or contains + * illegal characters. + * @see org.openecomp.appc.configuration.Configuration#isValidDouble(java.lang.String) + */ + @Override + public boolean isValidDouble(String key) { + String value = getProperty(key); + if (value != null) { + try { + Double.valueOf(value); + return true; + } catch (NumberFormatException e) { + return false; + } + } + return false; + } + + /** + * Returns an indication if the property is a valid integer value or not. + * + * @param key + * The key of the property to check + * @returns True if the value is a valid integer string, or false if it does not exist or contains illegal + * characters. + * @see org.openecomp.appc.configuration.Configuration#isValidInteger(java.lang.String) + */ + @Override + public boolean isValidInteger(String key) { + String value = getProperty(key); + if (value != null) { + try { + Integer.parseInt(value.trim(), 10); + return true; + } catch (NumberFormatException e) { + return false; + } + } + return false; + } + + /** + * Determines is the specified property exists and is a valid representation of an integer long value. + * + * @param key + * The property to be checked + * @return True if the property is a valid representation of an integer long value, and false if it either does not + * exist or is not valid. + * @see org.openecomp.appc.configuration.Configuration#isValidLong(java.lang.String) + */ + @Override + public boolean isValidLong(String key) { + String value = getProperty(key); + if (value != null) { + try { + Long.parseLong(value.trim(), 10); + return true; + } catch (NumberFormatException e) { + return false; + } + } + return false; + } + + /** + * This method allows an implementation to load configuration properties that may override default values. + * + * @param is + * An input stream that contains the properties to be loaded + */ + public void setProperties(InputStream is) { + try { + properties.load(is); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * This method allows an implementation to load configuration properties that may override default values. + * + * @param props + * An optional Properties object to be merged into the configuration, replacing any same-named + * properties. + * @see org.openecomp.appc.configuration.Configuration#setProperties(java.util.Properties) + */ + @Override + public void setProperties(Properties props) { + properties.putAll(props); + decryptAllProperties(); + } + + /** + * This method allows a caller to insert a new property definition into the configuration object. This allows the + * application to adjust or add to the current configuration. If the property already exists, it is replaced with + * the new value. + * + * @param key + * The key of the property to be defined + * @param value + * The value of the property to be defined + * @see org.openecomp.appc.configuration.Configuration#setProperty(java.lang.String, java.lang.String) + */ + @Override + public void setProperty(String key, String value) { + properties.setProperty(key, decrypt(value)); + } + + /** + * @see java.lang.Object#toString() + */ + @SuppressWarnings("nls") + @Override + public String toString() { + return String.format("Configuration: %d properties, keys:[%s]", properties.size(), properties.keySet() + .toString()); + } + + /** + * This is a helper method to read the manifest of the jar file that this class was loaded from. Note that this will + * only work if the code is packaged in a jar file. If it is an open deployment, such as under eclipse, this will + * not work and there is code added to detect that case. + * + * @return The manifest object from the jar file, or null if the code is not packaged in a jar file. + */ + @SuppressWarnings({ + "unused", "nls" + }) + private Manifest getManifest() { + ProtectionDomain domain = getClass().getProtectionDomain(); + CodeSource source = domain.getCodeSource(); + URL location = source.getLocation(); + String path = location.getPath(); + int index = path.indexOf('!'); + if (index != -1) { + path = path.substring(0, index); + } + if (path.endsWith(".jar")) { + try (JarFile jar = new JarFile(location.getFile())) { + return jar.getManifest(); + } catch (IOException e) { + logger.error("getManifest", e); + } + } + + return null; + } +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/configuration/package.html b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/configuration/package.html new file mode 100644 index 000000000..4460a9e5c --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/configuration/package.html @@ -0,0 +1,170 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<html> +<head> +<title>Configuration</title> +</head> + +<body> + <p style="margin-left: 30.0px;"> + CDP Configuration support is provided by a common framework to load + and manage configuration properties from multiple sources. The basic + concept is to load a set of default properties from a known resource + file located on the class path, and then override these defaults + with optional settings that can be provided by a user through either + additional property files or via the command line (as VM arguments). + The loading of defaults from a resource property file (named <strong>com/att/cdp/default.properties</strong>) + ensures that values are defined for properties the application needs + in order to operate. + </p> + <p style="margin-left: 30.0px;"> + One of these default values that can be set is the name of the + property file that allows the user to supply settings, as well as + the path where the file can be found. In general, the default name + of the property file will be "<strong>cdp.properties</strong>", + and the path that will be searched is "<strong>${user.home};etc;../etc</strong>". + However, these values can be changed through the use of the + default.properties resource file. The property that specifies the + property file name is named <strong>com.att.cdp.bootstrap.file</strong>, + while the property named <strong>com.att.cdp.bootstrap.path</strong> + specifies the search path. + </p> + <p style="margin-left: 30.0px;"> + After the default.properties are loaded, but prior to searching for + the application configuration file, the configuration factory checks + for properties <strong>com.att.cdp.bootstrap.path</strong> and <strong>com.att.cdp.bootstrap.file + </strong>in the System properties object (meaning they were set by the + command line). If these values are defined in the system properties + object, they are used. If not, these values are obtained from the + default properties just loaded. This allows the specification of + either the file name or path, or both, to be overridden during start + up by using command-line arguments. + </p> + <p style="margin-left: 30.0px;">The search path is scanned for the + first occurrence of the specified property file. The first + occurrence is loaded and scanning is stopped at that point. The + configuration factory does not load all occurrences it finds, only + the first occurrence it finds.</p> + <p style="margin-left: 30.0px;">The configuration properties are + loaded and processed according to a defined precedence order, such + that properties defined with a higher precedence override the same + property at a lower precedence. The precedence order is defined as + follows:</p> + <h2>Precedence Order</h2> + <ol> + <li>Default properties are initially loaded into the + configuration. These default properties are the lowest level + precedence, and will be overridden by any properties specified at + higher levels. These are loaded from resources that are packaged + as part of the various application components. Each component + (Server, Coordinator, EPM, or CLI) may have different default + properties. The default properties are loaded from a resource + named <strong>com/att/cdp/default.properties</strong>. The default + properties can specify the name of the application property file + to be used to configure the application, as well as the path to + search. Additionally, these properties can be supplied via the + command line to override the default settings if needed.<br /> <br /> + </li> + <li>The configuration factory allows for the application to + supply an initial properties object to initialize the + configuration. This properties object could be loaded or created + in any way necessary for the application. This is totally up to + the application to define, if it is needed. If no + application-specific property object is supplied, this step is + skipped. If a property object is supplied, it is used to replace + or set any properties that may have been defined by the defaults.<br /> + <br /> + </li> + <li>The configuration factory will then search for a bootstrap + file on a bootstrap path. The actual bootstrap file name and path + can be specified as properties on the command line, or will + default to a file name of <strong>cdp.properties</strong> and a + path of <strong>${user.home};etc;../etc</strong>. If desired, the + user can specify the exact name of the property file to be loaded + as well as the path using <strong>-Dcom.att.cdp.bootstrap.file=<filename></strong> + and <strong>-Dcom.att.cdp.bootstrap.path=<path></strong>. + These properties are set to default values by the default + properties loaded in step #1 above. The first occurrence of a + property file is the file loaded and used. Any other occurrences + are not processed.<br /> <br /> + </li> + <li>The System properties are then merged into the + configuration. This allows the highest level of precedence, + command-line VM arguments (-D<strong>name=value</strong>) to be + merged into the configuration property object. These settings + override all lower level settings of the same name, as well as + merge all system properties into the configuration object. + </li> + </ol> + <h2>Variables</h2> + <p style="margin-left: 30.0px;"> + The configuration support allows for variables to be inserted into + any property that is defined. Variables are named using the format <strong>${name}</strong>, + where the "name" is the name of a property that is defined + in the configuration, or a system property (such as <strong>user.home</strong>). + Variables can nest, such that a variable can be replaced with + another variable, which is then reevaluated to obtain the value. + This allows for indirection as well as variable substitution, if + needed. + </p> + <h2>Using the Configuration Support</h2> + <p style="margin-left: 30.0px;"> + The configuration support was designed to be easy to use. The + configuration implementation is abstracted away from the application + so that it could be changed easily in the future if needed, or if we + needed to load different implementations for different reasons. This + means that the application always accesses the configuration through + an interface, named <strong>Configuration</strong>. The + implementation of that configuration interface is obtained by a + static method on the <strong>ConfigurationFactory</strong> class. + The configuration factory will both create the configuration if not + already created on the first access, as well as return the current + configuration if already created. Additionally, the + ConfigurationFactory provides mechanisms to recreate the + configuration after the application is initialized should the need + arise to update its configuration. + </p> + <p style="margin-left: 30.0px;">An example of the code needed to + obtain access to the configuration is:</p> + <pre style="margin-left: 30.0px;">Configuration config = ConfigurationFactory.getConfiguration();</pre> + <p style="margin-left: 30.0px;">Please refer to the javadoc or the + source code in cdp-common for other ways that the configuration and + configuration factory can be used.</p> + <h2>Reloading Properties</h2> + <p style="margin-left: 30.0px;">The configuration support allows + for properties to be re-loaded and re-evaluated after the + application is running. This is designed to allow a configuration to + be refreshed should the need arise. This could allow on-demand + refresh (via a command, for example), or automatically based on + sensing a change in the configuration file.</p> + <p style="margin-left: 30.0px;"> + When the <strong>ConfigurationFactory</strong> method <strong>getConfiguration(Propert</strong><strong>ies)</strong> + is called, the current configuration is cleared and rebuilt using + the process defined above. The supplied property object is used in + step #2 of the process. While the properties are being re-built, no + access to the properties are allowed. Any attempt to access + properties while the re-build operation is in effect will block the + caller until completed. This is accomplished using read and write + shared locks. + </p> +</body> +</html> diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/encryption/EncryptionException.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/encryption/EncryptionException.java new file mode 100644 index 000000000..c21abc2b9 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/encryption/EncryptionException.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.encryption; + +public class EncryptionException extends RuntimeException { + + /** + * + */ + private static final long serialVersionUID = 8259594446628138378L; + + public EncryptionException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/encryption/EncryptionTool.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/encryption/EncryptionTool.java new file mode 100644 index 000000000..088fc8570 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/encryption/EncryptionTool.java @@ -0,0 +1,215 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.encryption; + +import java.security.Provider; +import java.security.Provider.Service; +import java.security.Security; + +import javax.crypto.Cipher; + +import org.jasypt.contrib.org.apache.commons.codec_1_3.binary.Base64; +import org.jasypt.util.text.BasicTextEncryptor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is used to encapsulate the encryption and decryption support in one place and to provide a utility to + * encrypt and decrypt data. + */ +public class EncryptionTool { + + /** + * This lock object is used ONLY if the singleton has not been set up. + */ + private static final Object lock = new Object(); + + /** + * The salt is used to initialize the PBE (password Based Encrpytion) algorithm. + */ + private static final byte[] DEFAULT_SALT = { + (byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c, (byte) 0x7e, (byte) 0xc8, (byte) 0xee, (byte) 0x99 + }; + + /** + * The prefix we insert onto any data we encrypt so that we can tell if it is encrpyted later and therefore decrypt + * it + */ + @SuppressWarnings("nls") + public static final String ENCRYPTED_VALUE_PREFIX = "enc:"; + + /** + * The instance of the encryption utility object + */ + private static EncryptionTool instance = null; + + /** + * The iteration count used to initialize the PBE algorithm and to generate the key spec + */ + private static final int ITERATION_COUNT = 20; + + /** + * The logger for this class. + */ + private static final Logger LOG = LoggerFactory.getLogger(EncryptionTool.class); + + /** + * The secret passphrase (PBE) that we use to perform encryption and decryption. The algorithm we are using is a + * symmetrical cipher. + */ + private static char[] secret = { + 'C', '_', 'z', 'l', '!', 'K', '!', '4', '?', 'O', 'z', 'E', 'K', 'E', '>', 'U', 'R', '/', '%', 'Y', '\\', 'f', + 'b', '"', 'e', 'n', '{', '"', 'l', 'U', 'F', '+', 'E', '\'', 'R', 'T', 'p', '1', 'V', '4', 'l', 'a', '9', 'w', + 'v', '5', 'Z', '#', 'i', 'V', '"', 'd', 'l', '!', 'L', 'M', 'g', 'L', 'Q', '{', 'v', 'v', 'K', 'V' + }; + + /** + * The algorithm to encrypt and decrpyt data is "Password (or passphrase) Based Encryption with Message Digest #5 + * and the Data Encryption Standard", i.e., PBEWithMD5AndDES. + */ + @SuppressWarnings("nls") + private static final String SECURITY_ALGORITHM = "PBEWITHMD5AND256BITAES";// "PBEWithMD5AndDES"; + + /** + * The decryption cipher object + */ + private Cipher decryptCipher = null; + + /** + * The encryption cipher object + */ + private Cipher encryptCipher = null; + + private BasicTextEncryptor encryptor; + + /** + * Get an instance of the EncryptionTool + * + * @return The encryption tool to be used + */ + public static final EncryptionTool getInstance() { + if (instance == null) { + synchronized (lock) { + if (instance == null) { + instance = new EncryptionTool(); + } + } + } + return instance; + } + + /** + * Create the EncryptionTool instance + */ + @SuppressWarnings("nls") + private EncryptionTool() { + // encryptor = new BasicTextEncryptor(); + // encryptor.setPassword(secret.toString()); + String out = "Found the following security algorithms:"; + for (Provider p : Security.getProviders()) { + for (Service s : p.getServices()) { + String algo = s.getAlgorithm(); + out += + String.format("\n -Algorithm [ %s ] in provider [ %s ] and service [ %s ]", algo, p.getName(), + s.getClassName()); + } + } + LOG.debug(out); + } + + /** + * Decrypt the provided encrypted text + * + * @param cipherText + * THe cipher text to be decrypted. If the ciphertext is not encrypted, then it is returned as is. + * @return the clear test of the (possibly) encrypted value. The original value if the string is not encrypted. + */ + @SuppressWarnings("nls") + public synchronized String decrypt(String cipherText) { + if (isEncrypted(cipherText)) { + String encValue = cipherText.substring(ENCRYPTED_VALUE_PREFIX.length()); + // return encryptor.decrypt(encValue); + byte[] plainByte = Base64.decodeBase64(encValue.getBytes()); + byte[] decryptByte = xorWithSecret(plainByte); + return new String(decryptByte); + } else { + return cipherText; + } + + } + + /** + * Encrypt the provided clear text + * + * @param clearText + * The clear text to be encrypted + * @return the encrypted text. If the clear text is empty (null or zero length), then an empty string is returned. + * If the clear text is already encrypted, it is not encrypted again and is returned as is. Otherwise, the + * clear text is encrypted and returned. + */ + @SuppressWarnings("nls") + public synchronized String encrypt(String clearText) { + if (clearText != null) { + byte[] encByte = xorWithSecret(clearText.getBytes()); + String encryptedValue = new String(Base64.encodeBase64(encByte)); + return ENCRYPTED_VALUE_PREFIX + encryptedValue; + } else { + return null; + } + } + + /** + * Is a value encrypted? A value is considered to be encrypted if it begins with the + * {@linkplain #ENCRYPTED_VALUE_PREFIX encrypted value prefix}. + * + * @param value + * the value to check. + * @return true/false; + */ + private static boolean isEncrypted(final String value) { + return value != null && value.startsWith(ENCRYPTED_VALUE_PREFIX); + } + + /** + * XORs the input byte array with the secret key, padding 0x0 to the end of the secret key if the input is longer + * and returns a byte array the same size as input + * + * @param inp + * The byte array to be XORed with secret + * @return A byte array the same size as inp or null if input is null. + */ + private byte[] xorWithSecret(byte[] inp) { + if (inp == null) { + return null; + } + + byte[] secretBytes = new String(secret).getBytes(); + int size = inp.length; + + byte[] out = new byte[size]; + for (int i = 0; i < size; i++) { + out[i] = (byte) ((inp[i]) ^ (secretBytes[i % secretBytes.length])); + } + return out; + } + +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/encryption/HexHelper.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/encryption/HexHelper.java new file mode 100644 index 000000000..01a602cf4 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/encryption/HexHelper.java @@ -0,0 +1,149 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.encryption; + +import java.util.HashMap; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * HexHelper utility used for encryption/decryption + */ +public final class HexHelper { + + @SuppressWarnings({ + "javadoc", "nls" + }) + public static final String CM_PATH = "@(#) [viewpath]/[item]"; + + @SuppressWarnings({ + "nls", "javadoc" + }) + public static final String CM_PROJECT = "@(#) [environment] [baseline]"; + + @SuppressWarnings({ + "javadoc", "nls" + }) + public static final String CM_VERSION = "@(#) [version] [crtime]"; + + private static final char[] HEX_TABLE = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', + 'E', 'F' }; + + /** + * The logger for this class. + */ + private static final Logger LOG = LoggerFactory.getLogger(HexHelper.class); + + private static Map<Character, Integer> TextToHex; + + static { + TextToHex = new HashMap<>(); + TextToHex.put(Character.valueOf('0'), Integer.valueOf(0)); + TextToHex.put(Character.valueOf('1'), Integer.valueOf(1)); + TextToHex.put(Character.valueOf('2'), Integer.valueOf(2)); + TextToHex.put(Character.valueOf('3'), Integer.valueOf(3)); + TextToHex.put(Character.valueOf('4'), Integer.valueOf(4)); + TextToHex.put(Character.valueOf('5'), Integer.valueOf(5)); + TextToHex.put(Character.valueOf('6'), Integer.valueOf(6)); + TextToHex.put(Character.valueOf('7'), Integer.valueOf(7)); + TextToHex.put(Character.valueOf('8'), Integer.valueOf(8)); + TextToHex.put(Character.valueOf('9'), Integer.valueOf(9)); + TextToHex.put(Character.valueOf('A'), Integer.valueOf(10)); + TextToHex.put(Character.valueOf('B'), Integer.valueOf(11)); + TextToHex.put(Character.valueOf('C'), Integer.valueOf(12)); + TextToHex.put(Character.valueOf('D'), Integer.valueOf(13)); + TextToHex.put(Character.valueOf('E'), Integer.valueOf(14)); + TextToHex.put(Character.valueOf('F'), Integer.valueOf(15)); + } + + /** + * Default private constructor prevents instantiation + */ + private HexHelper() { + // no-op + } + + /** + * Converts an array of bytes to the equivalent string representation using hexadecimal notation and returning that + * representation in a StringBuffer. + * + * @param bytes + * The bytes to be converted to a hexadecimal string + * @return The string representation + */ + public static StringBuffer convertBytesToHexSB(byte[] bytes) { + StringBuffer sb = new StringBuffer(bytes.length * 2); + int byteLen = bytes.length; + for (int index = 0; index < byteLen; index++) { + char tempChar; + // Get the first 4 bits (high) Do bitwise logical AND to get rid of + // low nibble. Shift results to right by 4 and get char + // representation + tempChar = HEX_TABLE[((bytes[index] & 0xf0) >>> 4)]; + sb.append(tempChar); + + // Get the last 4 bits (low) Do bitwise logical AND to get rid of + // high nibble. Get char representation + tempChar = HEX_TABLE[(bytes[index] & 0x0f)]; + sb.append(tempChar); + } + return sb; + } + + /** + * Converts a hexadecimal string representation of a binary value to an array of bytes + * + * @param hexValue + * The hex representation string to be converted + * @return The array of bytes that contains the binary value + */ + @SuppressWarnings("nls") + public static byte[] convertHexToBytes(String hexValue) { + byte[] bytes = null; + byte high; + byte low; + char hexChar; + + StringBuffer buffer = new StringBuffer(hexValue.toUpperCase()); + if (buffer.length() % 2 != 0) { + LOG.warn("Invalid HEX value length. " + + "The length of the value has to be a multiple of 2. Prepending '0' value."); + buffer.insert(0, '0'); + } + int hexLength = buffer.length(); + int byteLength = hexLength / 2; + + bytes = new byte[byteLength]; + for (int index = 0; index < hexLength; index += 2) { + hexChar = buffer.charAt(index); + high = (TextToHex.get(Character.valueOf(hexChar))).byteValue(); + high = (byte) (high << 4); + hexChar = buffer.charAt(index + 1); + low = (TextToHex.get(Character.valueOf(hexChar))).byteValue(); + high = (byte) (high | low); + bytes[index / 2] = high; + } + return bytes; + } +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/exceptions/APPCException.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/exceptions/APPCException.java new file mode 100644 index 000000000..bf3115f38 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/exceptions/APPCException.java @@ -0,0 +1,105 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.exceptions; + +/** + * This is a base class for all APPC defined exceptions. + */ + +public class APPCException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Constructs a new exception with null as its detail message. The cause is not initialized, and may subsequently be + * initialized by a call to initCause. + */ + public APPCException() { + } + + /** + * Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently + * be initialized by a call to initCause. + * + * @param message + * the detail message. The detail message is saved for later retrieval by the getMessage() method. + */ + public APPCException(String message) { + super(message); + } + + /** + * Constructs a new exception with the specified cause and a detail message of (cause==null ? null : + * cause.toString()) (which typically contains the class and detail message of cause). This constructor is useful + * for exceptions that are little more than wrappers for other throwables (for example, + * java.security.PrivilegedActionException). + * + * @param cause + * the cause (which is saved for later retrieval by the getCause() method). (A null value is permitted, + * and indicates that the cause is nonexistent or unknown.) + */ + public APPCException(Throwable cause) { + super(cause); + } + + /** + * + Constructs a new exception with the specified detail message and cause. + * <p> + * Note that the detail message associated with cause is not automatically incorporated in this exception's detail + * message. + * </p> + * + * @param message + * the detail message (which is saved for later retrieval by the getMessage() method). + * @param cause + * the cause (which is saved for later retrieval by the getCause() method). (A null value is permitted, + * and indicates that the cause is nonexistent or unknown.) + */ + public APPCException(String message, Throwable cause) { + super(message, cause); + } + + /** + * + Constructs a new exception with the specified detail message, cause, suppression enabled or disabled, and + * writable stack trace enabled or disabled. + * + * @param message + * the detail message. + * @param cause + * the cause. (A null value is permitted, and indicates that the cause is nonexistent or unknown.) + * @param enableSuppression + * whether or not suppression is enabled or disabled + * @param writableStackTrace + * whether or not the stack trace should be writable + */ + public APPCException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/exceptions/UnknownProviderException.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/exceptions/UnknownProviderException.java new file mode 100644 index 000000000..e73f9e5f7 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/exceptions/UnknownProviderException.java @@ -0,0 +1,104 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.exceptions; + +/** + * This exception indicates that the named provider could not be found or was unidentifiable. + */ +public class UnknownProviderException extends APPCException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Constructs a new exception with null as its detail message. The cause is not initialized, and may subsequently be + * initialized by a call to initCause. + */ + public UnknownProviderException() { + } + + /** + * Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently + * be initialized by a call to initCause. + * + * @param message + * the detail message. The detail message is saved for later retrieval by the getMessage() method. + */ + public UnknownProviderException(String message) { + super(message); + } + + /** + * Constructs a new exception with the specified cause and a detail message of (cause==null ? null : + * cause.toString()) (which typically contains the class and detail message of cause). This constructor is useful + * for exceptions that are little more than wrappers for other throwables (for example, + * java.security.PrivilegedActionException). + * + * @param cause + * the cause (which is saved for later retrieval by the getCause() method). (A null value is permitted, + * and indicates that the cause is nonexistent or unknown.) + */ + public UnknownProviderException(Throwable cause) { + super(cause); + } + + /** + * + Constructs a new exception with the specified detail message and cause. + * <p> + * Note that the detail message associated with cause is not automatically incorporated in this exception's detail + * message. + * </p> + * + * @param message + * the detail message (which is saved for later retrieval by the getMessage() method). + * @param cause + * the cause (which is saved for later retrieval by the getCause() method). (A null value is permitted, + * and indicates that the cause is nonexistent or unknown.) + */ + public UnknownProviderException(String message, Throwable cause) { + super(message, cause); + } + + /** + * + Constructs a new exception with the specified detail message, cause, suppression enabled or disabled, and + * writable stack trace enabled or disabled. + * + * @param message + * the detail message. + * @param cause + * the cause. (A null value is permitted, and indicates that the cause is nonexistent or unknown.) + * @param enableSuppression + * whether or not suppression is enabled or disabled + * @param writableStackTrace + * whether or not the stack trace should be writable + */ + public UnknownProviderException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/i18n/Msg.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/i18n/Msg.java new file mode 100644 index 000000000..3e4237258 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/i18n/Msg.java @@ -0,0 +1,612 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.i18n; + +import com.att.eelf.i18n.EELFResolvableErrorEnum; +import com.att.eelf.i18n.EELFResourceManager; + +/** + * The messages issued by APPC components. + * <p> + * This message definition is shared by all APPC components. + * </p> + * + */ +@SuppressWarnings("nls") +public enum Msg implements EELFResolvableErrorEnum { + + /** + * ECOMP Application Controller (APP-C) initialization started at {0} + */ + CONFIGURATION_STARTED, + + /** + * Prior configuration has been cleared + */ + CONFIGURATION_CLEARED, + + /** + * Loading configuration properties from file "{0}" + */ + LOADING_CONFIGURATION_OVERRIDES, + + /** + * Configuration defaults loaded from resource file "{0}" + */ + LOADING_DEFAULTS, + + /** + * No default property resource "{0}" was found! + */ + NO_DEFAULTS_FOUND, + + /** + * Property "{0}" ="{1}" + */ + PROPERTY_VALUE, + + /** + * No configuration file named [{0}] was found on the configuration search path [{1}]. \ If a configuration file + * should have been loaded, check the file name and search path specified. CDP will proceed using the \ default + * values and command-line overrides (if any). + */ + NO_OVERRIDE_PROPERTY_FILE_LOADED, + + /** + * Searching path "{0}" for configuration settings "{1}" + */ + SEARCHING_CONFIGURATION_OVERRIDES, + + /** + * Loading application-specific override properties + */ + LOADING_APPLICATION_OVERRIDES, + + /** + * No application-specific override properties were provided! + */ + NO_APPLICATION_OVERRIDES, + + /** + * Merging system properties into configuration + */ + MERGING_SYSTEM_PROPERTIES, + + /** + * Setting property "{0}={1}" in system properties + */ + SETTING_SPECIAL_PROPERTY, + + /** + * Loading resource bundle "{0}" + */ + LOADING_RESOURCE_BUNDLE, + + /** + * Logging has already been initialized, check the container logging definitions to ensure they represent your + * desired logging configuration. + */ + LOGGING_ALREADY_INITIALIZED, + + /** + * Searching path "{0}" for log configuration file "{1}" + */ + SEARCHING_LOG_CONFIGURATION, + + /** + * Loading default logging configuration from system resource file "{0}" + */ + LOADING_DEFAULT_LOG_CONFIGURATION, + + /** + * No log configuration could be found or defaulted! + */ + NO_LOG_CONFIGURATION, + + /** + * An unsupported logging framework is bound to SLF4J. Only Logback or Log4J are supported. + */ + UNSUPPORTED_LOGGING_FRAMEWORK, + + /** + * Loading logging configuration from file "{0}" + */ + LOADING_LOG_CONFIGURATION, + + /** + * Provider {0} cannot be found or cannot be resolved to a valid provider. + */ + UNKNOWN_PROVIDER, + + /** + * Server name "{0}" with id "{1}" in tenant "{2}" and region "{3}" did not change state within the alloted time. + * Current state is "{4}" and the desired state(s) are "{5}" + */ + SERVER_STATE_CHANGE_TIMEOUT, + + /** + * Server name "{0}" with id "{1}" in tenant "{2}" has a state of deleted and cannot be {3}. + */ + SERVER_DELETED, + + /** + * Server name "{0}" with id "{1}" in tenant "{2}" has an unknown state of "{3}". + */ + UNKNOWN_SERVER_STATE, + + /** + * {0} component {1} is being initialized... + */ + COMPONENT_INITIALIZING, + + /** + * {0} component {1} has completed initialization + */ + COMPONENT_INITIALIZED, + + /** + * {0} component {1} is terminating... + */ + COMPONENT_TERMINATING, + + /** + * {0} component {1} has terminated + */ + COMPONENT_TERMINATED, + + /** + * Operation {0} is not supported or implemented at this time. + */ + IAAS_ADAPTER_UNSUPPORTED_OPERATION, + + /** + * Operation {0} called. Input document:\n{1} + */ + IAAS_ADAPTER_RPC_CALLED, + + /** + * Unable to locate the {0} service in the OSGi container + */ + NO_SERVICE_FOUND, + + /** + * Dump of context parameters for module {0}, RPC {1}, and version {2} + */ + CONTEXT_PARAMETERS_DISPLAY, + + /** + * Response properties from execution of module '{0}', RPC '{1}', and version '{2}' are: + */ + RESPONSE_PARAMETERS_DISPLAY, + + /** + * Service {0}:{1} was provided a null (empty) or invalid argument, '{2}' = '{3}' + */ + NULL_OR_INVALID_ARGUMENT, + + /** + * Service {0}:{1} is processing service '{2}' with request id '{3}' + */ + PROCESSING_REQUEST, + + /** + * Service {0}:{1} received request for service '{2}' but that service is invalid or unknown. + */ + INVALID_SERVICE_REQUEST, + + /** + * {0} registering service {1} using class {2} + */ + REGISTERING_SERVICE, + + /** + * {0} unregistering service {1} + */ + UNREGISTERING_SERVICE, + + /** + * {0} IAAS Adapter initializing provider {1} as {2} + */ + LOADING_PROVIDER_DEFINITIONS, + + /** + * {0} IAAS Adapter restart of server requested + */ + RESTARTING_SERVER, + + /** + * {0} IAAS Adapter rebuild of server requested + */ + REBUILDING_SERVER, + + /** + * {0} IAAS Adapter migrate of server requested + */ + MIGRATING_SERVER, + + /** + * {0} IAAS Adapter evacuate of server requested + */ + EVACUATING_SERVER, + + /** + * {0} IAAS Adapter create snapshot of server requested + */ + SNAPSHOTING_SERVER, + + /** + * {0} IAAS Adapter cannot perform requested service, VM url '{1}' is invalid + */ + INVALID_SELF_LINK_URL, + + /** + * Located server '{0}' on tenant '{1}' and in state '{2}' + */ + SERVER_FOUND, + + /** + * No server found in provider with self-link URL [{0}] + */ + SERVER_NOT_FOUND, + + /** + * Exception {0} was caught attempting {1} of server [{2}] on tenant [{3}] + */ + SERVER_OPERATION_EXCEPTION, + + /** + * One or more properties for [{0}] are missing, null, or empty. They are: + */ + MISSING_REQUIRED_PROPERTIES, + + /** + * The server [{0}] (id={1}) in tenant {2} is in error state, {3} is not allowed + */ + SERVER_ERROR_STATE, + + /** + * The image {0} could not be located for {1} + */ + IMAGE_NOT_FOUND, + + /** + * Time out waiting for {0} with name {1} (and id {2}) to reach one of {3} states, current state is {4} + */ + STATE_CHANGE_TIMEOUT, + + /** + * Exception {0} waiting for {1} with name {2} (and id {3}) to reach one of {4} states, current state is {5} + * cause={6} + */ + STATE_CHANGE_EXCEPTION, + + /** + * Server {0} is being stopped... + */ + STOP_SERVER, + + /** + * Server {0} is being started... + */ + START_SERVER, + + /** + * Server {0} is being resumed... + */ + RESUME_SERVER, + + /** + * Server {0} is being unpaused... + */ + UNPAUSE_SERVER, + + /** + * Connection to provider {0} at identity {1} using tenant name {2} (id {3}) failed, reason={4}, retrying in {5} + * seconds, attempt {6} of {7}. + */ + CONNECTION_FAILED_RETRY, + + /** + * Connection to provider {0} at service {1} failed after all retry attempts. + */ + CONNECTION_FAILED, + + /** + * {0} IAAS Adapter stop server requested + */ + STOPPING_SERVER, + + /** + * Server {0} (id {1}) failed to rebuild, reason {2} + */ + REBUILD_SERVER_FAILED, + + /** + * Application {0} graph {1} response did not set the {2} parameter. This parameter is required for synchronization + * with the controller. Absence of this parameter is assumed to be a failure. Please correct the DG. + */ + PARAMETER_IS_MISSING, + + /** + * Application {0} graph {1} did not set parameter {2} to a valid numeric value ({3}). Please correct the DG. + */ + PARAMETER_NOT_NUMERIC, + + /** + * Application {0} graph {1} completed with failure: error code = {2}, message = {3} + */ + DG_FAILED_RESPONSE, + + /** + * Application {0} received exception {1} attempting to call graph {2}, exception message = {3} + */ + EXCEPTION_CALLING_DG, + + /** + * Application {0} was unable to locate graph {1} + */ + GRAPH_NOT_FOUND, + + /** + * Application {0} graph {1} responded with {3} properties + */ + DEBUG_GRAPH_RESPONSE_HEADER, + + /** + * {0}:{1} - {2} = {3} + */ + DEBUG_GRAPH_RESPONSE_DETAIL, + + /** + * Application {0} request {1} was supplied a property '{2}' with the value '{3}' that does not meet the required + * form(s): + */ + INVALID_REQUIRED_PROPERTY, + + /** + * Server {0} (id {1}) failed to migrate during {2} phase, reason {3} + */ + MIGRATE_SERVER_FAILED, + + /** + * Server {0} (id {1}) failed to evacuate, reason {2} + */ + EVACUATE_SERVER_FAILED, + + /** + * APP-C instance is too busy + */ + APPC_TOO_BUSY, + + /** + * Concurrent access to server "{0}" + */ + VF_SERVER_BUSY, + + /** + * Server "{0}" does not support command "{1}" in the current state "{2}" + */ + VF_ILLEGAL_COMMAND, + + /** + * Server "{0}" cannot handle command "{1}" because of its doubtful state + */ + VF_UNDEFINED_STATE, + + /** + * No resource found with ID "{0}" in A&AI system + */ + APPC_NO_RESOURCE_FOUND, + + /** + * The request "{0}" for server "{1}" has exceeded its TTL limit of "{3}" seconds + */ + APPC_EXPIRED_REQUEST, + + /** + * Workflow for vnfType = "{0}" and command = "{1}" not found. + */ + APPC_WORKFLOW_NOT_FOUND, + + /** + * Null vnfId and command provided + */ + APPC_INVALID_INPUT, + + /** + * Operation '{0}' for VNF type '{1}' from Source '{2}' with RequestID '{3}' was started at '{4}' and ended at '{5}' + * with status code '{6}' + */ + APPC_AUDIT_MSG, + + /** + * APP-C is unable to communicate with A&AI + */ + AAI_CONNECTION_FAILED, + + /** + * APP-C is unable to update COMPONENT_ID {0} to {1} for reason {2} + */ + AAI_UPDATE_FAILED, + + /** + * APP-C is unable to retrieve VF/VFC {0} data for Transaction ID{1}as a result of A&AI communication failure or its + * internal error. + */ + AAI_GET_DATA_FAILED, + + /** + * A&AI at identity {0} using VNF_ID {1} failed, reason={2}, retrying in {3} seconds, attempt {4} of {5} + */ + AAI_CONNECTION_FAILED_RETRY, + + /** + * APP-C is unable to delete COMPONENT_ID {0} for reason {1} + */ + AAI_DELETE_FAILED, + + /** + * VNF {0} is configured + */ + VNF_CONFIGURED, + + /** + * VNF {0} is being configured + */ + VNF_CONFIGURATION_STARTED, + + /** + * VNF {0} configuration failed for reason {1} + */ + VNF_CONFIGURATION_FAILED, + + /** + * VNF {0} is being tested + */ + VNF_TEST_STARTED, + + /** + * VNF {0} was tested + */ + VNF_TESTED, + + /** + * VNF {0} test failed for reason {1} + */ + VNF_TEST_FAILED, + + /** + * Server {0} (id {1}) failed to stop during {2} phase, reason {3} + */ + STOP_SERVER_FAILED, + + /** + * Server {0} (id {1}) failed to terminate during {2} phase, reason {3} + */ + TERMINATE_SERVER_FAILED, + + /** + * {0} IAAS Adapter terminate server requested + */ + TERMINATING_SERVER, + + /** + * Server {0} is being terminated... + */ + TERMINATE_SERVER, + + /** + * Migrate {0} finished with status {1}. Start Time: {2}. End Time: {3}. Request ID: {4}. Reason:{5}... + */ + MIGRATE_COMPLETE, + + /** + * Restart {0} finished with status {1}. Start Time: {2}. End Time: {3}. Request ID: {4}. Reason:{5}... + */ + RESTART_COMPLETE, + + /** + * Rebuild {0} finished with status {1}. Start Time: {2}. End Time: {3}. Request ID: {4}. Reason:{5}... + */ + REBUILD_COMPLETE, + + /** + * Located stack '{0}' on tenant '{1}' and in state '{2}' + */ + STACK_FOUND, + + /** + * {0} IAAS Adapter terminate stack requested + */ + + TERMINATING_STACK, + + /** + * stack {0} is being terminated... + */ + TERMINATE_STACK, + /** + * No stack found in provider with self-link URL [{0}] + */ + + STACK_NOT_FOUND, + + /** + * Exception {0} was caught attempting {1} of stack [{2}] on tenant [{3}] + */ + STACK_OPERATION_EXCEPTION, + + /** + * Stack {0} (id {1}) failed to terminate during {2} phase, reason {3} + */ + + TERMINATE_STACK_FAILED, + + /** + * Exception {0} was caught attempting to close provider context for {1}. + */ + + CLOSE_CONTEXT_FAILED, + + /** + * Stack {0} is being snapshoted... + */ + SNAPSHOTING_STACK, + + /** + * Stack {0} snapshoted, snapshot ID = [{1}]. + */ + STACK_SNAPSHOTED, + + /** + * Stack {0} is being restored to snapshot {1}... + */ + RESTORING_STACK, + + /** + * Stack {0} is restored to snapshot {1}. + */ + STACK_RESTORED, + + /** + * Parameter {0} is missing in svc request of {1}. + */ + MISSING_PARAMETER_IN_REQUEST, + + /** + * Cannot establish connection to server {0} port {1} with user {2}. + */ + CANNOT_ESTABLISH_CONNECTION, + + /** + * Operation '{0}' for VNF type '{1}' from Source '{2}' with RequestID '{3}' on '{4}' with action '{5}' + * ended in {6}ms with result '{7}' + */ + APPC_METRIC_MSG; + + /** + * Static initializer to ensure the resource bundles for this class are loaded... + */ + static { + EELFResourceManager.loadMessageBundle("org/openecomp/appc/i18n/MessageResources"); + } +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/logging/LoggingConstants.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/logging/LoggingConstants.java new file mode 100644 index 000000000..dcc797138 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/logging/LoggingConstants.java @@ -0,0 +1,70 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.logging; + +public class LoggingConstants { + + public static class MDCKeys { + + public static final String ERROR_CODE = "ErrorCode"; + public static final String ERROR_DESCRIPTION = "ErrorDescription"; + public static final String STATUS_CODE = "StatusCode"; + public static final String RESPONSE_CODE = "ResponseCode"; + public static final String RESPONSE_DESCRIPTION = "ResponseDescription"; + public static final String TARGET_ENTITY = "TargetEntity"; + public static final String TARGET_SERVICE_NAME = "TargetServiceName"; + public static final String PARTNER_NAME = "PartnerName"; + public static final String SERVER_NAME = "ServerName"; + public static final String BEGIN_TIMESTAMP = "BeginTimestamp"; + public static final String END_TIMESTAMP = "EndTimestamp"; + public static final String ELAPSED_TIME = "ElapsedTime"; + public static final String CLASS_NAME = "ClassName"; + public static final String TARGET_VIRTUAL_ENTITY = "TargetVirtualEntity"; + } + + public static class StatusCodes { + public static final String COMPLETE = "COMPLETE"; + public static final String ERROR = "ERROR"; + } + + public static class TargetNames { + public static final String APPC = "APPC"; + public static final String AAI = "A&AI"; + public static final String DB = "DataBase"; + public static final String APPC_PROVIDER = "APPC Provider"; + public static final String STATE_MACHINE = "StateMachine"; + public static final String WORKFLOW_MANAGER = "WorkflowManager"; + public static final String REQUEST_VALIDATOR = "RequestValidator"; + public static final String LOCK_MANAGER = "LockManager"; + public static final String REQUEST_HANDLER = "RequestHandler"; + } + + public static class TargetServiceNames{ + + public static class AAIServiceNames{ + public static final String QUERY = "query"; + public static final String GET_VNF_DATA = "getVnfData"; + } + + } + +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/logging/LoggingUtils.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/logging/LoggingUtils.java new file mode 100644 index 000000000..901ff3272 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/logging/LoggingUtils.java @@ -0,0 +1,196 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.logging; + +import org.openecomp.appc.i18n.Msg; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; +import org.slf4j.MDC; + +import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID; +import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + + + +public class LoggingUtils { + + private final static EELFLogger errorLogger = EELFManager.getInstance().getErrorLogger(); + private final static EELFLogger auditLogger = EELFManager.getInstance().getAuditLogger(); + private final static EELFLogger metricLogger = EELFManager.getInstance().getMetricsLogger(); + + public static void logErrorMessage(String errorCode, String errorDescription, String targetEntity, String targetServiceName, String additionalMessage, String className) { + logError(errorCode, errorDescription, targetEntity, targetServiceName, additionalMessage, className); + } + + public static void logErrorMessage(String targetEntity, String targetServiceName, String additionalMessage, String className) { + logError("", "", targetEntity, targetServiceName, additionalMessage, className); + } + + public static void logErrorMessage(String targetServiceName, String additionalMessage, String className) { + logError("", "", LoggingConstants.TargetNames.APPC, targetServiceName, additionalMessage, className); + } + + private static void logError(String errorCode, String errorDescription, String targetEntity, String targetServiceName, String additionalMessage, String className) { + populateErrorLogContext(errorCode, errorDescription, targetEntity, targetServiceName, className); + errorLogger.error(additionalMessage == null ? "" : additionalMessage); + cleanErrorLogContext(); + } + + public static void logAuditMessage(Date beginTimeStamp, Date endTimeStamp, String code, String responseDescription, String className) { + populateAuditLogContext(beginTimeStamp, endTimeStamp, code, responseDescription, className); + auditLogger.info(EELFResourceManager.format(Msg.APPC_AUDIT_MSG, + MDC.get(MDC_SERVICE_NAME), + MDC.get(LoggingConstants.MDCKeys.TARGET_VIRTUAL_ENTITY), + MDC.get(LoggingConstants.MDCKeys.PARTNER_NAME), + MDC.get(MDC_KEY_REQUEST_ID), + MDC.get(LoggingConstants.MDCKeys.BEGIN_TIMESTAMP), + MDC.get(LoggingConstants.MDCKeys.END_TIMESTAMP), + MDC.get(LoggingConstants.MDCKeys.RESPONSE_CODE))); + cleanAuditErrorContext(); + } + + public static void logMetricsMessage(Date beginTimeStamp, Date endTimeStamp, String targetEntity, String targetServiceName, String statusCode, String responseCode, String responseDescription, String className) { + populateMetricLogContext(beginTimeStamp, endTimeStamp, targetEntity, targetServiceName, statusCode, responseCode, responseDescription, className); + metricLogger.info(EELFResourceManager.format(Msg.APPC_METRIC_MSG, + MDC.get(MDC_SERVICE_NAME), + MDC.get(LoggingConstants.MDCKeys.TARGET_VIRTUAL_ENTITY), + MDC.get(LoggingConstants.MDCKeys.PARTNER_NAME), + MDC.get(MDC_KEY_REQUEST_ID), + MDC.get(LoggingConstants.MDCKeys.TARGET_ENTITY), + MDC.get(LoggingConstants.MDCKeys.TARGET_SERVICE_NAME), + MDC.get(LoggingConstants.MDCKeys.ELAPSED_TIME), + MDC.get(LoggingConstants.MDCKeys.STATUS_CODE))); + cleanMetricContext(); + } + + private static void populateAuditLogContext(Date beginTimeStamp, Date endTimeStamp, String code, String responseDescription, String className) { + populateTimeContext(beginTimeStamp, endTimeStamp); + MDC.put(LoggingConstants.MDCKeys.RESPONSE_CODE, code); + MDC.put(LoggingConstants.MDCKeys.STATUS_CODE, code.equals("100") || code.equals("400") ? + LoggingConstants.StatusCodes.COMPLETE : + LoggingConstants.StatusCodes.ERROR); + MDC.put(LoggingConstants.MDCKeys.RESPONSE_DESCRIPTION, responseDescription!=null?responseDescription:""); + MDC.put(LoggingConstants.MDCKeys.CLASS_NAME, className!=null?className:""); + } + + private static void cleanAuditErrorContext() { + cleanTimeContext(); + MDC.remove(LoggingConstants.MDCKeys.STATUS_CODE); + MDC.remove(LoggingConstants.MDCKeys.RESPONSE_CODE); + MDC.remove(LoggingConstants.MDCKeys.RESPONSE_DESCRIPTION); + MDC.remove(LoggingConstants.MDCKeys.CLASS_NAME); + } + + private static void populateErrorLogContext(String errorCode, String errorDescription, String targetEntity, String targetServiceName, String className) { + populateErrorContext(errorCode, errorDescription); + populateTargetContext(targetEntity, targetServiceName!=null?targetServiceName:""); + MDC.put(LoggingConstants.MDCKeys.CLASS_NAME, className!=null?className:""); + } + + private static void cleanErrorLogContext() { + cleanErrorContext(); + cleanTargetContext(); + MDC.remove(LoggingConstants.MDCKeys.CLASS_NAME); + } + + private static void populateMetricLogContext(Date beginTimeStamp, Date endTimeStamp, String targetEntity, String targetServiceName, String statusCode, String responseCode, String responseDescription, String className) { + populateTimeContext(beginTimeStamp, endTimeStamp); + populateTargetContext(targetEntity, targetServiceName); + populateResponseContext(statusCode, responseCode, responseDescription); + MDC.put(LoggingConstants.MDCKeys.CLASS_NAME, className!=null?className:""); + } + + private static void cleanMetricContext() { + cleanTimeContext(); + cleanTargetContext(); + cleanResponseContext(); + MDC.remove(LoggingConstants.MDCKeys.CLASS_NAME); + } + + private static void populateTargetContext(String targetEntity, String targetServiceName) { + MDC.put(LoggingConstants.MDCKeys.TARGET_ENTITY, targetEntity!=null?targetEntity:""); + MDC.put(LoggingConstants.MDCKeys.TARGET_SERVICE_NAME, targetServiceName!=null?targetServiceName:""); + } + + private static void cleanTargetContext() { + MDC.remove(LoggingConstants.MDCKeys.TARGET_ENTITY); + MDC.remove(LoggingConstants.MDCKeys.TARGET_SERVICE_NAME); + } + + private static void populateTimeContext(Date beginTimeStamp, Date endTimeStamp) { + String beginTime = ""; + String endTime = ""; + String elapsedTime = ""; + + if (beginTimeStamp != null && endTimeStamp != null) { + elapsedTime = String.valueOf(endTimeStamp.getTime() - beginTimeStamp.getTime()); + beginTime = generateTimestampStr(beginTimeStamp); + endTime = generateTimestampStr(endTimeStamp); + } + + MDC.put(LoggingConstants.MDCKeys.BEGIN_TIMESTAMP, beginTime); + MDC.put(LoggingConstants.MDCKeys.END_TIMESTAMP, endTime); + MDC.put(LoggingConstants.MDCKeys.ELAPSED_TIME, elapsedTime); + } + + private static String generateTimestampStr(Date timeStamp) { + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX"); + TimeZone tz = TimeZone.getTimeZone("UTC"); + df.setTimeZone(tz); + return df.format(timeStamp); + } + + private static void cleanTimeContext() { + MDC.remove(LoggingConstants.MDCKeys.BEGIN_TIMESTAMP); + MDC.remove(LoggingConstants.MDCKeys.END_TIMESTAMP); + MDC.remove(LoggingConstants.MDCKeys.ELAPSED_TIME); + } + + private static void populateResponseContext(String statusCode, String responseCode, String responseDescription) { + MDC.put(LoggingConstants.MDCKeys.STATUS_CODE, statusCode!=null?statusCode:""); + MDC.put(LoggingConstants.MDCKeys.RESPONSE_CODE, responseCode); + MDC.put(LoggingConstants.MDCKeys.RESPONSE_DESCRIPTION, responseDescription!=null?responseDescription:""); + } + + private static void cleanResponseContext() { + MDC.remove(LoggingConstants.MDCKeys.STATUS_CODE); + MDC.remove(LoggingConstants.MDCKeys.RESPONSE_CODE); + MDC.remove(LoggingConstants.MDCKeys.RESPONSE_DESCRIPTION); + } + + private static void populateErrorContext(String errorCode, String errorDescription) { + MDC.put(LoggingConstants.MDCKeys.ERROR_CODE, errorCode); + MDC.put(LoggingConstants.MDCKeys.ERROR_DESCRIPTION, errorDescription); + } + + private static void cleanErrorContext() { + MDC.remove(LoggingConstants.MDCKeys.ERROR_CODE); + MDC.remove(LoggingConstants.MDCKeys.ERROR_DESCRIPTION); + } + +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/Allocator.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/Allocator.java new file mode 100644 index 000000000..8301cb7a5 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/Allocator.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.pool; + +import java.io.Closeable; + +/** + * This interface is used to supply an object that will be called by the pool manager whenever a new widget must be + * allocated. + * @param <T> + * The generic type that we are caching. + */ + +public interface Allocator<T extends Closeable> { + + /** + * Allocate an object of type <T> and return it to the pool + * + * @param pool + * The pool that the object is to be allocated to + * @return An object of type T + */ + T allocate(Pool<T> pool); +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/CacheManagement.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/CacheManagement.java new file mode 100644 index 000000000..10c007548 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/CacheManagement.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + +package org.openecomp.appc.pool; + +public interface CacheManagement { + + /** + * @return The object that is actually being wrapped and cached + */ + Object getWrappedObject(); + +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/CachedElement.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/CachedElement.java new file mode 100644 index 000000000..558b2a33a --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/CachedElement.java @@ -0,0 +1,208 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.pool; + +import java.io.Closeable; +import java.io.IOException; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * This class is used as a "wrapper" for any closeable elements that are cached in a pool. It is implemented as a + * dynamic proxy, so that it appears to be the same class of object to the client as the interface being cached. The + * generic type being cached MUST be an interface. + * @param <T> + * The generic type that we create a cached element for. This type is used to wrap instances of this type and + * expose access to the {@link java.io.Closeable} interface by using a dynamic proxy. + */ + +public class CachedElement<T extends Closeable> implements Closeable, InvocationHandler, CacheManagement { + + /** + * The pool that is managing this cached element + */ + private Pool<T> pool; + + /** + * The element that we are caching in the pool + */ + private T element; + + /** + * A thread-safe atomic indicator that tells us that the wrapped element has been released to the pool already, and + * not to do it again. + */ + private AtomicBoolean released = new AtomicBoolean(false); + + /** + * Create a new instance of a cached element dynamic proxy for use in the pool. + * <p> + * This returns an instance of the proxy to the caller that appears to be the same interface(s) as the object being + * cached. The dynamic proxy then intercepts all open and close semantics and directs that element to the pool. + * </p> + * <p> + * If the object being proxied does not implement the {@link CacheManagement} interface, then that interface is + * added to the dynamic proxy being created. This interface is actually implemented by the invocation handler (this + * object) for the proxy and allows direct access to the wrapped object inside the proxy. + * </p> + * + * @param pool + * The pool that we are caching these elements within + * @param element + * The element actually being cached + * @param interfaces + * The interface list of interfaces the element must implement (usually one) + * @return The dynamic proxy + */ + @SuppressWarnings("unchecked") + public static <T extends Closeable> T newInstance(Pool<T> pool, T element, Class<?>[] interfaces) { + ClassLoader cl = element.getClass().getClassLoader(); + CachedElement<T> ce = new CachedElement<>(pool, element); + boolean found = false; + for (Class<?> intf : interfaces) { + if (intf.getName().equals(CacheManagement.class.getName())) { + found = true; + break; + } + } + + int length = found ? interfaces.length : interfaces.length + 1; + Class<?>[] proxyInterfaces = new Class[length]; + System.arraycopy(interfaces, 0, proxyInterfaces, 0, interfaces.length); + + if (!found) { + proxyInterfaces[interfaces.length] = CacheManagement.class; + } + + return (T) Proxy.newProxyInstance(cl, proxyInterfaces, ce); + } + + /** + * Construct a cached element and assign it to the pool as a free element + * + * @param pool + * The pool that the element will be managed within + * @param element + * The element we are caching + */ + @SuppressWarnings("unchecked") + public CachedElement(Pool<T> pool, T element) { + this.pool = pool; + this.element = element; + + try { + pool.release((T) this); + } catch (PoolDrainedException e) { + e.printStackTrace(); + } + } + + /** + * This method delegates the close call to the actual wrapped element. + * <p> + * NOTE: This is not the same method that is called by the dynamic proxy. This method is in place to satisfy the + * signature of the {@link java.io.Closeable} interface. If it were to be called directly, then we will delegate the + * close to the underlying context. However, when the cached element is called as a synamic proxy, entry is in the + * {@link #invoke(Object, Method, Object[])} method. + * </p> + * + * @see java.io.Closeable#close() + */ + @Override + public void close() throws IOException { + element.close(); + } + + /** + * This method is the magic part of dynamic proxies. When the caller makes a method call based on the interface + * being proxied, this method is given control. This informs us of the method and arguments of the call. The object + * reference is that of the dynamic proxy itself, which is us. + * <p> + * Here we will check to see if the user is trying to close the "element" (the dynamic proxy acts like the wrapped + * element). If he is, then we don't really close it, but instead release the element that we are wrapping back to + * the free pool. Once this has happened, we mark the element as "closed" (from the perspective of this dynamic + * proxy) so that we wont try to release it again. + * </p> + * <p> + * If the method is the <code>equals</code> method then we assume that we are comparing the cached element in one + * dynamic proxy to the cached element in another. We execute the comparison between the cached elements, and not + * the dynamic proxies themselves. This preserves the allusion to the caller that the dynamic proxy is the object + * being wrapped. + * </p> + * <p> + * For convenience, we also implement the <code>getWrappedObject</code> method so that the dynamic proxy can be + * called to obtain the actual wrapped object if desired. Note, to use this method, the caller would have to invoke + * it through reflection. + * </p> + * <p> + * If the method being invoked is not one that we intercept, then we simply delegate that method onto the wrapped + * object. + * </p> + * + * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) + */ + @SuppressWarnings({ + "unchecked", "nls" + }) + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + Object result = null; + + if (method.getName().equals("close")) { + if (released.compareAndSet(false, true)) { + if (!pool.isDrained()) { + pool.release((T) proxy); + } + } + } else if (method.getName().equals("equals")) { + CacheManagement cm = (CacheManagement) proxy; + T other = (T) cm.getWrappedObject(); + result = element.equals(other); + } else if (method.getName().equals("getWrappedObject")) { + return element; + } else { + result = method.invoke(element, args); + } + + return result; + } + + /** + * This method is used to be able to access the wrapped object underneath the dynamic proxy + * + * @see org.openecomp.appc.pool.CacheManagement#getWrappedObject() + */ + @Override + public T getWrappedObject() { + return element; + } + + @SuppressWarnings("nls") + @Override + public String toString() { + return element == null ? "null" : element.toString(); + } +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/Destructor.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/Destructor.java new file mode 100644 index 000000000..40d2f1170 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/Destructor.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.pool; + +import java.io.Closeable; + +/** + * @param <T> + * The generic type we are caching + */ + +public interface Destructor<T extends Closeable> { + + /** + * Called to destroy the object when it is no longer being used by the pool + * + * @param obj + * The object to be destroyed + * @param pool + * The pool that the object is being removed from + */ + void destroy(T obj, Pool<T> pool); +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/Pool.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/Pool.java new file mode 100644 index 000000000..4c5b92474 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/Pool.java @@ -0,0 +1,371 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.pool; + +import java.io.Closeable; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Deque; +import java.util.List; +import java.util.ListIterator; +import java.util.Properties; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * This class is used to manage a pool of things. + * <p> + * The class is parameterized so that the type of objects maintained in the pool is definable by some provided type. + * This type must implement the <code>Comparable</code> interface so that it can be managed in the pool. + * </p> + * + * @param <T> + * The type of element being pooled + */ + +public class Pool<T extends Closeable> { + private Deque<T> free; + private List<T> allocated; + private int minPool; + private int maxPool; + private Allocator<T> allocator; + private Destructor<T> destructor; + private ReadWriteLock lock; + private AtomicBoolean drained; + private Properties properties; + + /** + * Create the pool + * + * @param minPool + * The minimum size of the pool + * @param maxPool + * The maximum size of the pool, set to zero (0) for unbounded + * @throws PoolSpecificationException + * If the minimum size is less than 0, or if the max size is non-zero and less than the min size. + */ + public Pool(int minPool, int maxPool) throws PoolSpecificationException { + + if (minPool < 0) { + throw new PoolSpecificationException(String.format("The minimum pool size must be a " + + "positive value or zero, %d is not valid.", minPool)); + } + if (maxPool != 0 && maxPool < minPool) { + throw new PoolSpecificationException(String.format("The maximum pool size must be a " + + "positive value greater than the minimum size, or zero. %d is not valid.", maxPool)); + } + + this.minPool = minPool; + this.maxPool = maxPool; + + properties = new Properties(); + free = new ArrayDeque<T>(); + allocated = new ArrayList<T>(); + lock = new ReentrantReadWriteLock(); + drained = new AtomicBoolean(false); + } + + /** + * Returns the amount of objects on the free collection + * + * @return The number of objects on the free collection + */ + public int getFreeSize() { + Lock readLock = lock.readLock(); + readLock.lock(); + try { + return free.size(); + } finally { + readLock.unlock(); + } + } + + /** + * Returns the value for a specified property of this pool, if defined. + * + * @param key + * The key of the desired property + * @return The value of the property, or null if not defined + */ + public String getProperty(String key) { + return properties.getProperty(key); + } + + /** + * Sets the value of the specified property or replaces it if it already exists + * + * @param key + * The key of the property to be set + * @param value + * The value to set the property to + */ + public void setProperty(String key, String value) { + properties.setProperty(key, value); + } + + /** + * @return The properties object for the pool + */ + public Properties getProperties() { + return properties; + } + + /** + * Returns the number of objects that are currently allocated + * + * @return The allocate collection size + */ + public int getAllocatedSize() { + Lock readLock = lock.readLock(); + readLock.lock(); + try { + return allocated.size(); + } finally { + readLock.unlock(); + } + } + + /** + * @return the value of allocator + */ + public Allocator<T> getAllocator() { + return allocator; + } + + /** + * @param allocator + * the value for allocator + */ + public void setAllocator(Allocator<T> allocator) { + this.allocator = allocator; + } + + /** + * @return the value of destructor + */ + public Destructor<T> getDestructor() { + return destructor; + } + + /** + * @return the value of minPool + */ + public int getMinPool() { + return minPool; + } + + /** + * @return the value of maxPool + */ + public int getMaxPool() { + return maxPool; + } + + /** + * @param destructor + * the value for destructor + */ + public void setDestructor(Destructor<T> destructor) { + this.destructor = destructor; + } + + /** + * Drains the pool, releasing and destroying all pooled objects, even if they are currently allocated. + */ + public void drain() { + if (drained.compareAndSet(false, true)) { + Lock writeLock = lock.writeLock(); + writeLock.lock(); + try { + int size = getAllocatedSize(); + /* + * We can't use the "release" method call here because we are modifying the list we are iterating + */ + ListIterator<T> it = allocated.listIterator(); + while (it.hasNext()) { + T obj = it.next(); + it.remove(); + free.addFirst(obj); + } + size = getFreeSize(); + trim(size); + } finally { + writeLock.unlock(); + } + } + } + + /** + * Returns an indication if the pool has been drained + * + * @return True indicates that the pool has been drained. Once a pool has been drained, it can no longer be used. + */ + public boolean isDrained() { + return drained.get(); + } + + /** + * Reserves an object of type T from the pool for the caller and returns it + * + * @return The object of type T to be used by the caller + * @throws PoolExtensionException + * If the pool cannot be extended + * @throws PoolDrainedException + * If the caller is trying to reserve an element from a drained pool + */ + @SuppressWarnings("unchecked") + public T reserve() throws PoolExtensionException, PoolDrainedException { + if (isDrained()) { + throw new PoolDrainedException("The pool has been drained and cannot be used."); + } + + T obj = null; + Lock writeLock = lock.writeLock(); + writeLock.lock(); + try { + int freeSize = getFreeSize(); + int allocatedSize = getAllocatedSize(); + + if (freeSize == 0) { + if (allocatedSize == 0) { + extend(minPool == 0 ? 1 : minPool); + } else if (allocatedSize >= maxPool && maxPool > 0) { + throw new PoolExtensionException(String.format("Unable to add " + + "more elements, pool is at maximum size of %d", maxPool)); + } else { + extend(1); + } + } + + obj = free.removeFirst(); + allocated.add(obj); + } finally { + writeLock.unlock(); + } + + // return obj; + + /* + * Now that we have the real object, lets wrap it in a dynamic proxy so that we can intercept the close call and + * just return the context to the free pool. obj.getClass().getInterfaces(). We need to find ALL interfaces that + * the object (and all superclasses) implement and have the proxy implement them too + */ + Class<?> cls = obj.getClass(); + Class<?>[] array; + List<Class<?>> interfaces = new ArrayList<Class<?>>(); + while (!cls.equals(Object.class)) { + array = cls.getInterfaces(); + for (Class<?> item : array) { + if (!interfaces.contains(item)) { + interfaces.add(item); + } + } + cls = cls.getSuperclass(); + } + array = new Class<?>[interfaces.size()]; + array = interfaces.toArray(array); + return CachedElement.newInstance(this, obj, array); + } + + /** + * releases the allocated object back to the free pool to be used by another request. + * + * @param obj + * The object to be returned to the pool + * @throws PoolDrainedException + * If the caller is trying to release an element to a drained pool + */ + public void release(T obj) throws PoolDrainedException { + if (isDrained()) { + throw new PoolDrainedException("The pool has been drained and cannot be used."); + } + Lock writeLock = lock.writeLock(); + writeLock.lock(); + try { + if (allocated.remove(obj)) { + free.addFirst(obj); + } + } finally { + writeLock.unlock(); + } + } + + /** + * Extend the free pool by some number of elements + * + * @param count + * The number of elements to add to the pool + * @throws PoolExtensionException + * if the pool cannot be extended because no allocator has been specified. + */ + private void extend(int count) throws PoolExtensionException { + if (allocator == null) { + throw new PoolExtensionException(String.format("Unable to extend pool " + + "because no allocator has been specified")); + } + Lock writeLock = lock.writeLock(); + writeLock.lock(); + try { + for (int index = 0; index < count; index++) { + T obj = allocator.allocate(this); + if (obj == null) { + throw new PoolExtensionException( + "The allocator failed to allocate a new context to extend the pool."); + } + free.push(obj); + } + } finally { + writeLock.unlock(); + } + } + + /** + * Used to trim the free collection by some specified number of elements, or the free element count, whichever is + * less. The elements are removed from the end of the free element deque, thus trimming the oldest elements first. + * + * @param count + * The number of elements to trim + */ + private void trim(int count) { + Lock writeLock = lock.writeLock(); + writeLock.lock(); + try { + int trimCount = count; + if (getFreeSize() < count) { + trimCount = getFreeSize(); + } + for (int i = 0; i < trimCount; i++) { + T obj = free.removeLast(); + if (destructor != null) { + destructor.destroy(obj, this); + } + } + } finally { + writeLock.unlock(); + } + } +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/PoolDrainedException.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/PoolDrainedException.java new file mode 100644 index 000000000..71edb493c --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/PoolDrainedException.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.pool; + +/** + * This exception is thrown whenever an attempt is made to access a pool of resources where the pool has been drained. + * Once drained, the pool is no longer usable. + * + */ +public class PoolDrainedException extends PoolException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * PoolDrainedException constructor + * + * @param msg + * The error message + */ + public PoolDrainedException(String msg) { + super(msg); + } + +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/PoolException.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/PoolException.java new file mode 100644 index 000000000..0ba88b68e --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/PoolException.java @@ -0,0 +1,89 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.pool; + +/** + * A pool exception is a specialization of checked exceptions that define various pool abnormal states or requests. + * + */ +public class PoolException extends Exception { + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * PoolException constructor + */ + public PoolException() { + } + + /** + * PoolException constructor + * + * @param message + * The error message + */ + public PoolException(String message) { + super(message); + } + + /** + * PoolException constructor + * + * @param cause + * The cause of the exception + */ + public PoolException(Throwable cause) { + super(cause); + } + + /** + * PoolException constructor + * + * @param message + * The error message + * @param cause + * The cause of the exception + */ + public PoolException(String message, Throwable cause) { + super(message, cause); + } + + /** + * PoolException constructor + * + * @param message + * The error message + * @param cause + * The cause of the exception + * @param enableSuppression + * whether or not suppression is enabled or disabled + * @param writableStackTrace + * whether or not the stack trace should be writable + */ + public PoolException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/PoolExtensionException.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/PoolExtensionException.java new file mode 100644 index 000000000..64f338105 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/PoolExtensionException.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.pool; + +/** + * An error occurred trying to extend the pool + * + */ +public class PoolExtensionException extends PoolException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * PoolExtensionException constructor + * + * @param msg + * The error message + */ + public PoolExtensionException(String msg) { + super(msg); + } +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/PoolSpecificationException.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/PoolSpecificationException.java new file mode 100644 index 000000000..f46ca374a --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/pool/PoolSpecificationException.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.pool; + +/** + * This exception is thrown whenever the pool is not specified correctly + * + */ +public class PoolSpecificationException extends PoolException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * PoolSpecificationException constructor + * + * @param msg + * The error message + */ + public PoolSpecificationException(String msg) { + super(msg); + } + +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/JsonUtil.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/JsonUtil.java new file mode 100644 index 000000000..6c5623da1 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/JsonUtil.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.util; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.util.Map; + + +public class JsonUtil { + /** + * @param valueAsString a valid json Map represented as String + * @return a flat map that each entry key derived from hierarchy path in the json object and flatted to a dotted separated string. + * e.g. "{\"A\":\"A-value\",\"B\":{\"C\":\"B.C-value\",\"D\":\"B.D-value\"}}"; will be represented as {A=A-value, B.C=B.C-value, B.D=B.D-value} + * when it required that the input will not be flatted the json string should be formatted as below example: + * e.g. "{\"A\":\"A-value\",\"B\":\"{\\\"C\\\":\\\"C-value\\\",\\\"D\\\":\\\"D-value\\\"}\"}" will be represented as {A=A-value, B={"C":"C-value","D":"D-value"}} + * @throws IOException when the object is not valid json Map + */ + public static Map<String, String> convertJsonStringToFlatMap(String valueAsString) throws IOException { + ObjectMapper objectMapper = new ObjectMapper(); + Map readValueMap = objectMapper.readValue(valueAsString,Map.class); + return org.openecomp.appc.util.ObjectMapper.map(readValueMap); + } +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/MessageFormatter.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/MessageFormatter.java new file mode 100644 index 000000000..39c9a67e3 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/MessageFormatter.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class MessageFormatter { + private final static String paramNameRegexGroupName = "paramName"; + private final static String paramRegex = "\\$\\{(?<paramName>[^}$]+)\\}"; //start with ${ and after there is one or more characters that are not $ and not } and ended with } + + + public static String format(String messageTemplate, Map<String,Object> params) { + if (StringUtils.isEmpty(messageTemplate)) + return ""; + if (params == null || params.isEmpty()) + return messageTemplate; + + String formattedMessage = messageTemplate; + if (formattedMessage.contains("$")) { + for (Map.Entry<String, Object> entry : params.entrySet()) { + formattedMessage = formattedMessage.replaceAll("\\$\\{" + entry.getKey() + "\\}", String.valueOf(entry.getValue())); + } +/* } else { + StringBuilder builder = new StringBuilder(formattedMessage); + builder.append("; output params: ["); + for (Map.Entry<String, Object> entry : params.entrySet()) { + builder.append(entry.getKey()).append(":").append(String.valueOf(entry.getValue())).append("; "); + } + builder.append("]"); + formattedMessage = builder.toString();*/ + } + + return formattedMessage; + } + + public static List<String> getParamsNamesList(String messageTemplate) { + List<String> paramsNames = null; + if(!StringUtils.isEmpty(messageTemplate)){ + paramsNames = new ArrayList<String>(); + Matcher m = Pattern.compile(paramRegex).matcher(messageTemplate); + while (m.find()) { + String paramName = m.group(paramNameRegexGroupName); + paramsNames.add(paramName); + } + } + return paramsNames; + } + public static Set<String> getParamsNamesSet(String messageTemplate) { + List<String> paramsNamesList = getParamsNamesList(messageTemplate); + Set<String> paramsNamesSet = null; + if(paramsNamesList != null && !paramsNamesList.isEmpty()){ + paramsNamesSet = new HashSet<String>(); + for(String paramName : paramsNamesList){ + paramsNamesSet.add(paramName); + } + } + return paramsNamesSet; + } +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/ObjectMapper.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/ObjectMapper.java new file mode 100644 index 000000000..4d55d4e11 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/ObjectMapper.java @@ -0,0 +1,98 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.util; + +import java.lang.reflect.Array; +import java.util.Map; + +public class ObjectMapper { + + private ObjectMapper() { + } + + private static void dispatch(PathContext context, Object obj) { + + if (obj == null) { + return; + } + + final Class<?> cls = obj.getClass(); + + if (cls.isPrimitive() + || String.class.isAssignableFrom(cls) + || Number.class.isAssignableFrom(cls) + || Boolean.class.isAssignableFrom(cls)) { + handlePrimitive(context, obj); + } else if (cls.isArray()) { + handleArray(context, obj); + } else if (Map.class.isAssignableFrom(cls)) { + handleMap(context, (Map<?, ?>) obj); + } else if (Iterable.class.isAssignableFrom(cls)) { + handleCollection(context, Iterable.class.cast(obj)); + } else { + throw new IllegalArgumentException(obj.getClass().getName()); + } + } + + public static Map<String, String> map(Object obj) { + PathContext context = new PathContext(); + dispatch(context, obj); + return context.entries(); + } + + private static void handleMap(PathContext context, Map<?, ?> val) { + for (Map.Entry<?, ?> entry : val.entrySet()) { + context.pushToken(entry.getKey().toString()); + dispatch(context, entry.getValue()); + context.popToken(); + } + } + + private static void handleCollection(PathContext context, Iterable<?> val) { + int index = 0; + for (Object elem : val) { + handleElement(context, index++, elem); + } + } + + private static void handleArray(PathContext context, Object val) { + for (int i = 0, n = Array.getLength(val); i < n; i++) { + handleElement(context, i, Array.get(val, i)); + } + } + + private static void handleElement(PathContext context, int index, Object val) { + if (val == null) { + return; + } + + String modifier = new StringBuilder().append('[').append(Integer.valueOf(index)).append(']').toString(); + + context.pushModifier(modifier); + dispatch(context, val); + context.popModifier(); + } + + private static void handlePrimitive(PathContext context, Object val) { + context.entry(context.getPath(), val.toString()); + } +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/PathContext.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/PathContext.java new file mode 100644 index 000000000..5565afd2f --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/PathContext.java @@ -0,0 +1,100 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.util; + + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.Map; + +class PathContext { + + private StringBuilder path = new StringBuilder(128); + + private LinkedList<Integer> indexes = new LinkedList<>(); + private Map<String, String> entries = new LinkedHashMap<>(); + private int offset = 0; + + private final String delimiter; + + PathContext() { + this("."); + } + + PathContext(String delimiter) { + this.delimiter = delimiter; + } + + private void push(String elem, boolean delimit) { + if (elem == null) { + throw new IllegalArgumentException(); + } + + int length = elem.length(); + + if (delimit && !indexes.isEmpty()) { + path.append(delimiter); + length += delimiter.length(); + } + + path.append(elem); + offset += length; + indexes.addLast(Integer.valueOf(length)); + } + + private void pop() { + if (indexes.isEmpty()) { + throw new IllegalStateException(); + } + offset -= indexes.removeLast(); + path.setLength(offset); + } + + void pushToken(String token) { + push(token, true); + } + + void popToken() { + pop(); + } + + void pushModifier(String modifier) { + push(modifier, false); + } + + void popModifier() { + pop(); + } + + String getPath() { + return path.substring(0, offset); + } + + void entry(String name, String value) { + entries.put(name, value); + } + + Map<String, String> entries() { + return Collections.unmodifiableMap(entries); + } +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/StreamHelper.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/StreamHelper.java new file mode 100644 index 000000000..8f80b8117 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/StreamHelper.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + +package org.openecomp.appc.util; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; + +public class StreamHelper { + + /** + * private default constructor prevents instantiation + */ + private StreamHelper() { + } + + /** + * @param inputStream + * @return Input stream converted to string + */ + public static String getStringFromInputStream(InputStream inputStream) { + StringBuffer buffer = new StringBuffer(); + byte[] array = new byte[4096]; + + if (inputStream != null) { + try { + int len = inputStream.read(array); + while (len != -1) { + buffer.append(new String(array, 0, len, Charset.forName("UTF-8"))); + len = inputStream.read(array); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + return buffer.toString(); + } + +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/StringHelper.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/StringHelper.java new file mode 100644 index 000000000..0f9188694 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/StringHelper.java @@ -0,0 +1,592 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.util; + +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * This class contains several static helper methods that can be used to perform string manipulation algorithms. + * + */ + +public final class StringHelper { + + public static final String DASH = "-"; + public static final String DOT = "."; + public static final String ELLIPSES = "..."; + public static final String LINE_FEED = "\n"; + public static final String SLASH = "/"; + public static final String COMMA = ","; + + /** + * Converts the specified string pattern to a regular expression string. If the supplied string is null or empty, + * then a regular expression that matches all strings (.*) is returned. + * <p> + * The expression passed to this method should not already be a regular expression. If it contains problematic + * meta-characters for this routine (such as period, asterisk, and plus), they will be escaped and matched literally + * in the resulting regular expression returned. + * </p> + * + * @param value + * The pattern that we need to convert to a regular expression + * @return The regular expression that is equivalent to the pattern + */ + public static String convertToRegex(String value) { + if (value == null || value.trim().length() == 0) { + return ".*"; + } + boolean appendEOL = false; + StringBuffer buffer = new StringBuffer(value.trim()); + + /* + * If there are any period characters, we need to escape them so that they are exactly matched + */ + Pattern pattern = Pattern.compile("\\."); + Matcher matcher = pattern.matcher(buffer); + int position = 0; + while (matcher.find(position)) { + buffer.replace(matcher.start(), matcher.end(), "\\."); + position = matcher.end() + 1; + } + + /* + * If there are any asterisks or pluses, which we need to interpret as wildcard characters, we need to convert + * them into .* or . + */ + pattern = Pattern.compile("\\*|\\+"); + matcher = pattern.matcher(buffer); + position = 0; + while (matcher.find(position)) { + String metachar = buffer.substring(matcher.start(), matcher.end()); + if (metachar.equals("*")) { + buffer.replace(matcher.start(), matcher.end(), ".*"); + position = matcher.end() + 1; + if (matcher.end() < buffer.length() - 1) { + appendEOL = true; + } + } else if (metachar.equals("+")) { + buffer.replace(matcher.start(), matcher.end(), "."); + position = matcher.end(); + if (matcher.end() == buffer.length()) { + appendEOL = true; + } + } + } + + /* + * If the string contains a .* meta-character sequence anywhere in the middle of the string (i.e., there are + * other characters following the .* meta-characters), OR the string ends with the .+ sequence, then we need to + * append the "end-of-line" boundary condition to the end of the string to get predictable results. + */ + if (appendEOL) { + buffer.append("$"); + } + return buffer.toString(); + } + + /** + * Takes a string that may possibly be very long and return a string that is at most maxLength. If the string is + * longer than maxLength, the last three characters will be the ellipses (...) to indicate that the string was + * shortened. + * + * @param possiblyLongString + * @param maxLength + * must be at least 4 (one character plus ellipses) + * @return possibly shortened string + */ + public static String getShortenedString(String possiblyLongString, int maxLength) { + if ((possiblyLongString != null) && (maxLength > ELLIPSES.length()) + && (possiblyLongString.length() > maxLength)) { + return possiblyLongString.substring(0, maxLength - ELLIPSES.length()) + ELLIPSES; + + } + return possiblyLongString; + } + + /** + * Determines that a provided string is not null and not empty (length = 0 after trimming) + * + * @param theString + * The string to be tested + * @return true if the string IS NOT null and is NOT empty + */ + public static boolean isNotNullNotEmpty(String theString) { + return ((theString != null) && (!theString.trim().isEmpty())); + } + + /** + * Determines that a provided string IS null or an empty string (length = 0 after trimming) + * + * @param theString + * The string to be tested + * @return true if the string IS null OR is empty + */ + public static boolean isNullOrEmpty(String theString) { + return ((theString == null) || (theString.trim().isEmpty())); + } + + /** + * Returns an indication if the first string is equal to the second string, allowing for either or both strings to + * be null. + * + * @param a + * The first string to be compared + * @param b + * The second string to be compared + * @return True if both strings are null, or both strings are non-null AND they are equal. False otherwise. + */ + public static boolean equals(String a, String b) { + return equals(a, b, false); + } + + /** + * Returns an indication if the first string is equal to the second string, allowing for either or both strings to + * be null, and ignoring case. + * + * @param a + * The first string to be compared + * @param b + * The second string to be compared + * @return True if both strings are null, or both strings are non-null AND they are equal (without regard to case). + * False otherwise. + */ + public static boolean equalsIgnoreCase(String a, String b) { + return equals(a, b, true); + } + + /** + * Compares two strings (allowing either or both to be null), and allowing for optional case sensitive or + * insensitive comparison. + * + * @param a + * The first string to be compared + * @param b + * The second string to be compared + * @param caseInsensitive + * True if the comparison is to be case in-sensitive. + * @return True if both strings are null, or both strings are non-null and they are equal + */ + private static boolean equals(String a, String b, boolean caseInsensitive) { + if (a == null && b == null) { + return true; + } + if (a != null && b != null) { + if (caseInsensitive) { + return a.equalsIgnoreCase(b); + } else { + return a.equals(b); + } + } + + return false; + } + + /** + * This method is used to mangle a name. + * <p> + * This method will first remove all unacceptable characters from the name and translate all characters to lower + * case. This is done to eliminate any potentially troublesome characters. If the resulting string is empty, then a + * random string of characters for the minimum desired length is returned. If the string is too short to meet the + * minimum length requirement, it is padded with random characters. + * </p> + * <p> + * Once the string has been scrubbed and possibly padded, it may be truncated (if longer than the maximum value) and + * the result is returned. To make the string as unique as possible, the algorithm removes excess letters from the + * center of the string, concatenating the first nad last parts of the name together. The assumption is that users + * tend to start the names of multiple things in similar ways, and get more descriptive as the name progresses. If + * for example, several objects were named "A test Object", "A test Object1", and "A test Object2", shortening the + * name only from the left does not generate a unique name. + * </p> + * + * @param name + * The name to be mangled + * @param minLen + * minimum number of characters for the name + * @param maxLen + * maximum number of characters for the name + * @return The mangled name, or an empty string if the value is null or an empty string. + */ + public static String mangleName(String name, int minLen, int maxLen) { + StringBuffer buffer = new StringBuffer(name == null ? "" : name); + Pattern pattern = Pattern.compile("[^a-z0-9]+", Pattern.CASE_INSENSITIVE); + Matcher matcher = pattern.matcher(buffer); + int position = 0; + while (matcher.find(position)) { + buffer.delete(matcher.start(), matcher.end()); + position = matcher.start(); + } + + if (buffer.length() < minLen) { + for (int i = buffer.length(); i <= minLen; i++) { + buffer.append("A"); + } + } + + /* + * Remove out of the center of the name to preserve start and end and result in a string of max len + */ + if (buffer.length() > maxLen) { + int excess = buffer.length() - maxLen; + int left = maxLen / 2; + + buffer.delete(left, excess + left); + } + + return buffer.toString().toLowerCase(); + } + + /** + * This method is used to normalize a string value. + * <p> + * This method will ensure that the string value is trimmed of all leading and trailing whitespace if not null. If + * it is null or an empty string, then it will return null. + * </p> + * + * @param value + * The value to be normalized + * @return The normalized (no leading or trailing whitespace) value, or null if the string was null or an empty + * string (or all whitespace). This method will never return an empty string. + */ + public static String normalizeString(String value) { + if (value != null) { + String temp = value.trim(); + if (temp.length() > 0) { + return temp; + } + } + return null; + } + + /** + * This method is used to strip all carriage returns and line feed characters from a string + * + * @param value + * @return The original value less all carriage returns and line feeds + */ + public static String stripCRLF(String value) { + + if (value == null) { + return null; + } + String[] tokens = value.split("\r\n|\n\r|\r|\n"); + StringBuffer buffer = new StringBuffer(); + for (String token : tokens) { + buffer.append(token.trim()); + } + return buffer.toString(); + } + + /** + * Converts UNIX-style line endings to DOS-style. Replaces LF with CR+LF as long as the LF does not already exist + * paired with a CR. + * + * @param content + * The content to be converted + * @return The converted content. + */ + public static String toDOSLines(String content) { + if (content == null) { + return null; + } + + StringBuffer buffer = new StringBuffer(content); + Pattern pattern = Pattern.compile("^(\n)[^\r]|[^\r](\n)[^\r]|[^\r](\n)$"); + Matcher matcher = pattern.matcher(buffer); + int position = 0; + while (matcher.find(position)) { + int index = matcher.start(1); + if (index == -1) { + index = matcher.start(2); + } + if (index == -1) { + index = matcher.start(3); + } + + buffer.replace(index, index + 1, "\r\n"); + position = index + 1; + } + + return buffer.toString(); + } + + /** + * This method will convert a string contents to use the UNIX-style line endings. That is, all occurrences of CR + * (Carriage Return) and LF (Line Feed) are reduced to just use LF. + * + * @param content + * The buffer to be processed + * @return The converted contents + */ + public static String toUnixLines(String content) { + if (content == null) { + return null; + } + + StringBuffer buffer = new StringBuffer(content); + Pattern pattern = Pattern.compile("\r\n|\n\r"); + Matcher matcher = pattern.matcher(buffer); + int position = 0; + while (matcher.find(position)) { + buffer.replace(matcher.start(), matcher.end(), "\n"); + position = matcher.start(); + } + + return buffer.toString(); + } + + /** + * This method is used to translate characters in the input sequence that match the characters in the match list to + * the corresponding character in the replacement list. If the replacement list is shorter than the match list, then + * the character from the replacement list is taken as the modulo of the match character position and the length of + * the replacement list. + * + * @param sequence + * The input sequence to be processed + * @param match + * The list of matching characters to be searched + * @param replacement + * The list of replacement characters, positional coincident with the match list. If shorter than the + * match list, then the position "wraps" around on the replacement list. + * @return The translated string contents. + */ + public static Object translate(String sequence, String match, String replacement) { + + if (sequence == null) { + return sequence; + } + + StringBuffer buffer = new StringBuffer(sequence); + + for (int index = 0; index < buffer.length(); index++) { + char ch = buffer.charAt(index); + + int position = match.indexOf(ch); + if (position == -1) { + continue; + } + + if (position >= replacement.length()) { + position %= replacement.length(); + } + buffer.setCharAt(index, replacement.charAt(position)); + } + + return buffer.toString(); + } + + /** + * Ensures that the name provided is a valid identifier. This means that no spaces are allowed as well as special + * characters. This method translates all spaces and illegal characters to underscores (_). + * + * @param name + * The name to be checked and converted to an identifier if needed + * @return The valid identifier from the name + */ + public static String validIdentifier(String name) { + if (name == null || name.length() == 0) { + return name; + } + + StringBuffer buffer = new StringBuffer(name); + for (int index = 0; index < buffer.length(); index++) { + char ch = buffer.charAt(index); + + if ((index == 0 && !Character.isJavaIdentifierStart(ch)) || (!Character.isJavaIdentifierPart(ch))) { + buffer.setCharAt(index, '_'); + } + } + return buffer.toString(); + } + + /** + * This method verifies that the provided string only contains characters from the legal set, and replaces any + * character not in the legal set with the specified replacement character. + * + * @param sequence + * The sequence to be verified + * @param legal + * The set of all legal characters + * @param replacement + * The replacement character if a character is not in the legal set + * @return The verified *and possibly updated) string + */ + public static String verify(String sequence, String legal, char replacement) { + if (sequence == null) { + return sequence; + } + + StringBuffer buffer = new StringBuffer(sequence); + for (int index = 0; index < buffer.length(); index++) { + char ch = buffer.charAt(index); + if (legal.indexOf(ch) == -1) { + buffer.setCharAt(index, replacement); + } + } + return buffer.toString(); + } + + /** + * Private constructor to prevent instantiation of this class - All methods are static! + */ + private StringHelper() { + + } + + /** + * @param list + * The list of elements + * @return The list of elements formatted as a comma-delimited list + */ + public static String asList(List<String> list) { + StringBuffer buffer = new StringBuffer(); + if (list != null) { + if (list.size() == 1) { + buffer.append(list.get(0)); + } else { + for (String element : list) { + buffer.append(element); + buffer.append(", "); + } + + if (buffer.length() > 2) { + buffer.delete(buffer.length() - 2, buffer.length()); + } + } + } + return buffer.toString(); + } + + /** + * @param map + * A map of strings + * @return A map expressed as a comma-delimited list of name=value tuples + */ + public static String asList(Map<String, String> map) { + StringBuffer buffer = new StringBuffer(); + if (map != null) { + Set<String> keys = map.keySet(); + for (String key : keys) { + buffer.append(String.format("%s=%s, ", key, map.get(key))); + } + + if (buffer.length() > 2) { + buffer.delete(buffer.length() - 2, buffer.length()); + } + } + return buffer.toString(); + } + + /** + * @param values + * An array or varargs of Strings to be concatenated into a comma-separated list + * @return The comma-seprated list of values + */ + public static String asList(String... values) { + StringBuilder builder = new StringBuilder(); + builder.append('['); + if (values != null && values.length > 0) { + int count = values.length; + for (int index = 0; index < count - 1; index++) { + builder.append(values[index]); + builder.append(','); + } + builder.append(values[count - 1]); + } + builder.append(']'); + return builder.toString(); + } + + public static Object resolveToType(String input) { + String intRegex = "^(\\-)?[0-9]+$"; + String doubleRegex = "^(\\-)?[0-9\\.]+$"; + String boolRegex = "(^(?i)((true)|(false))$)"; + + // Check for null + if (input == null) { + return null; + } + + // Check int first + if (input.matches(intRegex)) { + try { + return Integer.parseInt(input); + } catch (NumberFormatException nfe) { + // Should not happen + nfe.printStackTrace(); + } + } + + // Check double (int + decimal point) + if (input.matches(doubleRegex)) { + try { + return Double.parseDouble(input); + } catch (NumberFormatException | NullPointerException e) { + // NPE won't happen bc of regex check + } + } + + // Check boolean + if (input.matches(boolRegex)) { + return Boolean.parseBoolean(input); + } + + // Try to parse a date + Date date = Time.utcParse(input); + if (date != null) { + return date; + } + + // No special type, return string + return input; + } + + /** + * Converts a properties object to a string in the format of <pre>[ key=value, key=value, ... ]</pre> + * + * @param props + * The properties object to format + * @return A string in the format <pre>[ key=value, ... ]</pre> or null if the input was null + */ + public static String propertiesToString(Properties props) { + if (props == null) { + return null; + } + StringBuilder out = new StringBuilder(); + out.append("["); + for (Object key : props.keySet()) { + out.append(String.format(" %s = %s,", key.toString(), props.getProperty(key.toString()))); + } + if (props.size() > 0) { + out.deleteCharAt(out.lastIndexOf(",")); + } + out.append(" ]"); + return out.toString(); + } +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/StructuredPropertyHelper.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/StructuredPropertyHelper.java new file mode 100644 index 000000000..1705547c1 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/StructuredPropertyHelper.java @@ -0,0 +1,252 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * This class is used to assemble properties that are defined using a structured name into groups, and allow them to be + * processed as sets of definitions. + * <p> + * For example, a structured name uses a dotted-notation, like "provider.name". Further, the nodes of the structured + * name may be serialized using a suffix ordinal number (e.g., "provider1.name"). These structured properties form a + * hierarchical name space where the names are grouped together and can be retrieved as a set. + * </p> + * + */ + +public class StructuredPropertyHelper { + + /** + * This method scans the properties object for all properties that match the root name and constructs a list of + * structured property node graphs that represents the namespaces of the properties. + * <p> + * For example, assume that there are structured properties of the form "provider1.name", "provider2.name", + * "provider3.name", and so forth. There may also be other subordinate properties as well (e.g., "provider1.type"). + * This method would construct a list of graphs of nodes, where each node represents one value of the structured + * name. The roots would be the values "provider1", "provider2", "provider3", and so forth. The values of the + * subordinate nodes would be the second, third, and so forth name nodes of the compound name. The value of the + * property is associated with nodes that are representative of the leaf of the name space. + * </p> + * + * @param properties + * The properties to be processed + * @param prefix + * The prefix of the root structured property name + * @return The node graph of the properties + */ + public static List<Node> getStructuredProperties(Properties properties, String prefix) { + List<Node> roots = new ArrayList<>(); + + for (String name : properties.stringPropertyNames()) { + if (name.startsWith(prefix)) { + String value = properties.getProperty(name); + processNamespace(roots, name, value); + } + } + + return roots; + } + + /** + * This method recursively walks the name space of the structured property and constructs the node graph to + * represent the property + * + * @param nodes + * The collection of nodes for the current level of the name space + * @param propertyName + * The name of the node + * @param value + * The value, if any + * @return The node for this level in the namespace + */ + @SuppressWarnings("nls") + private static Node processNamespace(List<Node> nodes, String propertyName, String value) { + String[] tokens = propertyName.split("\\.", 2); + String nodeName = normalizeNodeName(tokens[0]); + + Node namespaceNode = null; + for (Node node : nodes) { + if (node.getName().equals(nodeName)) { + namespaceNode = node; + break; + } + } + if (namespaceNode == null) { + namespaceNode = new Node(); + namespaceNode.setName(nodeName); + nodes.add(namespaceNode); + } + + if (tokens.length == 1 || tokens[1] == null || tokens[1].length() == 0) { + namespaceNode.setValue(value); + } else { + processNamespace(namespaceNode.getChildren(), tokens[1], value); + } + + return namespaceNode; + } + + /** + * This method normalizes a node name of the structured property name by removing leading and trailing whitespace, + * and by converting any ordinal position to a simple expression without leading zeroes. + * + * @param token + * The token to be normalized + * @return The normalized name, or null if the token was null; + */ + @SuppressWarnings("nls") + private static String normalizeNodeName(String token) { + if (token == null) { + return null; + } + + StringBuffer buffer = new StringBuffer(token.trim()); + Pattern pattern = Pattern.compile("([^0-9]+)([0-9]*)"); + Matcher matcher = pattern.matcher(buffer); + if (matcher.matches()) { + String nameRoot = matcher.group(1); + String ordinal = matcher.group(2); + if (ordinal != null && ordinal.length() > 0) { + int i = Integer.parseInt(ordinal); + buffer.setLength(0); + buffer.append(nameRoot); + buffer.append(Integer.toString(i)); + } + } + return buffer.toString(); + } + + /** + * This class represents a node in the structured property name space + * + */ + public static class Node implements Comparable<Node> { + + /** + * The name of the structured property node + */ + private String name; + + /** + * If the node is a leaf, then the value of the property + */ + private String value; + + /** + * If the node is not a leaf, then the sub-nodes of the property + */ + private List<Node> children; + + /** + * @return the value of name + */ + public String getName() { + return name; + } + + /** + * @param name + * the value for name + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the value of value + */ + public String getValue() { + return value; + } + + /** + * @param value + * the value for value + */ + public void setValue(String value) { + this.value = value; + } + + /** + * @return the value of children + */ + public List<Node> getChildren() { + if (children == null) { + children = new ArrayList<>(); + } + return children; + } + + /** + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return name.hashCode() + (value != null ? value.hashCode() : children.hashCode()); + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + Node other = (Node) obj; + boolean result = name.equals(other.name); + + if (value == null) { + result &= other.value == null; + } else { + result &= value.equals(other.value); + } + if (children == null) { + result &= other.children == null; + } else { + result &= children.equals(other.children); + } + return result; + } + + /** + * @see java.lang.Object#toString() + */ + @SuppressWarnings("nls") + @Override + public String toString() { + if (value != null) { + return String.format("%s = %s", name, value); + } + return String.format("%s.%s", name, children.toString()); + } + + @Override + public int compareTo(StructuredPropertyHelper.Node o) { + return name.compareTo(o.name); + } + } +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/Time.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/Time.java new file mode 100644 index 000000000..147ae2ca7 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/Time.java @@ -0,0 +1,608 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.util; + +import java.sql.Timestamp; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.Locale; +import java.util.SimpleTimeZone; +import java.util.TimeZone; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is a general purpose helper class to augment standard Java time support. + * + */ + +public final class Time { + + /** + * Logger to log operations + */ + private static final Logger LOG = LoggerFactory.getLogger(Time.class); + + /** + * A formatter to be used to format values + */ + private static SimpleDateFormat dateformatter = null; + + /** + * The UTC timezone (for UTC or GMT time) + */ + @SuppressWarnings("nls") + private static final TimeZone utcTZ = TimeZone.getTimeZone("UTC"); + + /** + * The cached reference to the datatype factory + */ + private static DatatypeFactory xmlDatatypeFactory = null; + + /** + * Private default constructor prevents instantiation + */ + private Time() { + // + } + + /** + * Increments a date by the indicated months, days, hours, minutes, and seconds, and returns the updated date. + * + * @param date + * The date to be manipulated + * @param months + * The number of months to be added to the date + * @param days + * The number of days to be added to the date + * @param hours + * The number of hours to be added to the date + * @param minutes + * The number of minutes to be added to the date + * @param seconds + * The number of seconds to be added to the date + * @return The updated date. + */ + public static Date addTime(final Date date, final int months, final int days, final int hours, final int minutes, + final int seconds) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + cal.add(Calendar.MONTH, months); + cal.add(Calendar.DATE, days); + cal.add(Calendar.HOUR_OF_DAY, hours); + cal.add(Calendar.MINUTE, minutes); + cal.add(Calendar.SECOND, seconds); + return cal.getTime(); + } + + /** + * Clears the time components of a calendar to zero, leaving the date components unchanged. + * + * @param cal + * the calendar to be updated + * @return The updated calendar object + */ + public static Calendar dateOnly(final Calendar cal) { + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + return cal; + } + + /** + * This method returns the local time that corresponds to the end of the current day + * + * @return The time that corresponds to the end of the current day, expressed as local time + */ + public static Date endOfDayLocal() { + return endOfDayLocal(new Date()); + } + + /** + * This method returns the last moment of the day for the supplied local time. This is defined as the millisecond + * before midnight of the current date represented by the local time. + * + * @param localTime + * The local time for which the last moment of the day is desired. + * @return The millisecond prior to midnight, local time. + */ + public static Date endOfDayLocal(final Date localTime) { + // @sonar:off + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTime(localTime); + calendar.set(Calendar.HOUR, 11); + calendar.set(Calendar.AM_PM, Calendar.PM); + calendar.set(Calendar.MINUTE, 59); + calendar.set(Calendar.SECOND, 59); + calendar.set(Calendar.MILLISECOND, 999); + // @sonar:on + + return calendar.getTime(); + } + + /** + * The end of the current day and in the current time zone expressed as a UTC time. + * + * @return The UTC time that corresponds to the end of the current day + */ + public static Date endOfDayUTC() { + return endOfDayUTC(new Date()); + } + + /** + * Returns the UTC time that corresponds to the end of the day for the local time specified, using the current + * (default) time zone. + * + * @param localTime + * The local time for which we are requesting the UTC time that corresponds to the end of the day + * @return The UTC time that corresponds to the end of the local day specified by the local time. + */ + public static Date endOfDayUTC(final Date localTime) { + return endOfDayUTC(localTime, TimeZone.getDefault()); + } + + /** + * Returns the time expressed in UTC time of the end of the day specified in local time and within the local time + * zone. + * + * @param localTime + * The local time for which we will compute the end of the local day, and then convert to UTC time. + * @param localTimeZone + * The time zone that the local time is within. + * @return The UTC date that corresponds to the end of the day local time and in the local time zone. + */ + public static Date endOfDayUTC(final Date localTime, final TimeZone localTimeZone) { + Date endOfDay = endOfDayLocal(localTime); + return utcDate(endOfDay, localTimeZone); + } + + /** + * returns current Date in 'UTC' Timezone + * + * @return The current date, expressed in the UTC timezone. + */ + @SuppressWarnings("nls") + public static Date getCurrentUTCDate() { + + // This code incorrectly changes the default timezone for the entire JVM in order to compute the UTC + // date for the current time. + + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTimeZone(TimeZone.getTimeZone("UTC")); + calendar.setTimeInMillis(utcTime()); + return calendar.getTime(); + } + + /** + * This method loads and caches the reference to the XML data type factory object. + * + * @return The XML Data Type Factory object + */ + public static DatatypeFactory getDatatypeFactory() { + if (xmlDatatypeFactory == null) { + try { + xmlDatatypeFactory = DatatypeFactory.newInstance(); + } catch (DatatypeConfigurationException e) { + e.printStackTrace(System.err); + } + } + return xmlDatatypeFactory; + } + + /** + * Gives the date-time String based on given Locale and Timezone + * + * @param date + * The date to be formatted + * @param locale + * The locale that we want to format the value for + * @param timezone + * The time zone that the date is within + * @return The formatted value + */ + public static String getDateByLocaleAndTimeZone(final Date date, final Locale locale, final TimeZone timezone) { + String strDate = null; + DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, locale); + df.setTimeZone(timezone); + synchronized (df) { + strDate = df.format(date); + } + return strDate; + } + + /** + * Returns singleton UTC date formatter. + * + * @return + */ + @SuppressWarnings("nls") + private static SimpleDateFormat getDateFormatter() { + if (dateformatter == null) { + dateformatter = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); + dateformatter.setTimeZone(new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC")); + } + return dateformatter; + } + + /** + * This method returns the local time that corresponds to a given UTC time in the current time zone. + * + * @param utcTime + * The UTC time for which we desire the equivalent local time in the current time zone. + * @return The local time that is equivalent to the given UTC time for the current time zone + */ + public static long localTime(final long utcTime) { + return localTime(utcTime, TimeZone.getDefault()); + } + + /** + * This method can be used to get the local time that corresponds to a specific UTC time. + * <p> + * This method has a problem since the offset can only be determined by having a local time. So, we take the UTC + * time and add the raw offset to it to come up with an approximation of the local time. This gives us a local time + * that we can use to determine what the offset should be, which is what we actually add to the UTC time to get the + * local time. + * </p> + * + * @param utcTime + * The UTC time for which we want to obtain the equivalent local time + * @param localTZ + * The time zone that we want the local time to be within + * @return The local time for the specified time zone and the given UTC time + */ + public static long localTime(final long utcTime, final TimeZone localTZ) { + int offset = localTZ.getOffset(utcTime + localTZ.getRawOffset()); + long result = utcTime + offset; + + return result; + } + + /** + * Sets the date components of a calendar to the specified values, leaving the time components unchanged. + * + * @param cal + * The calendar to be updated + * @param year + * The year to be set + * @param month + * The month to be set + * @param day + * The day to be set + * @return The updated calendar object + */ + public static Calendar setDate(final Calendar cal, final int year, final int month, final int day) { + cal.set(Calendar.YEAR, year); + cal.set(Calendar.MONTH, month); + cal.set(Calendar.DAY_OF_MONTH, day); + return cal; + } + + /** + * Returns the start of the day expressed in local time for the current local time. + * + * @return The start of the day + */ + public static Date startOfDayLocal() { + return startOfDayLocal(new Date()); + } + + /** + * This method returns the date that corresponds to the start of the day local time. The date returned represents + * midnight of the previous day represented in local time. If the UTC time is desired, use the methods + * {@link #startOfDayUTC(Date, TimeZone)}, {@link #startOfDayUTC(Date)}, or {@link #startOfDayUTC()} + * + * @param localTime + * The local date that we wish to compute the start of day for. + * @return The date that corresponds to the start of the local day + */ + public static Date startOfDayLocal(final Date localTime) { + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTime(localTime); + calendar.set(Calendar.HOUR, 0); + calendar.set(Calendar.AM_PM, Calendar.AM); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + + return calendar.getTime(); + } + + /** + * This method returns the UTC date that corresponds to the start of the local day based on the current time and the + * default time zone (the time zone we are running in). + * + * @return The start of the local day expressed as a UTC time. + */ + public static Date startOfDayUTC() { + return startOfDayUTC(new Date()); + } + + /** + * This method returns the UTC date that corresponds to the start of the local day specified in the current time + * zone. + * + * @param localTime + * The local time to be used to compute the start of the day + * @return The start of the local day expressed as a UTC time. + */ + public static Date startOfDayUTC(final Date localTime) { + return startOfDayUTC(localTime, TimeZone.getDefault()); + } + + /** + * This method returns the UTC date that corresponds to the start of the local day specified in the local timezone. + * + * @param localTime + * The local time to be used to compute start of day + * @param localTimeZone + * The time zone that the local time was recorded within + * @return The corresponding UTC date + */ + public static Date startOfDayUTC(final Date localTime, final TimeZone localTimeZone) { + Date startOfDay = startOfDayLocal(localTime); + return utcDate(startOfDay, localTimeZone); + } + + /** + * This method creates and returns an XML timestamp expressed as the current UTC value for the system. The caller + * does not specify the time value or time zone using this method. This ensures that the timestamp value is always + * expressed as UTC time. + * + * @return The XMLGregorianCalendar that can be used to record the timestamp + */ + + public static XMLGregorianCalendar timestamp() { + getDatatypeFactory(); + XMLGregorianCalendar ts = xmlDatatypeFactory.newXMLGregorianCalendar(); + GregorianCalendar utc = new GregorianCalendar(); + utc.setTime(utcDate()); + ts.setTimezone(0); + ts.setYear(utc.get(Calendar.YEAR)); + // Calendar Months are from 0-11 need to +1 + ts.setMonth(utc.get(Calendar.MONTH) + 1); + ts.setDay(utc.get(Calendar.DAY_OF_MONTH)); + ts.setHour(utc.get(Calendar.HOUR_OF_DAY)); + ts.setMinute(utc.get(Calendar.MINUTE)); + ts.setSecond(utc.get(Calendar.SECOND)); + ts.setMillisecond(utc.get(Calendar.MILLISECOND)); + return ts; + } + + /** + * Converts XMLGregorianCalendar to java.util.Date in Java + * + * @param calendar + * the calendar object to be converted + * @return The equivalent Date object + */ + public static Date toDate(final XMLGregorianCalendar calendar) { + if (calendar == null) { + return null; + } + return calendar.toGregorianCalendar().getTime(); + } + + /** + * Converts java Date to XMLGregorianCalendar. + * + * @param date + * The date to convert + * @return The XMLGregorianCalendar for the specified date + */ + @SuppressWarnings("nls") + public static XMLGregorianCalendar toXMLCalendar(final Date date) { + GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance(); + cal.setTime(date); + + XMLGregorianCalendar xmlCal = null; + try { + xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(cal); + } catch (DatatypeConfigurationException e) { + LOG.error("toXMLCalendar", e); + } + return xmlCal; + } + + /** + * Truncates the provided date so that only the date, hours, and minutes portions are significant. This method + * returns the date with the seconds and milliseconds forced to zero. + * + * @param date + * The date to truncate + * @return The date with only the year, month, day, hours, and minutes significant. + */ + public static Date truncDate(final Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + return cal.getTime(); + } + + /** + * The UTC date that corresponds to the current date in the local time zone. + * + * @return The UTC date for now in the current time zone. + */ + public static Date utcDate() { + return new Date(); + } + + /** + * The UTC date for the specified date in the current (default) time zone. + * + * @param date + * The local date for which the UTC date is desired. + * @return The UTC date that corresponds to the date in the current time zone. + */ + public static Date utcDate(final Date date) { + TimeZone tz = TimeZone.getDefault(); + return utcDate(date, tz); + } + + /** + * Returns the UTC date for the specified date in the specified time zone. + * + * @param date + * The date for which the UTC date is desired in the specified zone + * @param tz + * The time zone that corresponds to the date to be converted to UTC + * @return The UTC date that corresponds to the local date in the local time zone. + */ + public static Date utcDate(final Date date, final TimeZone tz) { + return new Date(utcTime(date.getTime(), tz)); + } + + /** + * Format incoming date as string in GMT or UTC. + * + * @param dt + * The date to be formatted + * @return The date formatted for UTC timezone + */ + public static String utcFormat(final Date dt) { + String strDate = null; + DateFormat df = getDateFormatter(); + synchronized (df) { + strDate = df.format(dt); + } + return strDate; + } + + /** + * Parse previously formated Date object back to a Date object. + * + * @param dateStr + * The representation of a UTC date as a string + * @return The date object containing the parsed representation, or null if the representation cannot be parsed + */ + @SuppressWarnings("nls") + public static Date utcParse(final String dateStr) { + String[] adtl = { + "yyyy-MM-dd" + }; + return utcParse(dateStr, adtl); + } + + /** + * Parse previously formated Date object back to a Date object. + * + * @param dateStr + * The representation of a UTC date as a string + * @param adtlFormatStrings + * A list of strings that represent additional date format representations to try and parse. + * @return The date object containing the parsed representation, or null if the representation cannot be parsed + */ + @SuppressWarnings("nls") + public static Date utcParse(final String dateStr, String... adtlFormatStrings) { + if (dateStr != null) { + // Build the list of formatters starting with the default defined in the class + List<DateFormat> formats = new ArrayList<>(); + formats.add(getDateFormatter()); + + if (adtlFormatStrings != null) { + for (String s : adtlFormatStrings) { + formats.add(new SimpleDateFormat(s)); + } + } + + // Return the first matching date formatter's result + for (DateFormat df : formats) { + df.setTimeZone(utcTZ); + try { + return df.parse(dateStr); + } catch (ParseException e) { + LOG.debug(String.format("IGNORE - Date string [%s] does not fit pattern [%s]", dateStr, + df.toString())); + } + } + } + return null; + } + + /** + * This method returns the current time for the UTC timezone + * + * @return The time in the UTC time zone that corresponds to the current local time. + */ + public static long utcTime() { + return new Date().getTime(); + } + + /** + * Get the UTC time that corresponds to the given time in the default time zone (current time zone for the system). + * + * @param localTime + * The time in the current time zone for which the UTC time is desired. + * @return The UTC time + */ + public static long utcTime(final long localTime) { + TimeZone tz = TimeZone.getDefault(); + return utcTime(localTime, tz); + } + + /** + * Get the UTC time that corresponds to the given time in the specified timezone. + * <p> + * Note that the java <code>getOffset()</code> method works a little counter-intuitive. It returns the offset that + * would be added to the current UTC time to get the LOCAL time represented by the local time zone. That means to + * get the UTC time, we need to SUBTRACT this offset from the local time. + * </p> + * + * @param localTime + * The time in the specified time zone for which the UTC time is desired. + * @param localTZ + * The time zone which the local time is in. + * @return The UTC time for the specified local time in the specified local time zone. + */ + public static long utcTime(final long localTime, final TimeZone localTZ) { + int offset = localTZ.getOffset(localTime); + return localTime - offset; + + } + + /** + * Creates a timestamp value from a time + * + * @param utcTime + * The UTC time to convert to a timestamp + * @return The timestamp + */ + public static Timestamp utcTimestamp(final long utcTime) { + TimeZone tz = TimeZone.getDefault(); + return new Timestamp(utcTime(utcTime, tz)); + } +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/UnmodifiableProperties.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/UnmodifiableProperties.java new file mode 100644 index 000000000..50bc96ff5 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/UnmodifiableProperties.java @@ -0,0 +1,353 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.Reader; +import java.io.Writer; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.InvalidPropertiesFormatException; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +/** + * This utility class is used to wrap a properties object and to delegate all read operations to the property object, + * while disallowing any write or modification to the property object. + * + */ +public class UnmodifiableProperties extends Properties implements Cloneable { + + /** + * Serial number + */ + private static final long serialVersionUID = 1L; + + private static final String PROPERTY_CANNOT_BE_MODIFIED_MSG = "Property cannot be modified!"; + + /** + * The properties object which we are wrapping + */ + private Properties properties; + + /** + * Create the unmodifiable wrapper around the provided properties object + * + * @param properties + * The properties to be wrapped and protected from modification + */ + public UnmodifiableProperties(Properties properties) { + this.properties = properties; + } + + /** + * @see java.util.Hashtable#clear() + */ + @Override + public synchronized void clear() { + throw new UnsupportedOperationException(PROPERTY_CANNOT_BE_MODIFIED_MSG); + } + + /** + * @see java.util.Hashtable#clone() + */ + // @sonar:off + @Override + public synchronized Object clone() { + throw new UnsupportedOperationException(PROPERTY_CANNOT_BE_MODIFIED_MSG); + } + + // @sonar:on + + /** + * @see java.util.Hashtable#contains(java.lang.Object) + */ + @Override + public synchronized boolean contains(Object value) { + return properties.contains(value); + } + + /** + * @see java.util.Hashtable#containsKey(java.lang.Object) + */ + @Override + public synchronized boolean containsKey(Object key) { + return properties.containsKey(key); + } + + /** + * @see java.util.Hashtable#containsValue(java.lang.Object) + */ + @Override + public boolean containsValue(Object value) { + return properties.containsValue(value); + } + + /** + * @see java.util.Hashtable#elements() + */ + @Override + public synchronized Enumeration<Object> elements() { + return properties.elements(); + } + + /** + * @see java.util.Hashtable#entrySet() + */ + @Override + public Set<java.util.Map.Entry<Object, Object>> entrySet() { + return Collections.unmodifiableSet(properties.entrySet()); + } + + /** + * @see java.util.Hashtable#equals(java.lang.Object) + */ + @Override + public synchronized boolean equals(Object o) { + return properties.equals(o); + } + + /** + * @see java.util.Hashtable#get(java.lang.Object) + */ + @Override + public synchronized Object get(Object key) { + return properties.get(key); + } + + /** + * @see java.util.Properties#getProperty(java.lang.String) + */ + @Override + public String getProperty(String key) { + return properties.getProperty(key); + } + + /** + * @see java.util.Properties#getProperty(java.lang.String, java.lang.String) + */ + @Override + public String getProperty(String key, String defaultValue) { + return properties.getProperty(key, defaultValue); + } + + /** + * @see java.util.Hashtable#hashCode() + */ + @Override + public synchronized int hashCode() { + return properties.hashCode(); + } + + /** + * @see java.util.Hashtable#isEmpty() + */ + @Override + public synchronized boolean isEmpty() { + return properties.isEmpty(); + } + + /** + * @see java.util.Hashtable#keys() + */ + @Override + public synchronized Enumeration<Object> keys() { + return properties.keys(); + } + + /** + * @see java.util.Hashtable#keySet() + */ + @Override + public Set<Object> keySet() { + return Collections.unmodifiableSet(properties.keySet()); + } + + /** + * @see java.util.Properties#list(java.io.PrintStream) + */ + @Override + public void list(PrintStream out) { + properties.list(out); + } + + /** + * @see java.util.Properties#list(java.io.PrintWriter) + */ + @Override + public void list(PrintWriter out) { + properties.list(out); + } + + /** + * @see java.util.Properties#load(java.io.InputStream) + */ + @Override + public synchronized void load(InputStream inStream) throws IOException { + throw new UnsupportedOperationException(PROPERTY_CANNOT_BE_MODIFIED_MSG); + } + + /** + * @see java.util.Properties#load(java.io.Reader) + */ + @Override + public synchronized void load(Reader reader) throws IOException { + throw new UnsupportedOperationException(PROPERTY_CANNOT_BE_MODIFIED_MSG); + } + + /** + * @see java.util.Properties#loadFromXML(java.io.InputStream) + */ + @Override + public synchronized void loadFromXML(InputStream in) throws IOException, InvalidPropertiesFormatException { + throw new UnsupportedOperationException(PROPERTY_CANNOT_BE_MODIFIED_MSG); + } + + /** + * @see java.util.Properties#propertyNames() + */ + @Override + public Enumeration<?> propertyNames() { + return properties.propertyNames(); + } + + /** + * @see java.util.Hashtable#put(java.lang.Object, java.lang.Object) + */ + @Override + public synchronized Object put(Object key, Object value) { + throw new UnsupportedOperationException(PROPERTY_CANNOT_BE_MODIFIED_MSG); + } + + /** + * @see java.util.Hashtable#putAll(java.util.Map) + */ + @Override + public synchronized void putAll(Map<? extends Object, ? extends Object> t) { + throw new UnsupportedOperationException(PROPERTY_CANNOT_BE_MODIFIED_MSG); + } + + /** + * @see java.util.Hashtable#rehash() + */ + @Override + protected void rehash() { + throw new UnsupportedOperationException(PROPERTY_CANNOT_BE_MODIFIED_MSG); + } + + /** + * @see java.util.Hashtable#remove(java.lang.Object) + */ + @Override + public synchronized Object remove(Object key) { + throw new UnsupportedOperationException(PROPERTY_CANNOT_BE_MODIFIED_MSG); + } + + /** + * @see java.util.Properties#save(java.io.OutputStream, java.lang.String) + */ + @Override + @Deprecated + public synchronized void save(OutputStream out, String comments) { + properties.save(out, comments); + } + + /** + * @see java.util.Properties#setProperty(java.lang.String, java.lang.String) + */ + @Override + public synchronized Object setProperty(String key, String value) { + throw new UnsupportedOperationException(PROPERTY_CANNOT_BE_MODIFIED_MSG); + } + + /** + * @see java.util.Hashtable#size() + */ + @Override + public synchronized int size() { + return properties.size(); + } + + /** + * @see java.util.Properties#store(java.io.OutputStream, java.lang.String) + */ + @Override + public void store(OutputStream out, String comments) throws IOException { + properties.store(out, comments); + } + + /** + * @see java.util.Properties#store(java.io.Writer, java.lang.String) + */ + @Override + public void store(Writer writer, String comments) throws IOException { + properties.store(writer, comments); + } + + /** + * @see java.util.Properties#storeToXML(java.io.OutputStream, java.lang.String) + */ + @Override + public synchronized void storeToXML(OutputStream os, String comment) throws IOException { + properties.storeToXML(os, comment); + } + + /** + * @see java.util.Properties#storeToXML(java.io.OutputStream, java.lang.String, java.lang.String) + */ + @Override + public synchronized void storeToXML(OutputStream os, String comment, String encoding) throws IOException { + properties.storeToXML(os, comment, encoding); + } + + /** + * @see java.util.Properties#stringPropertyNames() + */ + @Override + public Set<String> stringPropertyNames() { + return properties.stringPropertyNames(); + } + + /** + * @see java.util.Hashtable#toString() + */ + @Override + public synchronized String toString() { + return properties.toString(); + } + + /** + * @see java.util.Hashtable#values() + */ + @Override + public Collection<Object> values() { + return Collections.unmodifiableCollection(properties.values()); + } +} diff --git a/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/httpClient.java b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/httpClient.java new file mode 100644 index 000000000..0847c4091 --- /dev/null +++ b/app-c/appc/appc-common/src/main/java/org/openecomp/appc/util/httpClient.java @@ -0,0 +1,207 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.util; + +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URL; + + +public class httpClient { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(httpClient.class); + + private static Configuration configuration = ConfigurationFactory.getConfiguration(); + + @SuppressWarnings("deprecation") + public static int postMethod(String protocol, String ip, int port, String path, String payload, String contentType) throws APPCException { + + logger.info("Sending POST request to " + path); + + HttpPost post; + try { + + URL serviceUrl = new URL(protocol, ip, port, path); + post = new HttpPost(serviceUrl.toExternalForm()); + post.setHeader("Content-Type", contentType); + + StringEntity entity = new StringEntity(payload); + entity.setContentType(contentType); + post.setEntity(new StringEntity(payload)); + } catch (UnsupportedEncodingException | MalformedURLException e) { + throw new APPCException(e); + } + + logger.debug("Sending request " + post); + + CredentialsProvider credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials( + new AuthScope(ip, port), + new UsernamePasswordCredentials(configuration.getProperty("username"), configuration.getProperty("password"))); + CloseableHttpClient client = HttpClients.custom() + .setDefaultCredentialsProvider(credsProvider).build(); + + int httpCode; + try { + HttpResponse response = client.execute(post); + httpCode = response.getStatusLine().getStatusCode(); + } catch (IOException e) { + throw new APPCException(e); + } + return httpCode; + } + + @SuppressWarnings("deprecation") + public static int putMethod(String protocol, String ip, int port, String path, String payload, String contentType) throws APPCException { + + logger.info("Sending PUT request to " + path); + + HttpPut put; + try { + + URL serviceUrl = new URL(protocol, ip, port, path); + put = new HttpPut(serviceUrl.toExternalForm()); + put.setHeader("Content-Type", contentType); + + StringEntity entity = new StringEntity(payload); + entity.setContentType(contentType); + put.setEntity(new StringEntity(payload)); + } catch (UnsupportedEncodingException | MalformedURLException e) { + throw new APPCException(e); + } + + logger.debug("Sending request " + put); + + CredentialsProvider credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials( + new AuthScope(ip, port), + new UsernamePasswordCredentials(configuration.getProperty("username"), configuration.getProperty("password"))); + CloseableHttpClient client = HttpClients.custom() + .setDefaultCredentialsProvider(credsProvider).build(); + + int httpCode; + try { + HttpResponse response = client.execute(put); + httpCode = response.getStatusLine().getStatusCode(); + } catch (IOException e) { + throw new APPCException(e); + } + return httpCode; + } + + @SuppressWarnings("deprecation") + public static String getMethod(String protocol, String ip, int port, String path, String contentType) throws APPCException { + + logger.info("Sending GET request to " + path); + + HttpGet get; + try { + + URL serviceUrl = new URL(protocol, ip, port, path); + get = new HttpGet(serviceUrl.toExternalForm()); + get.setHeader("Content-Type", contentType); + } catch (MalformedURLException e) { + throw new APPCException(e); + } + + logger.debug("Sending request " + get); + + CredentialsProvider credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials( + new AuthScope(ip, port), + new UsernamePasswordCredentials(configuration.getProperty("username"), configuration.getProperty("password"))); + CloseableHttpClient client = HttpClients.custom() + .setDefaultCredentialsProvider(credsProvider).build(); + + int httpCode; + String result; + + try { + HttpResponse response = client.execute(get); + httpCode = response.getStatusLine().getStatusCode(); + result = (httpCode == HttpStatus.SC_OK) ? response.getEntity().toString() : null; + } catch (IOException e) { + throw new APPCException(e); + } + + return result; + } + + @SuppressWarnings("deprecation") + public static int deleteMethod(String protocol, String ip, int port, String path, String contentType) throws APPCException { + + logger.info("Sending DELETE request to " + path); + + HttpDelete delete; + try { + + URL serviceUrl = new URL(protocol, ip, port, path); + delete = new HttpDelete(serviceUrl.toExternalForm()); + delete.setHeader("Content-Type", contentType); + } catch (MalformedURLException e) { + throw new APPCException(e); + } + + logger.debug("Sending request " + delete); + + CredentialsProvider credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials( + new AuthScope(ip, port), + new UsernamePasswordCredentials(configuration.getProperty("username"), configuration.getProperty("password"))); + CloseableHttpClient client = HttpClients.custom() + .setDefaultCredentialsProvider(credsProvider).build(); + + int httpCode; + String result; + + try { + HttpResponse response = client.execute(delete); + httpCode = response.getStatusLine().getStatusCode(); + } catch (IOException e) { + throw new APPCException(e); + } + + return httpCode; + } +} diff --git a/app-c/appc/appc-common/src/main/resources/org/openecomp/appc/i18n/MessageResources.properties b/app-c/appc/appc-common/src/main/resources/org/openecomp/appc/i18n/MessageResources.properties new file mode 100644 index 000000000..0c571cbae --- /dev/null +++ b/app-c/appc/appc-common/src/main/resources/org/openecomp/appc/i18n/MessageResources.properties @@ -0,0 +1,792 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# This property file contains all message definitions used by APPC +# +# Message resources are identified by a key, which is defined in the Msg enumeration. This key is +# assigned a value which consists of 4 parts separated by a pipe (|) symbol. These parts are: +# +# 1. The message identifier +# 2. The Message text to be formatted and issued to the user +# 3. The suggested resolution text, how to fix the problem. +# 4. The description text, what is the problem so the user can understand +# +CONFIGURATION_STARTED=APPC0001I|\ + ECOMP Application Controller (APP-C) initialization started at {0}|\ + No resolution is required, this is an informational message|\ + The APP-C component configuration has been started because the component is being \ + initialized or loaded for the first time, or a new instance of the component is \ + being created. This message indicates that the component is starting. + +CONFIGURATION_CLEARED=APPC0002I|\ + All prior configuration has been cleared|\ + No resolution is required, this is an informational message|\ + The APP-C component is being started or restarted and any prior configuration \ + (if present), is cleared. This is normal. + +LOADING_CONFIGURATION_OVERRIDES=APPC0003I|\ + Loading configuration properties from file "{0}"|\ + No resolution is required, this is an informational message|\ + This message indicates that the configuration of the APP-C component was located \ + and is being loaded from the specified file. + +LOADING_DEFAULTS=APPC0004I|\ + Configuration defaults loaded from resource file "{0}"|\ + No resolution is required, this is an informational message|\ + This is a normal indication that the default configuration settings were loaded \ + from the resource file. The APP-C components load a default configuration first \ + so that all configuration values have valid default settings. Any user configuation \ + that may be specified then overrides these defaults. + +NO_DEFAULTS_FOUND=APPC0005E|\ + No default property resource "{0}" was found!|\ + This is an internal error. Contact support.|\ + This is an internal error that indicates that the default resource property file \ + could not be located. This is likely a packaging error and is indicative of \ + a construction problem. Refer this to development or level 3 support for assistance. + +PROPERTY_VALUE=APPC0006I|\ + Property "{0}" ="{1}"|\ + No resolution is required, this is an informational message|\ + This message is issued to show the value of configuration properties and is used to \ + debug start up of the component. + +NO_OVERRIDE_PROPERTY_FILE_LOADED=APPC0007E|\ + No configuration file named [{0}] was found on the configuration search path [{1}]. \ + If a configuration file should have been loaded, check the file name and search \ + path specified. APPC will proceed using the default values and command-line \ + overrides (if any).|\ + If a configuration file was expected, verify the file name and that it exists on \ + the search path for the configuration properties. The search path defaults to \ + <em>${user.home},/opt/app/appc/etc,etc,../etc,/etc,.</em> and can be overridden \ + by specification of the property <em>org.openecomp.appc.bootstrap.path</em>. The \ + property file name defaults to <em>appc.properties</em> and can also be \ + overridden by the <em>org.openecomp.appc.bootstrap.file</em> property.|\ + This message indicates that the bootstrap path was searched for the bootstrap \ + property file (a file that can be supplied to configure APPC) and that no file \ + with the specified name was found on any of the path elements of the path. + +SEARCHING_CONFIGURATION_OVERRIDES=APPC0008I|\ + Searching path "{0}" for configuration settings "{1}"|\ + No resolution is required|\ + This message indicates that the specified path is being examined for a configuration \ + file of the indicated name. The configuration file defaults to <em>appc.properties</em> \ + but can be overridden by specification of the <em>org.openecomp.appc.bootstrap.file</em> \ + property (using a command-line override, for example). This message is intended to \ + assist in the debugging and analysis of configuration issues where the indicated \ + file may not be processed or found. The path that is searched is a comma-delimited \ + list of directories and defaults to <em>${user.home},/opt/app/appc/etc,etc,../etc,/etc,.</em> \ + but can also be overridden by specification of the <em>org.openecomp.appc.bootstrap.path</em> \ + property. + +LOADING_APPLICATION_OVERRIDES=APPC0009I|\ + Loading application-specific override properties|\ + No resolution required|\ + This message indicates that the APPC component was invoked as an embedded component \ + and that the caller has supplied an override property object. + +NO_APPLICATION_OVERRIDES=APPC0010I|\ + No application-specific override properties were provided!|\ + No resolution required|\ + This message indicates that the APPC component was invoked as an embedded component \ + and that the caller has supplied an override property object, but that object was \ + empty. + +MERGING_SYSTEM_PROPERTIES=APPC0011I|\ + Merging system properties into configuration|\ + No resolution is required|\ + This message indicates that the java virtual machine system properties are being \ + examined and merged into the APP-C component configuration. This allows for command \ + line specification of any APP-C configuration property as a standard java define \ + JVM option (ex: -Dproperty=value). + +SETTING_SPECIAL_PROPERTY=APPC0012I|\ + Setting property "{0}={1}" in system properties|\ + No resolution required.|\ + This message indicates that the specified property loaded from defaults, property \ + file overrides, application overrides, or command-line overrides is being placed \ + in the system (java virtual machine) properties object. Some libraries that may \ + be integrated with APP-C (for example, DME2 or AFT libraries) may only look for \ + their properties in the system properties object. This allows those components \ + to be configured from the APP-C configuration. + +LOADING_RESOURCE_BUNDLE=APPC0013I|\ + Loading resource bundle "{0}"|\ + No resolution required|\ + This message indicates that the specified resource bundle is being loaded. + +LOGGING_ALREADY_INITIALIZED=APPC0014W|\ + Logging has already been initialized, check the container logging definitions to ensure \ + they represent your desired logging configuration.|\ + If logging is configured incorrectly, move the definitions to the container or component \ + that first initialized logging. If they are ok, no resolution is required.|\ + This message indicates that the logging environment already exists and has been configured. + +SEARCHING_LOG_CONFIGURATION=APPC0015I|\ + Searching path "{0}" for log configuration file "{1}"|\ + No resolution is required|\ + This message indicates that the APP-C component configuration file specified a logging \ + configuration file and/or search path and the path is being searched. This is used to \ + assist in debugging the configuration process. + +LOADING_DEFAULT_LOG_CONFIGURATION=APPC0016I|\ + Loading default logging configuration from system resource file "{0}"|\ + No resolution is required|\ + A default logging configuration for the component is loaded from system resources to \ + ensure that a valid logging environment exists. This is a normal message, and will \ + be followed by APPC0019I if a user-specified logging configuration overrides the \ + defaults. + +NO_LOG_CONFIGURATION=APPC0017E|\ + No log configuration could be found or defaulted!|\ + A valid logging configuration cannot be found, and no default configuration resource \ + was loaded. This is likely a packaging issue and should be referred to development \ + or level 3 support for assistance.|\ + This is an internal error. + +UNSUPPORTED_LOGGING_FRAMEWORK=APPC0018E|\ + An unsupported logging framework is bound to SLF4J. Only Logback or Log4J are supported.|\ + This is a compatibility error with logging frameworks used in the application environment \ + and should be referred to development or level 3 support for assistance.|\ + This is an internal error. + +LOADING_LOG_CONFIGURATION=APPC0019I|\ + Loading logging configuration from file "{0}"|\ + No resolution is required|\ + The specified logging configuration is being loaded. + +UNKNOWN_PROVIDER=APPC0020E|\ + Provider {0} cannot be found or cannot be resolved to one of the known providers, [{1}].|\ + Specify the name of a valid provider. The IAAS adapter contains a set of providers \ + that are defined. Each of these providers is assigned a logical name. The call \ + to the IAAS adapter must specify the name of the provider that is desired. This \ + could be the result of an incorrect call, or the IAAS adapter configuration is \ + wrong.|\ + The APP-C IAAS adapter is being called to request a service on a specific provider, but \ + the name of the provider cannot be found in the list of defined providers. This may \ + be an error in the directed graph that contains the call to the IAAS adapter, or it \ + may be an error in the request, or the configuration of the IAAS adapter may need \ + to be updated. + +SERVER_STATE_CHANGE_TIMEOUT=APPC0021E|\ + Server name "{0}" with id "{1}" in tenant "{2}" and region "{3}" did not change state \ + within the alloted time. Current state is "{4}" and the desired state(s) are "{5}"|\ + This is likely a provider issue. If the provider is OpenStack, check the virtual \ + machine on the horizon dashboard. If the machine is in an invalid state, you may \ + need to contact Openstack support. The exact mechanisms for recovery of a machine \ + in an invalid state are varied and will be different from provider to provider.|\ + This message indicates that the IAAS adapter has performed some requested action \ + on the specified server (virtual machine) but the server did not enter a valid \ + state (running, stopped, etc) within the timeout period. The last state (current state) \ + is shown, as well as the state that was expected. The servers name, UUID, containing \ + tenant, and region are shown so that the correct provider can be examined. + +SERVER_DELETED=APPC0022E|\ + Server name "{0}" with id "{1}" in tenant "{2}" has a state of deleted and cannot be {3}.|\ + The specified server has been deleted on the provider. This is likely an incorrect \ + request. Make sure that you are specifying the correct server ID/name, provider, \ + and region. If the self-link URL is used, make sure that the correct server resource \ + is specified. If the machine was correct, recreate or rebuild the machine to make \ + it usable. Correct the request.|\ + This message indicates that the server specified was found to have been deleted in the \ + target provider and that the requested action cannot be performed. This may be caused \ + by several things:\ + <ol>\ + <li>The UUID of the server is wrong and specifies a machine that no longer exists</li>\ + <li>The machine was deleted by a different process or request</li>\ + <li>The wrong provider was requested</li>\ + <li>The request was out-of-order</li>\ + </ol> + +UNKNOWN_SERVER_STATE=APPC0023E|\ + Server name "{0}" with id "{1}" in tenant "{2}" has an unknown state of "{3}".|\ + Check the machine to determine the state of the machine. Correct that state to a valid \ + state if possible. This may also be caused by an internal error in the PAL (Provider \ + Abstraction Layer) used by the IAAS if a new state definition has been added to the \ + provider (such as a new version or the installation of an unknown or unsupported \ + extension). If the machine's state is valid, refer this error to development or \ + level 3 support for assistance.|\ + This message indicates that a request was made to the IAAS adapter to take some action \ + on the specified virtual machine, but the machine was found to be in a state that \ + prevents that action from being performed. + +COMPONENT_INITIALIZING=APPC0024I|\ + {0} component {1} is being initialized...|\ + No resolution needed|\ + The IAAS adapter is being initialized + +COMPONENT_INITIALIZED=APPC0025I|\ + {0} component {1} has completed initialization|\ + No resolution needed|\ + The IAAS adapter has been initialized + +COMPONENT_TERMINATING=APPC0026I|\ + {0} component {1} is terminating...|\ + No resolution needed|\ + The IAAS adapter is being terminated + +COMPONENT_TERMINATED=APPC0027I|\ + {0} component {1} has terminated|\ + No resolution needed|\ + The IAAS adapter has been terminated + +IAAS_ADAPTER_UNSUPPORTED_OPERATION=APPC0028E|\ + Operation {0} is not supported or implemented at this time.|\ + Change the request to a supported operation|\ + The IAAS adapter has been requested to perform some operation that it cannot \ + perform at this time. + +IAAS_ADAPTER_RPC_CALLED=APPC0029I|\ + Operation [{0}] called. Input document:\n{1}|\ + No resolution required|\ + The IAAS adapter operation indicated was called with the requested input \ + parameters. + +NO_SERVICE_FOUND=APPC0030E|\ + Unable to locate the [{0}] service in the OSGi container|\ + Ensure that the feature containing that service is installed and running|\ + This indicates that the required feature could not be located + +CONTEXT_PARAMETERS_DISPLAY=APPC0031I|\ + Dump of context parameters for module [{0}], RPC [{1}], and version [{2}]|\ + No resolution required|\ + The specified RPC is being called and the context properties are being \ + displayed. This is a debugging message and preceeds the display of \ + each context property. + +RESPONSE_PARAMETERS_DISPLAY=APPC0032I|\ + Response properties from execution of module [{0}], RPC [{1}], and version [{2}] are:|\ + No resolution required|\ + The service logic directed graph has been executed and returned the response properties. \ + This message preceeds the dump of the response properties. It is used for debugging \ + of service logic and execution problems. + +NULL_OR_INVALID_ARGUMENT=APPC0033E|\ + Service {0}:{1} was provided a null (empty) or invalid argument, [{2}] = [{3}]|\ + This is likely an internal error, refer to support for assistance|\ + The indicated service was called, but the specified parameter or argument was either \ + null or empty, or it was invalid. If it has a value, the value is shown. If the \ + value is null, the value is shown as 'null'. + +PROCESSING_REQUEST=APPC0034I|\ + Service {0}:{1} is processing service [{2}] with request id [{3}]|\ + No resolution required|\ + The indicated application and RPC is processing the specified service request. + +INVALID_SERVICE_REQUEST=APPC0035E|\ + Service {0}:{1} received request for service [{2}] but that service is invalid or unknown.|\ + Correct the service request, likely a directed graph issue|\ + The RPC was invoked to process a service request, but the service is not valid. + +REGISTERING_SERVICE=APPC0036I|\ + {0} registering service {1} using class {2}|\ + No resolution required|\ + The indicated application service is registering itself with the OSGi container using the \ + indicated java class name. + +UNREGISTERING_SERVICE=APPC0037I|\ + {0} unregistering service {1}|\ + No resolution required|\ + The application service is being unregistered from the OSGi container services list. + +LOADING_PROVIDER_DEFINITIONS=APPC0038I|\ + {0} IAAS Adapter initializing provider {1} as {2}|\ + No resolution is required|\ + The IAAS adapter is loading the definition of the specified provider from its \ + configuration file. + +RESTARTING_SERVER=APPC0039I|\ + {0} IAAS Adapter restart of server requested|\ + No resolution required|\ + A graph has invoked the IAAS adapter and has requested the restart of a server. The \ + properties that govern the request are echoed immediately following this message. + +REBUILDING_SERVER=APPC0040I|\ + {0} IAAS Adapter rebuild of server requested|\ + No resolution required|\ + A graph has invoked the IAAS adapter and has requested the rebuilding of a server. The \ + properties that govern the request are echoed immediately following this message. + +INVALID_SELF_LINK_URL=APPC0041E|\ + {0} IAAS Adapter cannot perform requested service, VM url [{1}] is invalid|\ + Correct the call to the adapter with a valid self-link URL|\ + The IAAS adapter has been called to perform some operation on a virtual machine \ + but the vm_id of the virtual machine is not valid. + +SERVER_FOUND=APPC0042I|\ + Located server {0} on tenant [{1}] and in state [{2}]|\ + No resolution required|\ + This message indicates that a service request was made to perform some action on the server \ + and the indicated server was located on the specified tenant.\ + + +STACK_FOUND=APPC0042I|\ + Located stack {0} on tenant [{1}] and in state [{2}]|\ + No resolution required|\ + This message indicates that a service request was made to perform some action on the server \ + and the indicated server was located on the specified tenant. + + + +SERVER_NOT_FOUND=APPC0043E|\ + No server found in provider with self-link URL [{0}]|\ + Correct the server URL|\ + The requested server, identified by its self link URL, could not be found in the provider + +SERVER_OPERATION_EXCEPTION=APPC0044E|\ + Exception {0} was caught attempting {1} of server [{2}] on tenant [{3}]|\ + Contact support for assistance|\ + An exception was caught while trying to perform the indicated operation on the server. The \ + exception may yield more information about the cause of the error. This may be because \ + of access security, or the server is in an invalid state, or any number of reasons. This \ + message should be referred to support for assistance. + + +STACK_NOT_FOUND=APPC0043E|\ + No stack found in provider with self-link URL [{0}]|\ + Correct the server URL|\ + The requested stack, identified by its self link URL, could not be found in the provider + +STACK_OPERATION_EXCEPTION=APPC0044E|\ + Exception {0} was caught attempting {1} of server [{2}] on tenant [{3}]|\ + Contact support for assistance|\ + An exception was caught while trying to perform the indicated operation on the stack. The \ + exception may yield more information about the cause of the error. This may be because \ + of access security, or the stack is in an invalid state, or any number of reasons. This \ + message should be referred to support for assistance. + +MISSING_REQUIRED_PROPERTIES=APPC0045E|\ + One or more properties for [{0}] are missing, null, or empty. They are:|\ + A request to execute the adapter indicated was made from a directed graph, but the properties \ + of the request that are required by the adapter are missing or do not have a value. Correct \ + the directed graph to supply the missing properties.|\ + The specified properties for the indicated adapter operation are invalid or missing. + +SERVER_ERROR_STATE=APPC0046E|\ + The server [{0}] (id={1}) in tenant {2} is in error state, {3} is not allowed|\ + Destroy and recreate the instance|\ + A request to restart or rebuild a server in an error state was received, but those operations \ + are not allowed on a server in this state. OpenStack only allows a deletion of a server \ + that is in the error state. + +IMAGE_NOT_FOUND=APPC0047E|\ + The image {0} could not be located for {1}.|\ + The image indicated could not be found. If the operation being requested is a rebuild of \ + a server, then there is no action that can be taken other than to destroy the server and \ + rebuild it using an image that exists.|\ + This is likely caused by an image being deleted after it was used to build a server. If the \ + request is for a server rebuild, then the image used to create the server was later deleted \ + and no longer exists. The server cannot be rebuilt, because the image doesnt exist. \ + The server must be deleted and reconstructed using a valid, existing image. + +STATE_CHANGE_TIMEOUT=APPC0048E|\ + Time out waiting for {0} with name {1} (and id {2}) to reach one of {3} states, current state is {4}|\ + Recover the resource in whatever means is appropriate|\ + The resource indicated (by name and id) was expected to change it's state (status) to one of the \ + indicated expected states within a specified timeout but the resource did not complete the \ + state change. It's current state is also shown. This can be caused by any number of factors \ + but is normally a problem or conflict within the IaaS provider (OpenStack). + +STATE_CHANGE_EXCEPTION=APPC0049E|\ + Exception {0} waiting for {1} with name {2} (and id {3}) to reach one of {4} states, current state is {5}\n\ + cause={6}|\ + Recover the resource in whatever means is appropriate|\ + The resource indicated (by name and id) was expected to change it's state (status) to one of the \ + indicated expected states within a specified timeout but the resource did not complete the \ + state change. It's current state is also shown. This can be caused by any number of factors \ + but is normally a problem or conflict within the IaaS provider (OpenStack). + +STOP_SERVER=APPC0050I|\ + Server {0} is being stopped...|\ + No recovery required|\ + The processing being performed by APPC requires that the indicated server be stopped. + +START_SERVER=APPC0051I|\ + Server {0} is being started...|\ + No recovery required|\ + The processing being performed by APPC requires that the indicated server be started. + +RESUME_SERVER=APPC0052I|\ + Server {0} is being resumed...|\ + No recovery required|\ + The processing being performed by APPC requires that the indicated server be resumed from a suspended state. + +UNPAUSE_SERVER=APPC0053I|\ + Server {0} is being unpaused...|\ + No recovery required|\ + The processing being performed by APPC requires that the indicated server be unpaused from a paused state. + +CONNECTION_FAILED_RETRY=APPC0054E|\ + Connection to provider {0} at identity {1} using tenant name {2} (id {3}) failed, reason={4}, \ + retrying in {5} seconds, attempt {6} of {7}.|\ + The connection to the provider could not be obtained for the indicated reason. The application \ + controller will retry the attempt to connect to the provider a maximum number of times. The \ + message contains the amount of time the system will wait to retry the connection, and the \ + current attempt and the maximum number of attempts.|\ + Correct the cause of the connection failure as indicated by the reason. + +CONNECTION_FAILED=APPC0055E|\ + Connection to provider {0} at service {1} failed after all retry attempts.|\ + The connection to the named provider at the indicated service URL cannot be opened. All \ + retries have been exhausted. The application controller is giving up on the connection and will \ + fail the request.|\ + Correct the cause of the connection failure as indicated by the reason(s) in previous APPC0054E \ + messages. + +STOPPING_SERVER=APPC0056I|\ + {0} IAAS Adapter stop server requested|\ + No resolution required|\ + A graph has invoked the IAAS adapter and has requested the server to be stopped. The \ + properties that govern the request are echoed immediately following this message. + +REBUILD_SERVER_FAILED=APPC0057E|\ + Server {0} (id {1}) failed to rebuild, reason {2}|\ + The server rebuild failed for the indicated reason. Correct the cause of the failure and \ + rerun, if applicable.|\ + The adapter has attempted to rebuild the indicated server but the rebuild request has \ + been failed by the provider for some reason. The reason returned by the provider is \ + included in the message. + +PARAMETER_IS_MISSING=APPC0058E|\ + Application {0} graph {1} response did not set the {2} parameter. This parameter is \ + required for synchronization with the controller. Absence of this parameter is assumed \ + to be a failure. Please correct the DG.|\ + The indicated directed graph was called from the application controller but when the \ + graph returned the indicated property was not defined in the return parameters. The \ + controller requires that property to be defined and set to a value that is used to \ + inform the controller of the outcome of operations in the graph. Failure to set \ + the required parameter is assumed to be a failure regardless if the graph actually \ + succeeded or not.|\ + Correct the DG to set the specified parameter to a value that is expected and understood \ + by the controller. + +PARAMETER_NOT_NUMERIC=APPC0059E|\ + Application {0} graph {1} did not set parameter {2} to a valid numeric value ({3}). \ + Please correct the DG.|\ + The indicated directed graph was called by the application controller and the graph \ + did set the specified property, however the property is not a valid numeric \ + value. The parameter is used to convey a numeric quantity and the controller \ + cannot convert the value specified to a number. |\ + Correct the DG. + +DG_FAILED_RESPONSE=APPC0060E|\ + Application {0} graph {1} completed with failure: error code = {2}, message = {3}|\ + The directed graph indicated was called by the application controller and when \ + the graph returned, an error code was set indicating that the graph failed. This \ + is a message that echoes the results of the graph, and shows the returned error \ + code and message.|\ + Correct the cause of the error. + +EXCEPTION_CALLING_DG=APPC0061E|\ + Application {0} received exception {1} attempting to call graph {2}, exception \ + message = {3}|\ + The application controller attempted to call the service logic interpreter (SLI) \ + to execute the indicated graph, but an exception was caught. The class of the \ + exception is shown, as is the message associated with the exception. An \ + abbreviated stack trace is also displayed to provide information as to the \ + state of the thread at the time of the exception.|\ + Correct the cause of the exception and rerun. + +GRAPH_NOT_FOUND=APPC0062E|\ + Application {0} was unable to locate graph {1}|\ + The application controller attempted to call the service logic interpreter (SLI) \ + to execute the specified graph but the graph does not exist in the SLI database.|\ + Correct the database and install the correct graph. + +DEBUG_GRAPH_RESPONSE_HEADER=APPC0063D|\ + Application {0} graph {1} responded with {2} properties|\ + This is a debugging message that is output immediately after the call to the \ + directed graph and before any processing is performed to determine the success \ + or failure of that call. The heading is output prior to dumping all the parameters \ + that were returned by the graph.|\ + No recovery action is required. + +DEBUG_GRAPH_RESPONSE_DETAIL=APPC0064D|\ + {0}:{1} - {2} = {3}|\ + This is a debugging message that is output immediately after the call to the \ + directed graph and before any processing is performed to determine the success \ + or failure of that call. This message is repeated for each parameter that \ + exists in the return context from the graph.|\ + No recovery action is required. + +INVALID_REQUIRED_PROPERTY=APPC0065E|\ + Application {0} request "{1}" was supplied a property "{2}" with the value "{3}" \ + that does not meet the required form(s):|\ + This message indicates that the specified requested operation was passed the \ + specific property named and the property value did not meet the expected \ + format requirements. For example, if the property is expected to be a \ + numeric quantity and it contains alphabetic characters, or if it is expected \ + to be a URL and it is not valid. The message also contains a list of one \ + or more regular expressions that were used to validate the input, and which \ + supply the syntax required for the property.|\ + Correct the property and retry. + +MIGRATING_SERVER=APPC066I|\ + {0} IAAS Adapter migrate of server requested|\ + No resolution required|\ + A graph has invoked the IAAS adapter and has requested the migration of a server. The \ + properties that govern the request are echoed immediately following this message. + +EVACUATING_SERVER=APPC0067I|\ + {0} IAAS Adapter evacuate of server requested|\ + No resolution required|\ + A graph has invoked the IAAS adapter and has requested the evacuation of a server. The \ + properties that govern the request are echoed immediately following this message. + +MIGRATE_SERVER_FAILED=APPC0068E|\ + Server {0} (id {1}) failed to migrate during {2} phase, reason {3}|\ + The server migration failed for the indicated reason. Correct the cause of the failure and \ + rerun, if applicable.|\ + The adapter has attempted to migrate the indicated server but the migration request has \ + been failed by the provider for some reason. The reason returned by the provider is \ + included in the message. + +EVACUATE_SERVER_FAILED=APPC0069E|\ + Server {0} (id {1}) failed to evacuate, reason {2}|\ + The server evacuation failed for the indicated reason. Correct the cause of the failure and \ + rerun, if applicable.|\ + The adapter has attempted to evacuate the indicated server but the evacuation request has \ + been failed by the provider for some reason. The reason returned by the provider is \ + included in the message. + +APPC_TOO_BUSY=APPC0080E|\ + APP-C instance is too busy|\ + The APP-C instance handles too many requests and cannot accept new ones as its internal \ + execution queue is full. The problem can appear when the APP-C instance gets more requests \ + than it can handle simultaneously.|\ + Check the server KPIs for possible performance issues (e.g. insufficient memory, \ + high network latency, slow responsiveness of southbound systems and so on) which can affect \ + the system throughput. + +VF_SERVER_BUSY=APPC0081E|\ + Concurrent access to server "{0}"|\ + APP-C currently executes a command on the specified server and cannot accept yet another request \ + for the same one.|\ + Try to resubmit the request at later time. + +VF_ILLEGAL_COMMAND=APPC0082E|\ + Server "{0}" does not support command "{1}" in the current state "{2}"|\ + APP-C cannot perform the requested command on the server in the current state as no state transition \ + is defined for that.|\ + Contact support for assistance. + +VF_UNDEFINED_STATE=APPC0083E|\ + Server "{0}" cannot handle command "{1}" because of its doubtful state|\ + The resource has undefined working state as result of abnormal termination of a previous command.|\ + Recover the resource in whatever means is appropriate. + +APPC_NO_RESOURCE_FOUND=APPC0084E|\ + No resource found with ID "{0}" in A&AI system.|\ + APP-C is unable to resolve the VF details given the instance ID.|\ + Check whether the resource has been deleted (terminated) before. + +APPC_EXPIRED_REQUEST=APPC0085E|\ + The request "{0}" for server "{1}" has exceeded its TTL limit of "{2}" seconds|\ + The received expired event won't be handled by APP-C instance. Normally the problem might be \ + related to asynchronous requests arriving to APP-C instance via DMaaP channel.|\ + Try to submit a new request if still relevant. + +APPC_WORKFLOW_NOT_FOUND=APPC0086E|\ + Workflow for vnfType = "{0}" and command = "{1}" not found.|\ + Unable to retrive Workflow related to mention VNF type and command.|\ + Check provided VNF and Command details are correct. + +APPC_INVALID_INPUT=APPC0087E|\ + Null vnfId and command provided|\ + Request contains Null vnfId and command|\ + Provided non-null VNF and Command details. + +APPC_AUDIT_MSG=APPC0090A|\ + Operation "{0}" for VNF type "{1}" from Source "{2}" with RequestID "{3}" \ + was started at "{4}" and ended at "{5}" with status code "{6}"|\ + Audit detailed msg|\ + Audit detailed msg. + +AAI_CONNECTION_FAILED=APPC0106E|\ + APP-C is unable to communicate with A&AI|\ + Connection to A&AI at service {0} failed after all retry attempts.|\ + The connection to the A&AI at the indicated service URL cannot be opened. \ + All retries have been exhausted. APP-C is giving up on the connection and will?\ + reject the operation request.|\ + . + +AAI_UPDATE_FAILED=APPC0107E|\ + APP-C is unable to update COMPONENT_ID {0} to {1} for reason {2}|\ + The update at the end of the operation wasn't performed as a result of \ + A&AI communication failure or its internal error.|\ + . + +AAI_GET_DATA_FAILED=APPC0108E|\ + APP-C is unable to retrieve VF/VFC {0} data for Transaction ID?{1}?as a \ + result of A&AI communication failure or its internal error.|\ + Operation request will be rejected by APP-C|\ + . + +AAI_CONNECTION_FAILED_RETRY=APPC0105W|\ + A&AI at identity {0} using VNF_ID {1} failed, reason={2}, retrying in {3} seconds, attempt {4} of {5}.|\ + The connection to the A&AI could not be obtained for the indicated reason. APP-C will retry to connect \ + to the A&AI. The?message contains the retry delay, the current attempt and the maximum number of attempts.|\ + Correct the cause of the connection failure as indicated by the reason.? + +AAI_DELETE_FAILED=APPC0114E|\ + APP-C is unable to delete COMPONENT_ID {0} for reason {1}|\ + The deletion at the end of the operation wasn't performed as a result of \ + A&AI communication failure or its internal error.|\ + . + +VNF_CONFIGURED=APPC0118I|\ + VNF {0} is configured|\ + No resolution is required, this is an informational message|\ + The VNF configuration has been completed. + +VNF_CONFIGURATION_STARTED=APPC0116I|\ + VNF {0} is being configured|\ + No resolution is required, this is an informational message|\ + The VNF configuration has been started + +VNF_CONFIGURATION_FAILED=APPC0119E|\ + VNF {0} configuration failed for reason {1}|\ + The configuration operation wasn't performed as a result of VNF communication failure or its internal error.|\ + . + +VNF_TEST_STARTED=APPC0120I|\ + VNF {0} is being tested|\ + No resolution is required, this is an informational message|\ + The VNF test has been started + +VNF_TESTED=APPC0121I|\ + VNF {0} was tested|\ + No resolution is required, this is an informational message|\ + The VNF test has been completed + +VNF_TEST_FAILED=APPC0122E|\ + VNF {0} test failed for reason {1}|\ + The test operation wasn't performed as a result of VNF communication failure or its internal error.|\ + . + +STOP_SERVER_FAILED=APPC0112E|\ + Server {0} (id {1}) failed to stop during {2} phase, reason {3}|\ + The server stop failed for the indicated reason. Correct the cause of the failure and \ + rerun, if applicable.|\ + The adapter has attempted to stop the indicated server but the stop request has \ + been failed by the provider for some reason. The reason returned by the provider is \ + included in the message. + +TERMINATE_SERVER_FAILED=APPC0113E|\ + Server {0} (id {1}) failed to terminate during {2} phase, reason {3}|\ + The server termination failed for the indicated reason. Correct the cause of the failure and \ + rerun, if applicable.|\ + The adapter has attempted to terminate the indicated server but the migration request has \ + been failed by the provider for some reason. The reason returned by the provider is \ + included in the message. + +TERMINATE_STACK_FAILED=APPC0113E|\ + Server {0} (id {1}) failed to terminate during {2} phase, reason {3}|\ + The server termination failed for the indicated reason. Correct the cause of the failure and \ + rerun, if applicable.|\ + The adapter has attempted to terminate the indicated server but the migration request has \ + been failed by the provider for some reason. The reason returned by the provider is \ + included in the message. + +TERMINATING_SERVER=APPC0114I|\ + {0} IAAS Adapter?terminate server requested|\ + No resolution required|\ + A graph has invoked the IAAS adapter and has requested the server to be terminated. The \ + properties that govern the request are echoed immediately following this message. + + +TERMINATING_STACK=APPC0115I|\ + {0} IAAS Adapter?terminate stack requested|\ + No resolution required|\ + A graph has invoked the IAAS adapter and has requested the server to be terminated. The \ + properties that govern the request are echoed immediately following this message. + +TERMINATE_SERVER=APPC0116I|\ + Server {0} is being?terminated...|\ + No recovery required|\ + The processing being performed by APPC requires that the indicated server be terminated. + +TERMINATE_STACK=APPC0117I|\ + Stack {0} is being?terminated...|\ + No recovery required|\ + The processing being performed by APPC requires that the indicated server be terminated. + +MIGRATE_COMPLETE=APPC0118I|\ + Migrate {0} finished with status {1}. Start Time: {2}. End Time: {3}. Request ID: {4}. Reason:{5}...|\ + No resolution is required, this is an informational message|\ + APP-C Migrate Operation has completed. + +RESTART_COMPLETE=APPC0119I|\ + Restart {0} finished with status {1}. Start Time: {2}. End Time: {3}. Request ID: {4}. Reason:{5}...|\ + No resolution is required, this is an informational message|\ + APP-C Restart Operation has completed. + +REBUILD_COMPLETE=APPC0120I|\ + Rebuild {0} finished with status {1}. Start Time: {2}. End Time: {3}. Request ID: {4}. Reason:{5}...|\ + No resolution is required, this is an informational message|\ + APP-C Rebuild Operation has completed. + +CLOSE_CONTEXT_FAILED=APPC0121E|\ + Exception {0} was caught attempting to close provider context for {1}.|\ + Contact support for assistance|\ + An exception was caught while trying to close the provider context. The \ + exception may yield more information about the cause of the error. This may be because \ + of access security, or the server is in an invalid state, or any number of reasons. This \ + message should be referred to support for assistance. + +SNAPSHOTING_STACK=APPC0122I|\ + Stack {0} is being?snapshoted...|\ + No resolution is required|\ + Stack snapshot. + +STACK_SNAPSHOTED==APPC0123I|\ + Stack {0} snapshoted, snapshot ID = [{1}].|\ + No resolution is required|\ + Stack snapshoted successfully. + + +RESTORING_STACK=APPC0124I|\ + Stack {0} is being?restored to snapshot {1}...|\ + No resolution is required|\ + Stack restore. + +STACK_RESTORED=APPC0125I|\ + Stack {0} is restored to snapshot {1}.|\ + No resolution is required|\ + Stack restored successfully. + +MISSING_PARAMETER_IN_REQUEST=APPC0126E|\ + Parameter {0} is missing in svc request of {1}.|\ + Check DG node definition to pass missing parameter's value.|\ + Node definition in DG missing indicated parameter value or value is incorrect, \ + check the graph definition. + +CANNOT_ESTABLISH_CONNECTION=APPC0127E|\ + Cannot establish connection to server {0} port {1} with user {2}.|\ + Check server IP, port and user credentials.|\ + Wrong data sent in request's payload. + + +APPC_METRIC_MSG=APPC0128I|\ + Operation "{0}" for VNF type "{1}" from Source "{2}" with RequestID "{3}" on "{4}" with action "{5}" \ + ended in {6} ms with result "{7}"|\ + No resolution is required, this is an informational message|\ + This message indicates that the APPC logged some operation to metric diff --git a/app-c/appc/appc-common/src/main/resources/org/openecomp/appc/i18n/auth.properties b/app-c/appc/appc-common/src/main/resources/org/openecomp/appc/i18n/auth.properties new file mode 100644 index 000000000..bdb5af244 --- /dev/null +++ b/app-c/appc/appc-common/src/main/resources/org/openecomp/appc/i18n/auth.properties @@ -0,0 +1,23 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +username=admin +password=admin diff --git a/app-c/appc/appc-common/src/test/java/org/openecomp/appc/concurrent/TestSignal.java b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/concurrent/TestSignal.java new file mode 100644 index 000000000..1751b62d9 --- /dev/null +++ b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/concurrent/TestSignal.java @@ -0,0 +1,132 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.concurrent; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.concurrent.TimeoutException; + +import org.junit.Test; +import org.openecomp.appc.concurrent.Signal; + +public class TestSignal { + + private static final DateFormat formatter = new SimpleDateFormat("HH:mm:ss.SSS"); + public static final String SIGNAL_READY = "READY"; + public static final String SIGNAL_SHUTDOWN = "SHUTDOWN"; + + @Test + public void TestSimpleSignal() throws TimeoutException { + + Signal mySignal = new Signal(Thread.currentThread()); + mySignal.setTimeout(5000L); + Fred fred = new Fred(mySignal); + Thread t1 = new Thread(fred); + + /* + * Verify that fred is dead, then start him and wait for him to signal us he is ready to proceed + */ + assertFalse(t1.isAlive()); + t1.start(); + System.out.println(formatter.format(new Date()) + " MAIN: Waiting for Ready..."); + mySignal.waitFor(SIGNAL_READY); + System.out.println(formatter.format(new Date()) + " MAIN: Signal Ready received"); + + /* + * Verify that fred is still alive and we will sleep for a while (simulate doing things) + */ + assertTrue(t1.isAlive()); + try { + Thread.sleep(250L); + } catch (InterruptedException e) { + // ignored + } + + /* + * Verify that fred is still alive and signal him to shutdown + */ + assertTrue(t1.isAlive()); + System.out.println(formatter.format(new Date()) + " MAIN: Signaling shutdown"); + fred.getSignal().signal(SIGNAL_SHUTDOWN); + + /* + * Wait a little bit + */ + try { + Thread.sleep(250L); + } catch (InterruptedException e) { + // ignored + } + + /* + * Verify that fred is dead now and that he completed normally + */ + System.out.println(formatter.format(new Date()) + " MAIN: Shutting down..."); + assertFalse(t1.isAlive()); + assertTrue(fred.isCompleted()); + } + + public class Fred implements Runnable { + private Signal signal; + private Signal parentSignal; + private boolean completed = false; + + public Fred(Signal parentSignal) { + this.parentSignal = parentSignal; + } + + @Override + public void run() { + signal = new Signal(Thread.currentThread()); + signal.setTimeout(5000L); + try { + Thread.sleep(250L); + } catch (InterruptedException e) { + // Ignore + } + + System.out.println(formatter.format(new Date()) + " FRED: Signaling ready..."); + parentSignal.signal(SIGNAL_READY); + + try { + System.out.println(formatter.format(new Date()) + " FRED: Waiting for shutdown..."); + signal.waitFor(SIGNAL_SHUTDOWN); + System.out.println(formatter.format(new Date()) + " FRED: Received shutdown"); + completed = true; + } catch (TimeoutException e) { + e.printStackTrace(); + } + } + + public boolean isCompleted() { + return completed; + } + + public Signal getSignal() { + return signal; + } + } +} diff --git a/app-c/appc/appc-common/src/test/java/org/openecomp/appc/encryption/TestEncryption.java b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/encryption/TestEncryption.java new file mode 100644 index 000000000..e82a44352 --- /dev/null +++ b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/encryption/TestEncryption.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.encryption; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +import org.junit.Test; +import org.openecomp.appc.encryption.EncryptionTool; + +public class TestEncryption { + + @Test + public void testEncryptionDecryption() { + String plain = "AppC"; + String enc = EncryptionTool.getInstance().encrypt(plain); + assertNotEquals(plain, enc); + String dec = EncryptionTool.getInstance().decrypt(enc); + assertNotEquals(enc, dec); + assertEquals(plain, dec); + System.out.println(String.format("%s = [%s]", plain, enc)); + } + +} diff --git a/app-c/appc/appc-common/src/test/java/org/openecomp/appc/pool/CachedElementTest.java b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/pool/CachedElementTest.java new file mode 100644 index 000000000..423d33952 --- /dev/null +++ b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/pool/CachedElementTest.java @@ -0,0 +1,273 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.pool; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.junit.Before; +import org.junit.Test; +import org.openecomp.appc.pool.Allocator; +import org.openecomp.appc.pool.CachedElement; +import org.openecomp.appc.pool.Destructor; +import org.openecomp.appc.pool.Pool; +import org.openecomp.appc.pool.PoolDrainedException; +import org.openecomp.appc.pool.PoolExtensionException; +import org.openecomp.appc.pool.PoolSpecificationException; +import org.openecomp.appc.pool.*; + + +public class CachedElementTest implements Allocator<Testable>, Destructor<Testable> { + private static final int MIN = 10; + private static final int MAX = 100; + private Pool<Testable> pool; + private int index = 0; + private int destroyCount = 0; + + /** + * setup + * + * @throws PoolSpecificationException + * If the minimum size is less than 0, or if the max size is non-zero and less than the min size. + */ + @Before + public void setup() throws PoolSpecificationException { + pool = new Pool<>(MIN, MAX); + } + + /** + * Test state + */ + @Test + public void testAllocator() { + assertNull(pool.getAllocator()); + pool.setAllocator(this); + assertNotNull(pool.getAllocator()); + } + + /** + * Test state + */ + @Test + public void testDestructor() { + assertNull(pool.getDestructor()); + pool.setDestructor(this); + assertNotNull(pool.getDestructor()); + } + + /** + * Test that we can allocate and release elements and that the pool maintains them in MRU order + * + * @throws PoolExtensionException + * If the pool cannot be extended + * @throws PoolDrainedException + * If the caller is trying to reserve an element from a drained pool + */ + @Test + public void testAllocateAndRelease() throws PoolExtensionException, PoolDrainedException { + pool.setAllocator(this); + + assertFalse(pool.isDrained()); + + /* + * Allocate three elements + */ + Testable value1 = pool.reserve(); + assertNotNull(value1); + assertEquals(Integer.valueOf(MIN - 1), Integer.valueOf(value1.getId())); + assertEquals(1, pool.getAllocatedSize()); + assertEquals(MIN - 1, pool.getFreeSize()); + assertEquals(1, pool.getAllocatedSize()); + + Testable value2 = pool.reserve(); + assertNotNull(value2); + assertEquals(Integer.valueOf(MIN - 2), Integer.valueOf(value2.getId())); + assertEquals(2, pool.getAllocatedSize()); + assertEquals(MIN - 2, pool.getFreeSize()); + assertEquals(2, pool.getAllocatedSize()); + + Testable value3 = pool.reserve(); + assertNotNull(value3); + assertEquals(Integer.valueOf(MIN - 3), Integer.valueOf(value3.getId())); + assertEquals(3, pool.getAllocatedSize()); + assertEquals(MIN - 3, pool.getFreeSize()); + assertEquals(3, pool.getAllocatedSize()); + + /* + * Now, release them in the order obtained + */ + pool.release(value1); + pool.release(value2); + pool.release(value3); + + assertEquals(0, pool.getAllocatedSize()); + assertEquals(MIN, pool.getFreeSize()); + + /* + * Now, allocate them again, but their values should be reversed (3, 2, 1) representing the most recently used + * to the least recently used. + */ + value1 = pool.reserve(); + assertNotNull(value1); + assertEquals(Integer.valueOf(MIN - 3), Integer.valueOf(value1.getId())); + + value2 = pool.reserve(); + assertNotNull(value2); + assertEquals(Integer.valueOf(MIN - 2), Integer.valueOf(value2.getId())); + + value3 = pool.reserve(); + assertNotNull(value3); + assertEquals(Integer.valueOf(MIN - 1), Integer.valueOf(value3.getId())); + } + + /** + * Test that we can trim the pool to a desired size + * + * @throws PoolDrainedException + * If the caller is trying to release or reserve an element from a drained pool + * @throws PoolExtensionException + * If the pool cannot be extended + * @throws IllegalAccessException + * if this Method object is enforcing Java language access control and the underlying method is + * inaccessible. + * @throws IllegalArgumentException + * if the method is an instance method and the specified object argument is not an instance of the class + * or interface declaring the underlying method (or of a subclass or implementor thereof); if the number + * of actual and formal parameters differ; if an unwrapping conversion for primitive arguments fails; or + * if, after possible unwrapping, a parameter value cannot be converted to the corresponding formal + * parameter type by a method invocation conversion. + * @throws InvocationTargetException + * if the underlying method throws an exception. + * @throws SecurityException + * If a security manager, s, is present and any of the following conditions is met: + * <ul> + * <li>invocation of s.checkMemberAccess(this, Member.DECLARED) denies access to the declared method</li> + * <li>the caller's class loader is not the same as or an ancestor of the class loader for the current + * class and invocation of s.checkPackageAccess() denies access to the package of this class</li> + * </ul> + * @throws NoSuchMethodException + * if a matching method is not found. + */ + @SuppressWarnings("nls") + @Test + public void testTrim() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, + PoolDrainedException, PoolExtensionException, NoSuchMethodException, SecurityException { + + pool.setAllocator(this); + int SIZE = 50; + Testable[] array = new Testable[SIZE]; + + assertEquals(0, pool.getAllocatedSize()); + for (int i = 0; i < SIZE; i++) { + array[i] = pool.reserve(); + } + assertEquals(SIZE, pool.getAllocatedSize()); + + for (int i = 0; i < SIZE; i++) { + pool.release(array[i]); + } + assertEquals(0, pool.getAllocatedSize()); + + assertEquals(SIZE, pool.getFreeSize()); + + Method trimMethod = Pool.class.getDeclaredMethod("trim", new Class[] { + Integer.TYPE + }); + trimMethod.setAccessible(true); + trimMethod.invoke(pool, new Object[] { + SIZE - MIN + }); + + assertEquals(MIN, pool.getFreeSize()); + } + + /** + * Test that we can drain a pool containing a mix of free and allocated elements + * + * @throws PoolDrainedException + * If the caller is trying to release or reserve an element from a drained pool + * @throws PoolExtensionException + * If the pool cannot be extended + * @throws IOException + * if an I/O error occurs + */ + @Test + public void testDrain() throws PoolExtensionException, PoolDrainedException, IOException { + int SIZE = 50; + int FREE = 20; + int ALLOC = SIZE - FREE; + + Testable[] array = new Testable[SIZE]; + pool.setAllocator(this); + pool.setDestructor(this); + + assertFalse(pool.isDrained()); + + assertEquals(0, pool.getAllocatedSize()); + for (int i = 0; i < SIZE; i++) { + array[i] = pool.reserve(); + } + assertEquals(SIZE, pool.getAllocatedSize()); + + for (int i = 0; i < FREE; i++) { + array[i].close(); + } + assertEquals(ALLOC, pool.getAllocatedSize()); + assertEquals(FREE, pool.getFreeSize()); + + pool.drain(); + assertEquals(0, pool.getFreeSize()); + assertEquals(0, pool.getAllocatedSize()); + assertTrue(pool.isDrained()); + + assertEquals(SIZE, destroyCount); + } + + /** + * @see org.openecomp.appc.pool.Allocator#allocate(org.openecomp.appc.pool.Pool) + */ + @Override + public Testable allocate(Pool<Testable> pool) { + Testable element = new Element(index++); + Testable ce = CachedElement.newInstance(pool, element, new Class[] { + Testable.class + }); + return ce; + } + + /** + * @see org.openecomp.appc.pool.Destructor#destroy(java.io.Closeable, org.openecomp.appc.pool.Pool) + */ + @Override + public void destroy(Testable obj, Pool<Testable> pool) { + destroyCount++; + } +} diff --git a/app-c/appc/appc-common/src/test/java/org/openecomp/appc/pool/Element.java b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/pool/Element.java new file mode 100644 index 000000000..61c302432 --- /dev/null +++ b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/pool/Element.java @@ -0,0 +1,75 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.pool; + +import java.io.IOException; + +public class Element implements Testable { + private boolean closed; + private Integer id; + + public Element(int id) { + this.id = Integer.valueOf(id); + closed = false; + } + + @Override + public boolean equals(Object obj) { + boolean result = false; + if (obj instanceof Element) { + Element other = (Element) obj; + result = this.id.equals(other.id); + } + + return result; + } + + @Override + public int hashCode() { + return id.hashCode(); + } + + /** + * @see java.io.Closeable#close() + */ + @Override + public void close() throws IOException { + closed = true; + } + + @Override + public Boolean isClosed() { + return Boolean.valueOf(closed); + } + + @Override + public String toString() { + return Integer.toString(id); + } + + @Override + public Integer getId() { + return id; + } +} diff --git a/app-c/appc/appc-common/src/test/java/org/openecomp/appc/pool/PoolTest.java b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/pool/PoolTest.java new file mode 100644 index 000000000..97414804c --- /dev/null +++ b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/pool/PoolTest.java @@ -0,0 +1,320 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.pool; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +import org.junit.Before; +import org.junit.Test; +import org.openecomp.appc.pool.Allocator; +import org.openecomp.appc.pool.Destructor; +import org.openecomp.appc.pool.Pool; +import org.openecomp.appc.pool.PoolDrainedException; +import org.openecomp.appc.pool.PoolExtensionException; +import org.openecomp.appc.pool.PoolSpecificationException; +import org.openecomp.appc.pool.*; + + +public class PoolTest implements Allocator<Testable>, Destructor<Testable> { + + private Pool<Testable> pool; + private static final int MIN = 10; + private static final int MAX = 100; + private int index = 0; + private int destroyCount = 0; + + /** + * Set up the test by allocating a pool with MIN-MAX size (bounded pool) + * + * @throws PoolSpecificationException + * If the minimum size is less than 0, or if the max size is non-zero and less than the min size. + */ + @Before + public void setup() throws PoolSpecificationException { + pool = new Pool<>(MIN, MAX); + index = 0; + destroyCount = 0; + } + + /** + * Test that trying to construct a pool with a bad minimum throws an exception + * + * @throws PoolSpecificationException + * If the minimum size is less than 0, or if the max size is non-zero and less than the min size. + */ + @Test(expected = PoolSpecificationException.class) + public void testInvalidMinSize() throws PoolSpecificationException { + pool = new Pool<>(-1, MAX); + } + + /** + * Test that trying to construct a pool with a bad maximum throws an exception + * + * @throws PoolSpecificationException + * If the minimum size is less than 0, or if the max size is non-zero and less than the min size. + */ + @Test(expected = PoolSpecificationException.class) + public void testInvalidMaxSize() throws PoolSpecificationException { + pool = new Pool<>(MIN, -1); + } + + /** + * Test creation of a pool where max is less than min fails + * + * @throws PoolSpecificationException + * If the minimum size is less than 0, or if the max size is non-zero and less than the min size. + */ + @Test(expected = PoolSpecificationException.class) + public void testInvalidSizeRange() throws PoolSpecificationException { + pool = new Pool<>(MAX, MIN); + } + + /** + * Test state + */ + @Test + public void testMinPool() { + assertEquals(MIN, pool.getMinPool()); + } + + /** + * Test state + */ + @Test + public void testMaxPool() { + assertEquals(MAX, pool.getMaxPool()); + } + + /** + * Test state + */ + @Test + public void testAllocator() { + assertNull(pool.getAllocator()); + pool.setAllocator(this); + assertNotNull(pool.getAllocator()); + } + + /** + * Test state + */ + @Test + public void testDestructor() { + assertNull(pool.getDestructor()); + pool.setDestructor(this); + assertNotNull(pool.getDestructor()); + } + + /** + * Test that we can allocate and release elements and that the pool maintains them in MRU order + * + * @throws PoolExtensionException + * If the pool cannot be extended + * @throws PoolDrainedException + * If the caller is trying to reserve an element from a drained pool + */ + @Test + public void testAllocateAndRelease() throws PoolExtensionException, PoolDrainedException { + pool.setAllocator(this); + + assertFalse(pool.isDrained()); + + /* + * Allocate three elements + */ + Testable value1 = pool.reserve(); + assertNotNull(value1); + assertEquals(Integer.valueOf(MIN - 1), value1.getId()); + assertEquals(1, pool.getAllocatedSize()); + assertEquals(MIN - 1, pool.getFreeSize()); + assertEquals(1, pool.getAllocatedSize()); + + Testable value2 = pool.reserve(); + assertNotNull(value2); + assertEquals(Integer.valueOf(MIN - 2), value2.getId()); + assertEquals(2, pool.getAllocatedSize()); + assertEquals(MIN - 2, pool.getFreeSize()); + assertEquals(2, pool.getAllocatedSize()); + + Testable value3 = pool.reserve(); + assertNotNull(value3); + assertEquals(Integer.valueOf(MIN - 3), value3.getId()); + assertEquals(3, pool.getAllocatedSize()); + assertEquals(MIN - 3, pool.getFreeSize()); + assertEquals(3, pool.getAllocatedSize()); + + /* + * Now, release them in the order obtained + */ + pool.release(value1); + pool.release(value2); + pool.release(value3); + + assertEquals(0, pool.getAllocatedSize()); + assertEquals(MIN, pool.getFreeSize()); + + /* + * Now, allocate them again, but their values should be reversed (3, 2, 1) representing the most recently used + * to the least recently used. + */ + value1 = pool.reserve(); + assertNotNull(value1); + assertEquals(Integer.valueOf(MIN - 3), value1.getId()); + + value2 = pool.reserve(); + assertNotNull(value2); + assertEquals(Integer.valueOf(MIN - 2), value2.getId()); + + value3 = pool.reserve(); + assertNotNull(value3); + assertEquals(Integer.valueOf(MIN - 1), value3.getId()); + } + + /** + * Test that we can trim the pool to a desired size + * + * @throws PoolExtensionException + * If the pool cannot be extended + * @throws NoSuchMethodException + * if a matching method is not found. + * @throws SecurityException + * if the request is denied. + * @throws IllegalAccessException + * if this Method object is enforcing Java language access control and the underlying method is + * inaccessible. + * @throws IllegalArgumentException + * if the method is an instance method and the specified object argument is not an instance of the class + * or interface declaring the underlying method (or of a subclass or implementor thereof); if the number + * of actual and formal parameters differ; if an unwrapping conversion for primitive arguments fails; or + * if, after possible unwrapping, a parameter value cannot be converted to the corresponding formal + * parameter type by a method invocation conversion. + * @throws InvocationTargetException + * if the underlying method throws an exception. + * @throws PoolDrainedException + * If the caller is trying to reserve an element from a drained pool + */ + @SuppressWarnings("nls") + @Test + public void testTrim() throws PoolExtensionException, NoSuchMethodException, SecurityException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, PoolDrainedException { + pool.setAllocator(this); + int SIZE = 50; + Proxy[] array = new Proxy[SIZE]; + + assertEquals(0, pool.getAllocatedSize()); + for (int i = 0; i < SIZE; i++) { + array[i] = (Proxy) pool.reserve(); + } + assertEquals(SIZE, pool.getAllocatedSize()); + + for (int i = 0; i < SIZE; i++) { + pool.release((Testable) array[i]); + } + assertEquals(0, pool.getAllocatedSize()); + + assertEquals(SIZE, pool.getFreeSize()); + + Method trimMethod = Pool.class.getDeclaredMethod("trim", new Class[] { + Integer.TYPE + }); + trimMethod.setAccessible(true); + trimMethod.invoke(pool, new Object[] { + SIZE - MIN + }); + + assertEquals(MIN, pool.getFreeSize()); + } + + /** + * Test that we can drain a pool containing a mix of free and allocated elements + * + * @throws PoolExtensionException + * If the pool cannot be extended + * @throws PoolDrainedException + * If the caller is trying to reserve an element from a drained pool + */ + @Test + public void testDrain() throws PoolExtensionException, PoolDrainedException { + int SIZE = 50; + int FREE = 20; + int ALLOC = SIZE - FREE; + + Proxy[] array = new Proxy[SIZE]; + pool.setAllocator(this); + pool.setDestructor(this); + + assertFalse(pool.isDrained()); + + assertEquals(0, pool.getAllocatedSize()); + for (int i = 0; i < SIZE; i++) { + array[i] = (Proxy) pool.reserve(); + } + assertEquals(SIZE, pool.getAllocatedSize()); + + for (int i = 0; i < FREE; i++) { + pool.release((Testable) array[i]); + } + assertEquals(ALLOC, pool.getAllocatedSize()); + assertEquals(FREE, pool.getFreeSize()); + + pool.drain(); + assertEquals(0, pool.getFreeSize()); + assertEquals(0, pool.getAllocatedSize()); + assertTrue(pool.isDrained()); + + assertEquals(SIZE, destroyCount); + } + + /** + * @see org.openecomp.appc.pool.Destructor#destroy(java.io.Closeable, org.openecomp.appc.pool.Pool) + */ + @Override + public void destroy(Testable obj, Pool<Testable> pool) { + destroyCount++; + try { + obj.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * @see org.openecomp.appc.pool.Allocator#allocate(org.openecomp.appc.pool.Pool) + */ + @Override + public Testable allocate(Pool<Testable> pool) { + Testable e = new Element(index++); + + return e; + } +} diff --git a/app-c/appc/appc-common/src/test/java/org/openecomp/appc/pool/Testable.java b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/pool/Testable.java new file mode 100644 index 000000000..61adf91d3 --- /dev/null +++ b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/pool/Testable.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.pool; + +import java.io.Closeable; + +public interface Testable extends Closeable { + + Integer getId(); + + Boolean isClosed(); +} + diff --git a/app-c/appc/appc-common/src/test/java/org/openecomp/appc/util/TestJsonUtil.java b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/util/TestJsonUtil.java new file mode 100644 index 000000000..d78049e12 --- /dev/null +++ b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/util/TestJsonUtil.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.util; + +import org.junit.Assert; +import org.junit.Test; +import org.openecomp.appc.util.JsonUtil; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import static org.junit.Assert.*; + + + +public class TestJsonUtil { + + @Test + public void testConvertJsonStringToFlatMap() { + try { + String jsonString = "{\"A\":\"A-value\",\"B\":{\"C\":\"B.C-value\",\"D\":\"B.D-value\"}}"; + Map<String, String> flatMap = JsonUtil.convertJsonStringToFlatMap(jsonString); + assertNotNull(flatMap); + Map<String, String> expectedMap = new HashMap<>(); + expectedMap.put("A","A-value"); + expectedMap.put("B.C","B.C-value"); + expectedMap.put("B.D","B.D-value"); + assertEquals(expectedMap,flatMap); + } catch (IOException e) { + e.printStackTrace(); + Assert.fail(e.toString()); + } + } + + @Test + public void testConvertJsonStringToFlatMapWithInnerJson() { + try { + String jsonString = "{\"A\":\"A-value\",\"B\":\"{\\\"C\\\":\\\"C-value\\\",\\\"D\\\":\\\"D-value\\\"}\"}"; + Map<String, String> flatMap = JsonUtil.convertJsonStringToFlatMap(jsonString); + assertNotNull(flatMap); + Map<String, String> expectedMap = new HashMap<>(); + expectedMap.put("A","A-value"); + expectedMap.put("B","{\"C\":\"C-value\",\"D\":\"D-value\"}"); + assertEquals(expectedMap,flatMap); + } catch (IOException e) { + e.printStackTrace(); + Assert.fail(e.toString()); + } + } +} diff --git a/app-c/appc/appc-common/src/test/java/org/openecomp/appc/util/TestStreamHelper.java b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/util/TestStreamHelper.java new file mode 100644 index 000000000..d0b93a3c1 --- /dev/null +++ b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/util/TestStreamHelper.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.util; + +import static org.junit.Assert.*; + +import java.io.ByteArrayInputStream; + +import org.junit.Test; +import org.openecomp.appc.util.StreamHelper; + +public class TestStreamHelper { + + private static final String text = "Filler text (also placeholder text or dummy text) is text that shares " + + "some characteristics of a real written text, but is random or otherwise generated. It may be used " + + "to display a sample of fonts, generate text for testing, or to spoof an e-mail spam filter. The " + + "process of using filler text is sometimes called greeking, although the text itself may be nonsense, " + + "or largely Latin, as in Lorem ipsum.\nASDF is the sequence of letters that appear on the first four " + + "keys on the home row of a QWERTY or QWERTZ keyboard. They are often used as a sample or test case " + + "or as random, meaningless nonsense. It is also a common learning tool for keyboard classes, since " + + "all four keys are located on Home row.\nETAOIN SHRDLU is the approximate order of frequency of the " + + "twelve most commonly used letters in the English language, best known as a nonsense phrase that " + + "sometimes appeared in print in the days of \"hot type\" publishing due to a custom of Linotype " + + "machine operators.\nLorem ipsum... is one of the most common filler texts, popular with " + + "typesetters and graphic designers. \"Li Europan lingues...\" is another similar example.\n" + + "Now is the time for all good men to come to the aid of the party\" is a phrase first proposed " + + "as a typing drill by instructor Charles E. Weller; its use is recounted in his book The Early " + + "History of the Typewriter, p. 21 (1918).[1] Frank E. McGurrin, an expert on the early Remington " + + "typewriter, used it in demonstrating his touch typing abilities in January 1889.[2] It has " + + "appeared in a number of typing books, often in the form \"Now is the time for all good men to " + + "come to the aid of their country.\"\nThe quick brown fox jumps over the lazy dog - A coherent, " + + "short phrase that uses every letter of the alphabet. See pangram for more examples.\nNew Petitions" + + " and Building Code - Many B movies of the 1940s, 50s, and 60s utilized the \"spinning newspaper\" " + + "effect to narrate important plot points that occurred offscreen. The effect necessitated the " + + "appearance of a realistic front page, which consisted of a main headline relevant to the plot, " + + "and several smaller headlines used as filler. A large number of these spinning newspapers " + + "included stories titled \"New Petitions Against Tax\" and \"Building Code Under Fire.\" These " + + "phrases have become running jokes among B movie fans, and particularly fans of Mystery " + + "Science Theater 3000. \nCharacter Generator Protocol - The Character Generator Protocol " + + "(CHARGEN) service is an Internet protocol intended for testing, debugging, and measurement " + + "purposes.\n!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefgh\n\"" + + "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghi\n" + + "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghij\n" + + "$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijk\n"; + + @Test + public void testStreamHelperNullStream() { + assertNotNull(StreamHelper.getStringFromInputStream(null)); + assertEquals("", StreamHelper.getStringFromInputStream(null)); + } + + @Test + public void testStreamHelperByteArrayStream() { + ByteArrayInputStream in = new ByteArrayInputStream(text.getBytes()); + + assertEquals(text, StreamHelper.getStringFromInputStream(in)); + } + +} diff --git a/app-c/appc/appc-common/src/test/java/org/openecomp/appc/util/TestStringHelper.java b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/util/TestStringHelper.java new file mode 100644 index 000000000..0afd4cb43 --- /dev/null +++ b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/util/TestStringHelper.java @@ -0,0 +1,104 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + + + +package org.openecomp.appc.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.Properties; + +import org.junit.Test; +import org.openecomp.appc.util.StringHelper; + + +public class TestStringHelper { + + @Test + public void testAsListWithNullList() { + String value = StringHelper.asList((String[]) null); + assertNotNull(value); + assertEquals("[]", value); + } + + @Test + public void testAsListWithEmptyList() { + String value = StringHelper.asList(new String[] {}); + assertNotNull(value); + assertEquals("[]", value); + } + + @Test + public void testAsListWithSingleValue() { + String value = StringHelper.asList("one"); + assertNotNull(value); + assertEquals("[one]", value); + } + + @Test + public void testAsListWithTwoValues() { + String value = StringHelper.asList("one", "two"); + assertNotNull(value); + assertEquals("[one,two]", value); + } + + @Test + public void testAsListWithFiveValues() { + String value = StringHelper.asList("one", "two", "three", "four", "five"); + assertNotNull(value); + assertEquals("[one,two,three,four,five]", value); + } + + @Test + public void testPropertiesToString() { + String key1 = "key1"; + String val1 = "val1"; + String key2 = "key2"; + String val2 = "val2"; + + assertEquals(null, StringHelper.propertiesToString(null)); + + Properties props = new Properties(); + + String result = StringHelper.propertiesToString(props); + assertNotNull(result); + assertEquals("[ ]", result); + + props.setProperty(key1, val1); + result = StringHelper.propertiesToString(props); + assertNotNull(result); + assertTrue(result.contains(key1)); + assertTrue(result.contains(val1)); + assertTrue(result.lastIndexOf(",") < result.length() - 3); // No trailing comma + + props.setProperty(key2, val2); + result = StringHelper.propertiesToString(props); + assertNotNull(result); + assertTrue(result.contains(key1)); + assertTrue(result.contains(val1)); + assertTrue(result.contains(key2)); + assertTrue(result.contains(val2)); + assertTrue(result.lastIndexOf(",") < result.length() - 3); // No trailing comma + } +} diff --git a/app-c/appc/appc-common/src/test/java/org/openecomp/appc/util/TestStructuredPropertyHelper.java b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/util/TestStructuredPropertyHelper.java new file mode 100644 index 000000000..35541277f --- /dev/null +++ b/app-c/appc/appc-common/src/test/java/org/openecomp/appc/util/TestStructuredPropertyHelper.java @@ -0,0 +1,233 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.util; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import org.junit.Before; +import org.junit.Test; +import org.openecomp.appc.util.StructuredPropertyHelper; +import org.openecomp.appc.util.StructuredPropertyHelper.Node; + +/** + * This class is used to test the structured property helper class. + * <p> + * A structured property is one where the name is constructed from a compound set of elements, concatenated by a period, + * and optionally being enumerated using a sequence number suffix. A java package name is an example of a structured + * name, where each element of the name represents a directory or name in the namespace hierarchy. Property names may + * also be structured. This class constructs a graph of the structured properties and this test case is used to verify + * its operation. + * </p> + * + */ +public class TestStructuredPropertyHelper { + + /** + * The properties to be parsed + */ + private Properties properties; + + /** + * The result of parsing the properties + */ + private List<Node> nodes = new ArrayList<>(); + + /** + * Initialize the test environment + */ + @SuppressWarnings("nls") + @Before + public void setup() { + nodes.clear(); + + properties = new Properties(); + + properties.setProperty("provider1.name", "provider1Name"); + properties.setProperty("provider1.type", "provider1type"); + properties.setProperty("provider1.URL", "provider1URL"); + properties.setProperty("provider2.name", "provider2Name"); + properties.setProperty("provider2.type", "provider2type"); + properties.setProperty("provider2.URL", "provider2URL"); + properties.setProperty("provider003.name", "provider3Name"); + properties.setProperty("provider003.type", "provider3type"); + properties.setProperty("provider003.URL", "provider3URL"); + + properties.setProperty("node1.level1.value1.key", "1.1.1"); + properties.setProperty("node1.level1.value2.key", "1.1.2"); + properties.setProperty("node1.level1.value3.key", "1.1.3"); + properties.setProperty("node1.level2.value1.key", "1.2.1"); + properties.setProperty("node1.level2.value2.key", "1.2.2"); + properties.setProperty("node1.level2.value3.key", "1.2.3"); + properties.setProperty("node1.level3.value1.key", "1.3.1"); + properties.setProperty("node1.level3.value2.key", "1.3.2"); + properties.setProperty("node1.level3.value3.key", "1.3.3"); + properties.setProperty("node2.level1.value1.key", "2.1.1"); + properties.setProperty("node2.level1.value2.key", "2.1.2"); + properties.setProperty("node2.level1.value3.key", "2.1.3"); + properties.setProperty("node2.level2.value1.key", "2.2.1"); + properties.setProperty("node2.level2.value2.key", "2.2.2"); + properties.setProperty("node2.level2.value3.key", "2.2.3"); + properties.setProperty("node2.level3.value1.key", "2.3.1"); + properties.setProperty("node2.level3.value2.key", "2.3.2"); + properties.setProperty("node2.level3.value3.key", "2.3.3"); + properties.setProperty("node3.level1.value1.key", "3.1.1"); + properties.setProperty("node3.level1.value2.key", "3.1.2"); + properties.setProperty("node3.level1.value3.key", "3.1.3"); + properties.setProperty("node3.level2.value1.key", "3.2.1"); + properties.setProperty("node3.level2.value2.key", "3.2.2"); + properties.setProperty("node3.level2.value3.key", "3.2.3"); + properties.setProperty("node3.level3.value1.key", "3.3.1"); + properties.setProperty("node3.level3.value2.key", "3.3.2"); + properties.setProperty("node3.level3.value3.key", "3.3.3"); + + properties.setProperty("other.property", "bogus"); + properties.setProperty("yet.another.property", "bogus"); + properties.setProperty("simpleProperty", "bogus"); + + } + + /** + * Test that a simple namespace works + */ + @SuppressWarnings("nls") + @Test + public void testSimpleNamespace() { + nodes = StructuredPropertyHelper.getStructuredProperties(properties, "provider"); + + assertNotNull(nodes); + assertFalse(nodes.isEmpty()); + + assertEquals(3, nodes.size()); + + List<Node> children; + for (Node node : nodes) { + switch (node.getName()) { + case "provider1": + assertNull(node.getValue()); + children = node.getChildren(); + assertNotNull(children); + assertEquals(3, children.size()); + for (Node child : children) { + switch (child.getName()) { + case "URL": + assertEquals("provider1URL", child.getValue()); + break; + case "type": + assertEquals("provider1type", child.getValue()); + break; + case "name": + assertEquals("provider1Name", child.getValue()); + break; + default: + fail("Unknown child of " + node.getName() + " with value " + child.toString()); + } + } + break; + case "provider2": + assertNull(node.getValue()); + children = node.getChildren(); + assertNotNull(children); + assertEquals(3, children.size()); + for (Node child : children) { + switch (child.getName()) { + case "URL": + assertEquals("provider2URL", child.getValue()); + break; + case "type": + assertEquals("provider2type", child.getValue()); + break; + case "name": + assertEquals("provider2Name", child.getValue()); + break; + default: + fail("Unknown child of " + node.getName() + " with value " + child.toString()); + } + } + break; + case "provider3": + /* + * Note that the helper normalizes any ordinal suffixes (003 became 3) + */ + assertNull(node.getValue()); + children = node.getChildren(); + assertNotNull(children); + assertEquals(3, children.size()); + for (Node child : children) { + switch (child.getName()) { + case "URL": + assertEquals("provider3URL", child.getValue()); + break; + case "type": + assertEquals("provider3type", child.getValue()); + break; + case "name": + assertEquals("provider3Name", child.getValue()); + break; + default: + fail("Unknown child of " + node.getName() + " with value " + child.toString()); + } + } + break; + default: + fail("Unknown provider " + node.toString()); + } + } + // System.out.println(nodes); + } + + /** + * Test a multi-dimensional namespace (3X3X3) + */ + @SuppressWarnings("nls") + @Test + public void testMultiLevelNamespace() { + nodes = StructuredPropertyHelper.getStructuredProperties(properties, "node"); + + assertNotNull(nodes); + assertFalse(nodes.isEmpty()); + + assertEquals(3, nodes.size()); + for (Node node : nodes) { + assertNull(node.getValue()); + List<Node> children = node.getChildren(); + assertNotNull(children); + assertEquals(3, children.size()); + for (Node child : children) { + assertNull(child.getValue()); + List<Node> grandChildren = child.getChildren(); + assertNotNull(grandChildren); + assertEquals(3, grandChildren.size()); + for (Node greatGrandChild : grandChildren) { + assertNull(greatGrandChild.getValue()); + List<Node> greatGrandChildren = greatGrandChild.getChildren(); + assertNotNull(greatGrandChildren); + assertEquals(1, greatGrandChildren.size()); + } + } + } + // System.out.println(nodes); + } +} diff --git a/app-c/appc/appc-common/src/test/resources/org/openecomp/appc/i18n/TestAdditionalResources.properties b/app-c/appc/appc-common/src/test/resources/org/openecomp/appc/i18n/TestAdditionalResources.properties new file mode 100644 index 000000000..020ea7d28 --- /dev/null +++ b/app-c/appc/appc-common/src/test/resources/org/openecomp/appc/i18n/TestAdditionalResources.properties @@ -0,0 +1,22 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +ADDITIONAL_RESOURCE=This is a message loaded from an additional resource bundle diff --git a/app-c/appc/appc-common/src/test/resources/org/openecomp/appc/i18n/TestResources_de.properties b/app-c/appc/appc-common/src/test/resources/org/openecomp/appc/i18n/TestResources_de.properties new file mode 100644 index 000000000..01bc87ac6 --- /dev/null +++ b/app-c/appc/appc-common/src/test/resources/org/openecomp/appc/i18n/TestResources_de.properties @@ -0,0 +1,26 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# +# Message bundle for German (language de, no specific country) +# +MESSAGE_TEST=Eine Nachricht f�r Unit-Tests den Ressource-Manager, arg0 = {0}, arg1 = {1}, arg2 = {2} +TEST_001=Dies ist eine Testnachricht ohne Eins�tze bearbeitet werden! diff --git a/app-c/appc/appc-common/src/test/resources/org/openecomp/appc/i18n/TestResources_en_US.properties b/app-c/appc/appc-common/src/test/resources/org/openecomp/appc/i18n/TestResources_en_US.properties new file mode 100644 index 000000000..db9be7b5e --- /dev/null +++ b/app-c/appc/appc-common/src/test/resources/org/openecomp/appc/i18n/TestResources_en_US.properties @@ -0,0 +1,26 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# +# Message bundle for English - United States (en_US). This is also the default bundle if no other bundles are found. +# +MESSAGE_TEST=A message for unit testing the resource manager, arg0={0}, arg1={1}, arg2={2} +TEST_001=This is a test message with no inserts to be edited! diff --git a/app-c/appc/appc-dg-util/.gitignore b/app-c/appc/appc-dg-util/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dg-util/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dg-util/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dg-util/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dg-util/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dg-util/appc-dg-util-bundle/.gitignore b/app-c/appc/appc-dg-util/appc-dg-util-bundle/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-bundle/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dg-util/appc-dg-util-bundle/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dg-util/appc-dg-util-bundle/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-bundle/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dg-util/appc-dg-util-bundle/pom.xml b/app-c/appc/appc-dg-util/appc-dg-util-bundle/pom.xml new file mode 100644 index 000000000..7d8f50df0 --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-bundle/pom.xml @@ -0,0 +1,207 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-util</artifactId> + <version>1.0.0</version> + </parent> + + <artifactId>appc-dg-util-bundle</artifactId> + <packaging>bundle</packaging> + <name>appc-dg-util - bundle</name> + <properties> + <exam.version>4.9.1</exam.version> + <url.version>1.6.0</url.version> + <sal-netconf-connector.version>1.3.1-Beryllium-SR1</sal-netconf-connector.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>javax</groupId> + <artifactId>javaee-api</artifactId> + <version>7.0</version> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.adaptors</groupId> + <artifactId>aai-service-provider</artifactId> + </dependency> + + <dependency> + <groupId>javax.ws.rs</groupId> + <artifactId>javax.ws.rs-api</artifactId> + </dependency> + + <!-- Jersey support needed for OpenStack connector and API version logic --> + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-client</artifactId> + </dependency> + + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-json</artifactId> + </dependency> + + <dependency> + <groupId>javax.xml.bind</groupId> + <artifactId>jaxb-api</artifactId> + <version>2.1</version> + </dependency> + + <dependency> + <groupId>javax.xml</groupId> + <artifactId>jaxp-api</artifactId> + <version>1.4.2</version> + </dependency> + + <!-- Needed to run test cases --> + <dependency> + <groupId>org.glassfish.jersey.core</groupId> + <artifactId>jersey-common</artifactId> + <version>2.9.1</version> + </dependency> + + <dependency> + <groupId>org.codehaus.jackson</groupId> + <artifactId>jackson-jaxrs</artifactId> + <version>1.9.12</version> + </dependency> + + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>4.5.1</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>compile</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>equinoxSDK381</groupId> + <artifactId>org.eclipse.osgi</artifactId> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + </dependency> + + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + <version>5.1.31</version> + <type>jar</type> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>com.vmware</groupId> + <artifactId>vijava</artifactId> + <version>5.1</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>xerces</groupId> + <artifactId>xerces</artifactId> + <version>2.4.0</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore</artifactId> + <version>${apache.httpcomponents.version}</version> + </dependency> + + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>1.2</version> + </dependency> + + <dependency> + <groupId>org.json</groupId> + <artifactId>json</artifactId> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dmaap-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-netconf-adapter-bundle</artifactId> + <!--<version>${project.version}</version>--> + <version>1.0.0</version> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>appc-dg-util</Bundle-SymbolicName> + <Bundle-Activator>org.openecomp.appc.dg.util.AppcDgUtilActivator</Bundle-Activator> + <Export-Package>org.openecomp.appc.dg.util.*</Export-Package> + <Import-Package>org.openecomp.appc.adapter.netconf,org.openecomp.appc.adapter.netconf.dao,org.openecomp.appc.adapter.netconf.util,org.openecomp.appc.adapter.netconf.exception,org.openecomp.appc.adapter.dmaap.*,org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.bind.*,javax.naming.*,com.fasterxml.*,javax.xml.parsers</Import-Package>n + <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/AppcDgUtilActivator.java b/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/AppcDgUtilActivator.java new file mode 100644 index 000000000..50265183f --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/AppcDgUtilActivator.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +/* + * 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.openecomp.appc.dg.util; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class AppcDgUtilActivator implements BundleActivator { + + public void start(BundleContext context) { + System.out.println("Starting the bundle"); + } + + public void stop(BundleContext context) { + System.out.println("Stopping the bundle"); + } + +} diff --git a/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/ExecuteNodeAction.java b/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/ExecuteNodeAction.java new file mode 100644 index 000000000..27f92a4a9 --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/ExecuteNodeAction.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.util; + +import java.util.Map; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + + +public interface ExecuteNodeAction extends SvcLogicJavaPlugin { + void getResource(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + void postResource(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + void deleteResource(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + void getVnfHierarchy(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + void waitMethod(Map<String, String> params, SvcLogicContext ctx) throws APPCException; +} diff --git a/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/InputParameterValidation.java b/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/InputParameterValidation.java new file mode 100644 index 000000000..5d436db9c --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/InputParameterValidation.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.util; + +import java.util.Map; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + + +public interface InputParameterValidation extends SvcLogicJavaPlugin { + + void validateAttribute(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + void validateAttributeLength(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + void validateAttributeCharacter(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + +} diff --git a/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/UpgradeStubNode.java b/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/UpgradeStubNode.java new file mode 100644 index 000000000..6b7cab862 --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/UpgradeStubNode.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.util; + +import java.util.Map; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + + +public interface UpgradeStubNode extends SvcLogicJavaPlugin { + void handleUpgradeStub(Map<String, String> params, SvcLogicContext ctx) throws APPCException; +} diff --git a/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/impl/ExecuteNodeActionImpl.java b/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/impl/ExecuteNodeActionImpl.java new file mode 100644 index 000000000..e2097a0c0 --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/impl/ExecuteNodeActionImpl.java @@ -0,0 +1,293 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.util.impl; + +import org.openecomp.appc.adapter.netconf.util.Constants; +import org.openecomp.appc.dg.util.ExecuteNodeAction; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.i18n.Msg; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicException; +import org.openecomp.sdnc.sli.SvcLogicResource; +import org.openecomp.sdnc.sli.aai.AAIClient; +import org.openecomp.sdnc.sli.aai.AAIService; +import org.openecomp.sdnc.sli.provider.ExecuteNodeExecutor; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + + +public class ExecuteNodeActionImpl implements ExecuteNodeAction { + + private AAIService aaiService; + protected static AAIClient client; + private static final EELFLogger logger = EELFManager.getInstance().getLogger(ExecuteNodeActionImpl.class); + + public ExecuteNodeActionImpl() { + // getAAIservice(); + } + + /** + * initialize the SDNC adapter (AAIService) by building the context. + */ + private void initialize() { + getAAIservice(); + } + + private void getAAIservice() { + BundleContext bctx = FrameworkUtil.getBundle(AAIService.class).getBundleContext(); + // Get AAIadapter reference + ServiceReference sref = bctx.getServiceReference(AAIService.class.getName()); + if (sref != null) { + logger.info("AAIService from bundlecontext"); + aaiService = (AAIService) bctx.getService(sref); + + } else { + logger.info("AAIService error from bundlecontext"); + logger.error(EELFResourceManager.format(Msg.AAI_CONNECTION_FAILED, sref.toString())); + } + } + + /** + * Method called in TestDG to test timeout scenario + * + * @param params waitTime time in millisecond DG is going to sleep + * @param ctx + * @throws APPCException + */ + @Override public void waitMethod(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + try { + String waitTime = params.get("waitTime"); + + logger.info("DG will waits for " + Long.parseLong(waitTime) + "milliseconds"); + Thread.sleep(Long.parseLong(waitTime)); + logger.info("DG waits for " + Long.parseLong(waitTime) + " milliseconds completed"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + @Override public void getResource(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + initialize(); + String resourceType = params.get("resourceType"), ctx_prefix = params.get("prefix"), resourceKey = + params.get("resourceKey"); + if (logger.isDebugEnabled()) { + logger.debug("inside getResorce"); + logger.debug("Retrieving " + resourceType + " details from A&AI for Key : " + resourceKey); + } + client = aaiService; + try { + SvcLogicResource.QueryStatus response = + client.query(resourceType, false, null, resourceKey, ctx_prefix, null, ctx); + logger.info("AAIResponse: " + response.toString()); + ctx.setAttribute("getResource_result", response.toString()); + } catch (SvcLogicException e) { + logger.error(EELFResourceManager.format(Msg.AAI_GET_DATA_FAILED, resourceKey, "", e.getMessage())); + } + if (logger.isDebugEnabled()) { + logger.debug("exiting getResource======"); + } + } + + @Override public void postResource(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + initialize(); + String resourceType = params.get("resourceType"), ctx_prefix = params.get("prefix"), resourceKey = + params.get("resourceKey"), att_name = params.get("attributeName"), att_value = + params.get("attributeValue"); + if (logger.isDebugEnabled()) { + logger.debug("inside postResource"); + logger.debug("Updating " + resourceType + " details in A&AI for Key : " + resourceKey); + logger.debug("Updating " + att_name + " to : " + att_value); + } + Map<String, String> data = new HashMap<String, String>(); + data.put(att_name, att_value); + client = aaiService; + + try { + SvcLogicResource.QueryStatus response = client.update(resourceType, resourceKey, data, ctx_prefix, ctx); + logger.info("AAIResponse: " + response.toString()); + ctx.setAttribute("postResource_result", response.toString()); + } catch (SvcLogicException e) { + logger.error(EELFResourceManager.format(Msg.AAI_UPDATE_FAILED, resourceKey, att_value, e.getMessage())); + } + if (logger.isDebugEnabled()) { + logger.debug("exiting postResource======"); + } + } + + @Override public void deleteResource(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + initialize(); + String resourceType = params.get("resourceType"), resourceKey = params.get("resourceKey"); + + if (logger.isDebugEnabled()) { + logger.debug("inside deleteResource"); + logger.debug("Deleting " + resourceType + " details From A&AI for Key : " + resourceKey); + } + client = aaiService; + try { + SvcLogicResource.QueryStatus response = client.delete(resourceType, resourceKey, ctx); + logger.info("AAIResponse: " + response.toString()); + ctx.setAttribute("deleteResource_result", response.toString()); + } catch (SvcLogicException e) { + logger.error(EELFResourceManager.format(Msg.AAI_DELETE_FAILED, resourceKey, e.getMessage())); + } + if (logger.isDebugEnabled()) { + logger.debug("exiting deleteResource======"); + } + } + + @Override public void getVnfHierarchy(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + if (logger.isDebugEnabled()) { + logger.debug("Inside getVnfHierarchy======"); + } + //String ctx_prefix = params.get("prefix"); + String resourceKey = params.get("resourceKey"); + String retrivalVnfKey = "vnf-id = '" + resourceKey + "' AND relationship-key = 'vserver.vserver-id'"; + Map<String, String> paramsVnf = new HashMap<String, String>(); + paramsVnf.put("resourceType", "generic-vnf:relationship-list"); + paramsVnf.put("prefix", "vnfRetrived"); + paramsVnf.put("resourceKey", retrivalVnfKey); + logger.debug("Retrieving VNF details from A&AI"); + //Retrive all the relations of VNF + getResource(paramsVnf, ctx); + if (ctx.getAttribute("getResource_result").equals("SUCCESS")) { + if (ctx.getAttribute("vnfRetrived.heat-stack-id") != null) { + ctx.setAttribute("VNF.heat-stack-id", ctx.getAttribute("vnfRetrived.heat-stack-id")); + } + Map<String, String> vnfHierarchyMap = new ConcurrentHashMap<String, String>(); + int vmCount = 0; + logger.debug("Parsing Vserver details from VNF relations"); + for (String ctxKeySet : ctx + .getAttributeKeySet()) { //loop through relationship-list data, to get vserver relations + if (ctxKeySet.startsWith("vnfRetrived.") && ctx.getAttribute(ctxKeySet).equalsIgnoreCase("vserver")) { + String vmKey = ctxKeySet.substring(0, ctxKeySet.length() - "related-to".length()); + String vserverID = null; + String tenantID = null; + int relationshipLength = 0; + if (ctx.getAttributeKeySet().contains(vmKey + "relationship-data_length")) { + relationshipLength = Integer.parseInt(ctx.getAttribute(vmKey + "relationship-data_length")); + } + + for (int j = 0; j + < relationshipLength; j++) { //loop inside relationship data, to get vserver-id and tenant-id + String key = ctx.getAttribute(vmKey + "relationship-data[" + j + "].relationship-key"); + String value = ctx.getAttribute(vmKey + "relationship-data[" + j + "].relationship-value"); + vnfHierarchyMap.put("VNF.VM[" + vmCount + "]." + key, value); + if ("vserver.vserver-id".equals(key)) { + vserverID = value; + } + if ("tenant.tenant-id".equals(key)) { + tenantID = value; + } + } + int relatedPropertyLength = 0; + if (ctx.getAttributeKeySet().contains(vmKey + "related-to-property_length")) { + relatedPropertyLength = + Integer.parseInt(ctx.getAttribute(vmKey + "related-to-property_length")); + } + for (int j = 0; + j < relatedPropertyLength; j++) { //loop inside related-to-property data, to get vserver-name + String key = ctx.getAttribute(vmKey + "related-to-property[" + j + "].property-key"); + String value = ctx.getAttribute(vmKey + "related-to-property[" + j + "].property-value"); + vnfHierarchyMap.put("VNF.VM[" + vmCount + "]." + key, value); + } + //Retrive VM relations to find vnfc's + //VM to VNFC is 1 to 1 relation + String vmRetrivalKey = "vserver-id = '" + vserverID + "' AND tenant_id = '" + tenantID + "'"; + Map<String, String> paramsVm = new HashMap<String, String>(); + paramsVm.put("resourceType", "vserver:relationship-list"); + paramsVm.put("prefix", "vmRetrived"); + paramsVm.put("resourceKey", vmRetrivalKey); + SvcLogicContext vmCtx = new SvcLogicContext(); + + logger.debug("Retrieving VM details from A&AI"); + getResource(paramsVm, vmCtx); + if (vmCtx.getAttribute("getResource_result").equals("SUCCESS")) { + if (logger.isDebugEnabled()) { + logger.debug("Parsing VNFC details from VM relations"); + } + vnfHierarchyMap.put("VNF.VM[" + vmCount + "].URL", + vmCtx.getAttribute("vmRetrived.vserver-selflink")); + for (String ctxVnfcKeySet : vmCtx + .getAttributeKeySet()) { //loop through relationship-list data, to get vnfc relations + if (ctxVnfcKeySet.startsWith("vmRetrived.") && vmCtx.getAttribute(ctxVnfcKeySet) + .equalsIgnoreCase("vnfc")) { + String vnfcKey = ctxVnfcKeySet.substring(0, + ctxVnfcKeySet.length() - "related-to".length()); + relationshipLength = 0; + if (vmCtx.getAttributeKeySet().contains(vnfcKey + "relationship-data_length")) { + relationshipLength = Integer.parseInt( + vmCtx.getAttribute(vnfcKey + "relationship-data_length")); + } + for (int j = 0; j + < relationshipLength; j++) { //loop through relationship data, to get vnfc name + String key = vmCtx.getAttribute( + vnfcKey + "relationship-data[" + j + "].relationship-key"); + String value = vmCtx.getAttribute( + vnfcKey + "relationship-data[" + j + "].relationship-value"); + if (key.equalsIgnoreCase("vnfc.vnfc-name")) { + vnfHierarchyMap.put("VNF.VM[" + vmCount + "].VNFC", value); + break; //VM to VNFC is 1 to 1 relation, once we got the VNFC name we can break the loop + } + } + } + } + } else { + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, "Error Retrieving VNFC hierarchy"); + vnfHierarchyMap.put("getVnfHierarchy_result", "FAILURE"); + logger.error("Failed in getVnfHierarchy, Error retrieving Vserver details. Error message: " + + vmCtx.getAttribute("getResource_result")); + logger.warn("Incorrect or Incomplete VNF Hierarchy"); + throw new APPCException("Error Retrieving VNFC hierarchy"); + } + vmCount++; + } + } + vnfHierarchyMap.put("VNF.VMCount", vmCount + ""); + if (vmCount == 0) { + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, "VM count is 0"); + } + ctx.setAttribute("getVnfHierarchy_result", "SUCCESS"); + //Finally set all attributes to ctx + for (String attribute : vnfHierarchyMap.keySet()) { + ctx.setAttribute(attribute, vnfHierarchyMap.get(attribute)); + } + } else { + ctx.setAttribute("getVnfHierarchy_result", "FAILURE"); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, "Error Retrieving VNFC hierarchy"); + logger.error("Failed in getVnfHierarchy, Error retrieving VNF details. Error message: " + ctx + .getAttribute("getResource_result")); + logger.warn("Incorrect or Incomplete VNF Hierarchy"); + throw new APPCException("Error Retrieving VNFC hierarchy"); + } + if (logger.isDebugEnabled()) { + logger.debug("exiting getVnfHierarchy======"); + } + } +} diff --git a/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/impl/InputParameterValidationImpl.java b/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/impl/InputParameterValidationImpl.java new file mode 100644 index 000000000..aec1ac220 --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/impl/InputParameterValidationImpl.java @@ -0,0 +1,133 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.util.impl; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +import org.openecomp.appc.dg.util.InputParameterValidation; +import org.openecomp.appc.exceptions.APPCException; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.SvcLogicContext; + + + +public class InputParameterValidationImpl implements InputParameterValidation +{ + private static final char NL = '\n'; + private static final EELFLogger logger = EELFManager.getInstance().getLogger(InputParameterValidationImpl.class); + + public InputParameterValidationImpl() { + } + + + @SuppressWarnings("nls") + @Override + public void validateAttribute(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + Map<String, String> contextParams=getValueFromContext(ctx); + boolean isSuccess = true; + try { + for (String k : params.keySet()) { + logger.info("validating attribute " + k); + if (!contextParams.containsKey(k)) { + logger.info("missing attribute " + k); + isSuccess =false; + } + if(contextParams.get(k)==null){ + logger.info("mandatory attribute " + k+ "is null"); + isSuccess =false; + } + } + }catch (NullPointerException np) { + isSuccess =false; + } + ctx.setAttribute("validateAttribute", String.valueOf(isSuccess)); + } + + @SuppressWarnings("nls") + @Override + public void validateAttributeLength(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + Map<String, String> contextParams=getValueFromContext(ctx); + boolean isSuccess =true; + try { + int maxLength = Integer.parseInt(params.get("maximum_length_param")); + params.remove("maximum_length_param"); + + for (String k : params.keySet()) { + logger.info("validating attribute " + k); + if(contextParams.get(k).length() > maxLength){ + logger.info("attribute " + k+ "'s length is exceeding Maximum limit of " + maxLength +" character"); + isSuccess=false; + } + } + }catch (NullPointerException np) { + isSuccess=false; + } + ctx.setAttribute("validateAttributeLength", String.valueOf(isSuccess)); + } + + @SuppressWarnings("nls") + @Override + public void validateAttributeCharacter(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + Map<String, String> contextParams=getValueFromContext(ctx); + boolean isSuccess =true; + try { + String specialCharacter = params.get("special_characters"); + String pattern = ".*[" + Pattern.quote(specialCharacter) + "].*"; + params.remove("special_characters"); + + for (String k : params.keySet()) { + logger.info("validating attribute " + k); + if(contextParams.get(k).matches(pattern)){ + logger.info("attribute " + k + " contains any of these " + specialCharacter + " special character "); + isSuccess =false; + } + + } + }catch (NullPointerException np) { + isSuccess =false; + } + ctx.setAttribute("validateAttributeCharacter", String.valueOf(isSuccess)); + } + + + private Map getValueFromContext(SvcLogicContext context) { + Set<String> keys = context.getAttributeKeySet(); + Map<String, String> params = new HashMap<String, String>(); + StringBuilder builder = new StringBuilder(); + if (keys != null && !keys.isEmpty()) { + builder.append(NL); + for (String key : keys) { + String value = context.getAttribute(key); + params.put(key,value); + + } + } + return params; + + } + + +} diff --git a/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/impl/UpgradeStubNodeImpl.java b/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/impl/UpgradeStubNodeImpl.java new file mode 100644 index 000000000..39f86ae6f --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/impl/UpgradeStubNodeImpl.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.util.impl; + +import java.util.Map; + +import org.openecomp.appc.dg.util.UpgradeStubNode; +import org.openecomp.appc.exceptions.APPCException; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.SvcLogicContext; + + +public class UpgradeStubNodeImpl implements UpgradeStubNode { + + public static final String FAILURE_INDICATOR_FIELD_NAME = "failureIndicator"; + private static final EELFLogger logger = EELFManager.getInstance().getLogger(UpgradeStubNodeImpl.class); + + @Override + public void handleUpgradeStub(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + logger.debug("Entering in handleUpgradeStub : "+ params.toString()); + String failureInd = params.get(FAILURE_INDICATOR_FIELD_NAME); + if (null != failureInd && Boolean.valueOf(failureInd)){ + throw new APPCException("Simulating exception..."); + } + logger.info("Simulating was successful"); + } +} diff --git a/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..547b8cdfb --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- + Starter Blueprint Camel Definition appc-aai-adapter-blueprint +--> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + + <bean id="inputParameterValidationBean" class="org.openecomp.appc.dg.util.impl.InputParameterValidationImpl" scope="prototype" > + </bean> + + <service id="inputParameterValidationService" interface="org.openecomp.appc.dg.util.InputParameterValidation" ref="inputParameterValidationBean"/> + + <bean id="executeNodeActionBean" class="org.openecomp.appc.dg.util.impl.ExecuteNodeActionImpl" scope="prototype" > + </bean> + + <service id="executeNodeActionService" interface="org.openecomp.appc.dg.util.ExecuteNodeAction" ref="executeNodeActionBean"/> + + <!--bean id="DCAEReporterPlugin" class="org.openecomp.appc.dg.util.impl.DCAEReporterPluginImpl" scope="prototype" > + <property name="eventSender" ref="eventSenderServiceRef"/> + </bean--> + + <!--reference interface="org.openecomp.appc.adapter.dmaap.EventSender" id="eventSenderServiceRef"/--> + <!--service id = "DCAEReporterPluginService" interface="org.openecomp.appc.dg.util.DCAEReporterPlugin" ref="DCAEReporterPlugin"/--> + + <!--bean id="NetconfClientPlugin" class="org.openecomp.appc.dg.util.impl.NetconfClientPluginImpl" scope="prototype" ></bean--> + <!--service id = "NetconfClientService" interface="org.openecomp.appc.dg.util.NetconfClientPlugin" ref="NetconfClientPlugin"/--> + + <!--bean id="NetconfDBPlugin" class="org.openecomp.appc.dg.util.impl.NetconfDBPluginImpl" scope="prototype" ></bean--> + <!--service id = "NetconfDBService" interface="org.openecomp.appc.dg.util.NetconfDBPlugin" ref="NetconfDBPlugin"/--> + + <bean id="upgradeNode" class="org.openecomp.appc.dg.util.impl.UpgradeStubNodeImpl" scope="prototype"/> + <service id = "upgradeNodeService" interface="org.openecomp.appc.dg.util.UpgradeStubNode" ref="upgradeNode"/> + +</blueprint> diff --git a/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..4c11b73c7 --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-bundle/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,26 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. +# diff --git a/app-c/appc/appc-dg-util/appc-dg-util-features/.gitignore b/app-c/appc/appc-dg-util/appc-dg-util-features/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-features/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dg-util/appc-dg-util-features/pom.xml b/app-c/appc/appc-dg-util/appc-dg-util-features/pom.xml new file mode 100644 index 000000000..2c2b6c766 --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-features/pom.xml @@ -0,0 +1,124 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-dg-util</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <name>appc-dg-util-features</name> + <artifactId>appc-dg-util-features</artifactId> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-util-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>features-mdsal</artifactId> + <classifier>features</classifier> + <type>xml</type> + + <scope>runtime</scope> + </dependency> + + + + <!-- dependency for opendaylight-karaf-empty for use by testing --> +<!-- <dependency> --> +<!-- <groupId>org.opendaylight.controller</groupId> --> +<!-- <artifactId>opendaylight-karaf-empty</artifactId> --> +<!-- <type>zip</type> --> +<!-- </dependency> --> + + + + + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>features-yangtools</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <plugin> + <!-- launches the feature test, which validates that your karaf feature + can be installed inside of a karaf container. It doesn't validate that your + functionality works correctly, just that you have all of the dependent bundles + defined correctly. --> + <!-- Skipping ODL feature test --> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <systemPropertyVariables> + <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId> + <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId> + <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version> + </systemPropertyVariables> + <dependenciesToScan> + <dependency>org.opendaylight.yangtools:features-test</dependency> + </dependenciesToScan> + <classpathDependencyExcludes> + <!-- The dependencies which bring in AbstractDataBrokerTest class + brings in a second PaxExam container which results in the feature tests failing + with a message similar to: "ERROR o.ops4j.pax.exam.spi.PaxExamRuntime - Ambiguous + TestContainer ..." This excludes the container we don't want to use. --> + <classpathDependencyExcludes>org.ops4j.pax.exam:pax-exam-container-native</classpathDependencyExcludes> + </classpathDependencyExcludes> + <skipTests>true</skipTests> + </configuration> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dg-util/appc-dg-util-features/src/main/resources/features.xml b/app-c/appc/appc-dg-util/appc-dg-util-features/src/main/resources/features.xml new file mode 100644 index 000000000..9bcfbd0ac --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-features/src/main/resources/features.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="appc-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + + <repository>mvn:org.opendaylight.mdsal/features-mdsal/${features-mdsal.version}/xml/features</repository> + + <feature name='appc-dg-util' description="application DG utillity" version='${project.version}'> + <!--<feature version="${project.version}">appc-aai-adapter</feature>--> + <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> + <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> + <bundle>mvn:org.openecomp.appc/appc-dg-util-bundle/${project.version}</bundle> + </feature> + +</features> diff --git a/app-c/appc/appc-dg-util/appc-dg-util-installer/.gitignore b/app-c/appc/appc-dg-util/appc-dg-util-installer/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-installer/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dg-util/appc-dg-util-installer/pom.xml b/app-c/appc/appc-dg-util/appc-dg-util-installer/pom.xml new file mode 100644 index 000000000..a1abe59fa --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-installer/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-dg-util</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>appc-dg-util-installer</artifactId> + <name>APPC DG Util - Karaf Installer</name> + <packaging>pom</packaging> + + <properties> + <application.name>appc-dg-util</application.name> + <features.boot>appc-dg-util</features.boot> + <features.repositories>mvn:org.openecomp.appc/appc-dg-util-features/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-util-features</artifactId> + <version>${project.version}</version> + <classifier>features</classifier> + <type>xml</type> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-util-bundle</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>false</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>true</attach> + <finalName>${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <excludeGroupIds>org.opendaylight</excludeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals> + <!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-dg-util/appc-dg-util-installer/src/assembly/assemble_installer_zip.xml b/app-c/appc/appc-dg-util/appc-dg-util-installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..8948a3302 --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>controller</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/app-c/appc/appc-dg-util/appc-dg-util-installer/src/assembly/assemble_mvnrepo_zip.xml b/app-c/appc/appc-dg-util/appc-dg-util-installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..a18efd00b --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,47 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>controller</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + +</assembly> diff --git a/app-c/appc/appc-dg-util/appc-dg-util-installer/src/main/resources/scripts/install-feature.sh b/app-c/appc/appc-dg-util/appc-dg-util-installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..1d769fada --- /dev/null +++ b/app-c/appc/appc-dg-util/appc-dg-util-installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,40 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +#!/bin/bash + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -n -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot} diff --git a/app-c/appc/appc-dg-util/pom.xml b/app-c/appc/appc-dg-util/pom.xml new file mode 100644 index 000000000..b6329cc8d --- /dev/null +++ b/app-c/appc/appc-dg-util/pom.xml @@ -0,0 +1,23 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-dg-util</artifactId> + <packaging>pom</packaging> + <name>APPC DG util</name> + <!--<version>1.1.16-SNAPSHOT</version>--> + <description>APPC DG Utility</description> + + <!-- ================================================================================== --> + <!-- The modules we build --> + <!-- ================================================================================== --> + <modules> + <module>appc-dg-util-bundle</module> + <module>appc-dg-util-features</module> + <module>appc-dg-util-installer</module> + </modules> + +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-dg/.gitignore b/app-c/appc/appc-dg/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dg/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dg/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dg/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dg/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dg/appc-dg-shared/.gitignore b/app-c/appc/appc-dg/appc-dg-shared/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dg/appc-dg-shared/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dg/appc-dg-shared/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dg/appc-dg-shared/README.txt b/app-c/appc/appc-dg/appc-dg-shared/README.txt new file mode 100644 index 000000000..960d51885 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/README.txt @@ -0,0 +1 @@ +This project contains set of DG-ready reusable APP-C utility classes, such as utility for executing a command on remote machine via SSH and more.
\ No newline at end of file diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/.gitignore b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/pom.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/pom.xml new file mode 100644 index 000000000..a1bdfbfcd --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/pom.xml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-shared</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-dg-aai</artifactId> + <packaging>bundle</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-common</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.adaptors</groupId> + <artifactId>aai-service-provider</artifactId> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-mockito</artifactId> + <version>1.6.2</version> + <scope>test</scope> + + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-junit4</artifactId> + <version>1.6.2</version> + <scope>test</scope> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>appc-dg-aai</Bundle-SymbolicName> + <Export-Package>org.openecomp.appc.dg.aai</Export-Package> + <Private-Package>org.openecomp.appc.dg.aai.impl.*</Private-Package> + <Import-Package> + !org.apache.log,!org.apache.commons.logging,!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.jasypt.*,* + </Import-Package> + <Embed-Dependency> + appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false + </Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/AAIPlugin.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/AAIPlugin.java new file mode 100644 index 000000000..e220182f2 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/AAIPlugin.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.aai; + +import java.util.Map; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + + +public interface AAIPlugin extends SvcLogicJavaPlugin { + void postGenericVnfData(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + void getGenericVnfData(Map<String, String> params, SvcLogicContext ctx) throws APPCException; +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/impl/AAIPluginImpl.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/impl/AAIPluginImpl.java new file mode 100644 index 000000000..6eae559e8 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/impl/AAIPluginImpl.java @@ -0,0 +1,122 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.aai.impl; + +import org.openecomp.appc.dg.aai.AAIPlugin; +import org.openecomp.appc.dg.aai.impl.Constants; +import org.openecomp.appc.exceptions.APPCException; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicException; +import org.openecomp.sdnc.sli.SvcLogicResource; +import org.openecomp.sdnc.sli.aai.AAIClient; +import org.openecomp.sdnc.sli.aai.AAIService; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +import java.util.HashMap; +import java.util.Map; + + +public class AAIPluginImpl implements AAIPlugin { + private AAIClient aaiClient; + private static final EELFLogger logger = EELFManager.getInstance().getLogger(AAIPluginImpl.class); + + public AAIPluginImpl() { + BundleContext bctx = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); + ServiceReference sref = bctx.getServiceReference(AAIService.class); + aaiClient = (AAIClient) bctx.getService(sref); + } + + @Override + public void postGenericVnfData(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + String vnf_id = ctx.getAttribute(Constants.VNF_ID_PARAM_NAME); + String prefix = ctx.getAttribute(Constants.AAI_PREFIX_PARAM_NAME); + + String key = "vnf-id = '" + vnf_id + "'"; + + Map<String, String> data = new HashMap<>(); + for (Map.Entry<String, String> entry : params.entrySet()) { + String paramKey = entry.getKey(); + int pos = paramKey.indexOf(Constants.AAI_INPUT_DATA); + if (pos == 0) { + data.put(paramKey.substring(Constants.AAI_INPUT_DATA.length()+1), entry.getValue()); + } + } + + try { + SvcLogicResource.QueryStatus response = aaiClient.update("generic-vnf", key, data, prefix, ctx); + if (SvcLogicResource.QueryStatus.NOT_FOUND.equals(response)) { + String errorMessage = String.format("VNF not found for vnf_id = %s", vnf_id); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, errorMessage); + throw new APPCException(errorMessage); + } + logger.info("AAIResponse: " + response.toString()); + if (SvcLogicResource.QueryStatus.FAILURE.equals(response)) { + String errorMessage = String.format("Error Querying AAI with vnfID = %s", vnf_id); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, errorMessage); + throw new APPCException(errorMessage); + } + } catch (SvcLogicException e) { + String errorMessage = String.format("Error in postVnfdata %s", e); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, errorMessage); + logger.error(errorMessage); + throw new APPCException(e); + } + } + + @Override + public void getGenericVnfData(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + String vnf_id = ctx.getAttribute(Constants.VNF_ID_PARAM_NAME); + String prefix = ctx.getAttribute(Constants.AAI_PREFIX_PARAM_NAME); + + String key = "vnf-id = '" + vnf_id + "'"; + try { + SvcLogicResource.QueryStatus response = aaiClient.query("generic-vnf", false, null, key, prefix, null, ctx); + if (SvcLogicResource.QueryStatus.NOT_FOUND.equals(response)) { + String errorMessage = String.format("VNF not found for vnf_id = %s", vnf_id); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, errorMessage); + throw new APPCException(errorMessage); + } else if (SvcLogicResource.QueryStatus.FAILURE.equals(response)) { + String errorMessage = String.format("Error Querying AAI with vnfID = %s", vnf_id); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, errorMessage); + throw new APPCException(errorMessage); + } + String aaiEntitlementPoolUuid = ctx.getAttribute(Constants.AAI_ENTITLMENT_POOL_UUID_NAME); + if (null == aaiEntitlementPoolUuid) aaiEntitlementPoolUuid = ""; + String aaiLicenseKeyGroupUuid = ctx.getAttribute(Constants.AAI_LICENSE_KEY_UUID_NAME); + if (null == aaiLicenseKeyGroupUuid) aaiLicenseKeyGroupUuid = ""; + + ctx.setAttribute(Constants.IS_RELEASE_ENTITLEMENT_REQUIRE, Boolean.toString(!aaiEntitlementPoolUuid.isEmpty())); + ctx.setAttribute(Constants.IS_RELEASE_LICENSE_REQUIRE, Boolean.toString(!aaiLicenseKeyGroupUuid.isEmpty())); + + logger.info("AAIResponse: " + response.toString()); + } catch (SvcLogicException e) { + String errorMessage = String.format("Error in getVnfdata %s", e); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, errorMessage); + logger.error(errorMessage); + throw new APPCException(e); + } + } +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/impl/Constants.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/impl/Constants.java new file mode 100644 index 000000000..3feab4795 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/impl/Constants.java @@ -0,0 +1,112 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.aai.impl; + + +public class Constants { + public final static String VNF_ID_PARAM_NAME = "aai.vnfID"; + public static final String AAI_PREFIX_PARAM_NAME = "aai.prefix"; + public static final String AAI_INPUT_DATA = "aai.input.data"; + public static final String AAI_ERROR_MESSAGE = "org.openecomp.appc.dg.error"; + + public static final String CONFIGURE_PATH = "/restconf/config/opendaylight-inventory:nodes/node/"; + public static final String CONNECT_PATH = "/restconf/config/opendaylight-inventory:nodes/node/controller-config/yang-ext:mount/config:modules"; + public static final String CHECK_CONNECTION_PATH = "/restconf/operational/opendaylight-inventory:nodes/node/"; + public static final String DISCONNECT_PATH = "/restconf/config/opendaylight-inventory:nodes/node/controller-config/yang-ext:mount/config:modules/module/odl-sal-netconf-connector-cfg:sal-netconf-connector/"; + + public static final String CONTROLLER_IP = "127.0.0.1"; + public static final int CONTROLLER_PORT = 8181; + public static final String PROTOCOL = "http"; + + public static final String VF_LICENSE = "VF_LICENSE"; + + // tables and fields + public static final String NETCONF_SCHEMA = "sdnctl"; + public static final String SDNCTL_SCHEMA = "sdnctl"; + public static final String DEVICE_AUTHENTICATION_TABLE_NAME = "DEVICE_AUTHENTICATION"; + public static final String CONFIGFILES_TABLE_NAME = "CONFIGFILES"; + public static final String DEVICE_INTERFACE_LOG_TABLE_NAME = "DEVICE_INTERFACE_LOG"; + public static final String FILE_CONTENT_TABLE_FIELD_NAME = "FILE_CONTENT"; + public static final String FILE_NAME_TABLE_FIELD_NAME = "FILE_NAME"; + public static final String USER_NAME_TABLE_FIELD_NAME = "USER_NAME"; + public static final String PASSWORD_TABLE_FIELD_NAME = "PASSWORD"; + public static final String PORT_NUMBER_TABLE_FIELD_NAME = "PORT_NUMBER"; + public static final String VNF_TYPE_TABLE_FIELD_NAME = "VNF_TYPE"; + public static final String SERVICE_INSTANCE_ID_FIELD_NAME = "SERVICE_INSTANCE_ID"; + public static final String REQUEST_ID_FIELD_NAME = "REQUEST_ID"; + public static final String CREATION_DATE_FIELD_NAME = "CREATION_DATE"; + public static final String LOG_FIELD_NAME = "LOG"; + public static final String ASDC_ARTIFACTS_TABLE_NAME = "ASDC_ARTIFACTS"; + + // input fields names + public static final String PAYLOAD = "payload"; + + // constants fo DG + public static final String VNF_TYPE_FIELD_NAME = "org.openecomp.appc.vftype"; + public static final String VNF_VERSION_FIELD_NAME = "org.openecomp.appc.vfversion"; + public static final String VNF_RESOURCE_VERSION_FIELD_NAME = "org.openecomp.appc.resource-version"; + public static final String TARGET_VNF_TYPE = "target-vnf-type"; + public static final String FILE_CONTENT_FIELD_NAME = "file-content"; + public static final String CONNECTION_DETAILS_FIELD_NAME = "connection-details"; + public static final String CONFIGURATION_FILE_FIELD_NAME = "configuration-file-name"; + public static final String VNF_HOST_IP_ADDRESS_FIELD_NAME = "vnf-host-ip-address"; + public static final String UPGRADE_VERSION = "upgrade-version"; + public static final String DG_ERROR_FIELD_NAME = "org.openecomp.appc.dg.error"; + public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; + public static final String RESOURCEKEY = "resourceKey"; + public static final String REQ_ID_FIELD_NAME = "org.openecomp.appc.reqid"; + public static final String API_VERSION_FIELD_NAME = "org.openecomp.appc.apiversion"; + public static final String MODEL_ENTITLMENT_POOL_UUID_NAME = "model.entitlement.pool.uuid"; + public static final String MODEL_LICENSE_KEY_UUID_NAME = "model.license.key.uuid"; + public static final String ENTITLMENT_POOL_UUID_NAME = "entitlement.pool.uuid"; + public static final String LICENSE_KEY_UUID_NAME = "license.key.uuid"; + public static final String IS_ACQUIRE_LICENSE_REQUIRE ="is.acquire-license.require"; + public static final String IS_RELEASE_LICENSE_REQUIRE ="is.release-license.require"; + + public static final String AAI_ENTITLMENT_POOL_UUID_NAME = "aai.input.data.entitlement-assignment-group-uuid"; + public static final String AAI_LICENSE_KEY_UUID_NAME = "aai.input.data.license-assignment-group-uuid"; + public static final String AAI_LICENSE_KEY_VALUE = "aai.input.data.license-key"; + public static final String IS_AAI_ENTITLEMENT_UPDATE_REQUIRE = "is.aai-entitlement-update.require"; + public static final String IS_AAI_LICENSE_UPDATE_REQUIRE = "is.aai-license-update.require"; + public static final String IS_ACQUIRE_ENTITLEMENT_REQUIRE ="is.acquire-entitlement.require"; + public static final String IS_RELEASE_ENTITLEMENT_REQUIRE ="is.release-entitlement.require"; + + public enum ASDC_ARTIFACTS_FIELDS { + SERVICE_UUID, + DISTRIBUTION_ID, + SERVICE_NAME, + SERVICE_DESCRIPTION, + RESOURCE_UUID, + RESOURCE_INSTANCE_NAME, + RESOURCE_NAME, + RESOURCE_VERSION, + RESOURCE_TYPE, + ARTIFACT_UUID, + ARTIFACT_TYPE, + ARTIFACT_VERSION, + ARTIFACT_DESCRIPTION, + INTERNAL_VERSION, + CREATION_DATE, + ARTIFACT_NAME, + ARTIFACT_CONTENT + } +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..260b218d6 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + + <service id="aaiServicePlugin" interface="org.openecomp.appc.dg.aai.AAIPlugin"> + <bean class="org.openecomp.appc.dg.aai.impl.AAIPluginImpl"/> + </service> + +</blueprint> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/src/main/test/java/org/openecomp/appc/dg/aai/impl/AAIClientMock.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/src/main/test/java/org/openecomp/appc/dg/aai/impl/AAIClientMock.java new file mode 100644 index 000000000..fc4379dd2 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/src/main/test/java/org/openecomp/appc/dg/aai/impl/AAIClientMock.java @@ -0,0 +1,544 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.aai.impl; + +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicException; +import org.openecomp.sdnc.sli.SvcLogicResource; +import org.openecomp.sdnc.sli.aai.AAIClient; +import org.openecomp.sdnc.sli.aai.AAIServiceException; +import org.openecomp.sdnc.sli.aai.data.*; +import org.openecomp.sdnc.sli.aai.data.notify.NotifyEvent; +import org.openecomp.sdnc.sli.aai.data.v1507.VServer; +import org.openecomp.sdnc.sli.aai.update.Update; + + +public class AAIClientMock implements AAIClient { + + Map<String, String> mockAAI = new HashMap<>(); + + public void setMockAAI(Map<String, String> mockAAI) { + this.mockAAI = mockAAI; + } + + @Override + public AAIResponse requestSdnZoneQuery(String s, String s1, String s2) throws AAIServiceException { + return null; + } + + @Override + public boolean postNetworkVceData(String s, Vce vce) throws AAIServiceException { + return false; + } + + @Override + public Vce requestNetworkVceData(String s) throws AAIServiceException { + return null; + } + + @Override + public boolean deleteNetworkVceData(String s, String s1) throws AAIServiceException { + return false; + } + + @Override + public ServiceInstance requestServiceInterfaceData(String s) throws AAIServiceException { + return null; + } + + @Override + public ServiceInstance requestServiceInterfaceData(String s, String s1, String s2) throws AAIServiceException { + return null; + } + + @Override + public boolean postServiceInterfaceData(String s, String s1, String s2, ServiceInstance serviceInstance) throws AAIServiceException { + return false; + } + + @Override + public SearchResults requestServiceInstanceURL(String s) throws AAIServiceException { + return null; + } + + @Override + public Vpe requestNetworkVpeData(String s) throws AAIServiceException { + return null; + } + + @Override + public boolean postNetworkVpeData(String s, Vpe vpe) throws AAIServiceException { + return false; + } + + @Override + public boolean deleteNetworkVpeData(String s, String s1) throws AAIServiceException { + return false; + } + + @Override + public Vserver requestVServerData(String s, String s1, String s2, String s3) throws AAIServiceException { + return null; + } + + @Override + public boolean postVServerData(String s, String s1, String s2, String s3, Vserver vserver) throws AAIServiceException { + return false; + } + + @Override + public boolean deleteVServerData(String s, String s1, String s2, String s3, String s4) throws AAIServiceException { + return false; + } + + @Override + public URL requestVserverURLNodeQuery(String s) throws AAIServiceException { + return null; + } + + @Override + public String getTenantIdFromVserverUrl(URL url) { + return null; + } + + @Override + public String getCloudOwnerFromVserverUrl(URL url) { + return null; + } + + @Override + public String getCloudRegionFromVserverUrl(URL url) { + return null; + } + + @Override + public String getVServerIdFromVserverUrl(URL url, String s) { + return null; + } + + @Override + public Vserver requestVServerDataByURL(URL url) throws AAIServiceException { + return null; + } + + @Override + public VplsPe requestNetworkVplsPeData(String s) throws AAIServiceException { + return null; + } + + @Override + public boolean postNetworkVplsPeData(String s, VplsPe vplsPe) throws AAIServiceException { + return false; + } + + @Override + public boolean deleteNetworkVplsPeData(String s, String s1) throws AAIServiceException { + return false; + } + + @Override + public Complex requestNetworkComplexData(String s) throws AAIServiceException { + return null; + } + + @Override + public boolean postNetworkComplexData(String s, Complex complex) throws AAIServiceException { + return false; + } + + @Override + public boolean deleteNetworkComplexData(String s, String s1) throws AAIServiceException { + return false; + } + + @Override + public CtagPool requestCtagPoolData(String s, String s1, String s2) throws AAIServiceException { + return null; + } + + @Override + public VServer dataChangeRequestVServerData(URL url) throws AAIServiceException { + return null; + } + + @Override + public CtagPool dataChangeRequestCtagPoolData(URL url) throws AAIServiceException { + return null; + } + + @Override + public VplsPe dataChangeRequestVplsPeData(URL url) throws AAIServiceException { + return null; + } + + @Override + public Vpe dataChangeRequestVpeData(URL url) throws AAIServiceException { + return null; + } + + @Override + public DvsSwitch dataChangeRequestDvsSwitchData(URL url) throws AAIServiceException { + return null; + } + + @Override + public PServer dataChangeRequestPServerData(URL url) throws AAIServiceException { + return null; + } + + @Override + public OamNetwork dataChangeRequestOAMNetworkData(URL url) throws AAIServiceException { + return null; + } + + @Override + public AvailabilityZone dataChangeRequestAvailabilityZoneData(URL url) throws AAIServiceException { + return null; + } + + @Override + public Complex dataChangeRequestComplexData(URL url) throws AAIServiceException { + return null; + } + + @Override + public boolean dataChangeDeleteVServerData(URL url) throws AAIServiceException { + return false; + } + + @Override + public boolean dataChangeDeleteCtagPoolData(URL url) throws AAIServiceException { + return false; + } + + @Override + public boolean dataChangeDeleteVplsPeData(URL url) throws AAIServiceException { + return false; + } + + @Override + public boolean dataChangeDeleteVpeData(URL url) throws AAIServiceException { + return false; + } + + @Override + public boolean dataChangeDeleteDvsSwitchData(URL url) throws AAIServiceException { + return false; + } + + @Override + public boolean dataChangeDeleteOAMNetworkData(URL url) throws AAIServiceException { + return false; + } + + @Override + public boolean dataChangeDeleteAvailabilityZoneData(URL url) throws AAIServiceException { + return false; + } + + @Override + public boolean dataChangeDeleteComplexData(URL url) throws AAIServiceException { + return false; + } + + @Override + public GenericVnf requestGenericVnfData(String s) throws AAIServiceException { + return null; + } + + @Override + public boolean postGenericVnfData(String s, GenericVnf genericVnf) throws AAIServiceException { + return false; + } + + @Override + public boolean deleteGenericVnfData(String s, String s1) throws AAIServiceException { + return false; + } + + @Override + public DvsSwitch requestDvsSwitchData(String s) throws AAIServiceException { + return null; + } + + @Override + public boolean postDvsSwitchData(String s, DvsSwitch dvsSwitch) throws AAIServiceException { + return false; + } + + @Override + public boolean deleteDvsSwitchData(String s, String s1) throws AAIServiceException { + return false; + } + + @Override + public PInterface requestPInterfaceData(String s, String s1) throws AAIServiceException { + return null; + } + + @Override + public boolean postPInterfaceData(String s, String s1, PInterface pInterface) throws AAIServiceException { + return false; + } + + @Override + public boolean deletePInterfaceData(String s, String s1, String s2) throws AAIServiceException { + return false; + } + + @Override + public PhysicalLink requestPhysicalLinkData(String s) throws AAIServiceException { + return null; + } + + @Override + public boolean postPhysicalLinkData(String s, PhysicalLink physicalLink) throws AAIServiceException { + return false; + } + + @Override + public boolean deletePhysicalLinkData(String s, String s1) throws AAIServiceException { + return false; + } + + @Override + public PServer requestPServerData(String s) throws AAIServiceException { + return null; + } + + @Override + public boolean postPServerData(String s, PServer pServer) throws AAIServiceException { + return false; + } + + @Override + public boolean deletePServerData(String s, String s1) throws AAIServiceException { + return false; + } + + @Override + public L3Network requestL3NetworkData(String s) throws AAIServiceException { + return null; + } + + @Override + public L3Network requestL3NetworkQueryByName(String s) throws AAIServiceException { + return null; + } + + @Override + public boolean postL3NetworkData(String s, L3Network l3Network) throws AAIServiceException { + return false; + } + + @Override + public boolean deleteL3NetworkData(String s, String s1) throws AAIServiceException { + return false; + } + + @Override + public VpnBinding requestVpnBindingData(String s) throws AAIServiceException { + return null; + } + + @Override + public boolean deleteVpnBindingData(String s, String s1) throws AAIServiceException { + return false; + } + + @Override + public VnfImage requestVnfImageData(String s) throws AAIServiceException { + return null; + } + + @Override + public VnfImage requestVnfImageDataByVendorModel(String s, String s1) throws AAIServiceException { + return null; + } + + @Override + public VnfImage requestVnfImageDataByVendorModelVersion(String s, String s1, String s2) throws AAIServiceException { + return null; + } + + @Override + public boolean sendNotify(NotifyEvent notifyEvent, String s, String s1) throws AAIServiceException { + return false; + } + + @Override + public SitePairSet requestSitePairSetData(String s) throws AAIServiceException { + return null; + } + + @Override + public boolean postSitePairSetData(String s, SitePairSet sitePairSet) throws AAIServiceException { + return false; + } + + @Override + public boolean deleteSitePairSetData(String s, String s1) throws AAIServiceException { + return false; + } + + @Override + public Service requestServiceData(String s) throws AAIServiceException { + return null; + } + + @Override + public boolean postServiceData(String s, Service service) throws AAIServiceException { + return false; + } + + @Override + public boolean deleteServiceData(String s, String s1) throws AAIServiceException { + return false; + } + + @Override + public QueryResponse requestNodeQuery(String s, String s1, String s2) throws AAIServiceException { + return null; + } + + @Override + public String requestDataByURL(URL url) throws AAIServiceException { + return null; + } + + @Override + public GenericVnf requestGenericVnfeNodeQuery(String s) throws AAIServiceException { + return null; + } + + @Override + public Tenant requestTenantData(String s, String s1, String s2) throws AAIServiceException { + return null; + } + + @Override + public Tenant requestTenantDataByName(String s, String s1, String s2) throws AAIServiceException { + return null; + } + + @Override + public boolean postTenantData(String s, String s1, String s2, Tenant tenant) throws AAIServiceException { + return false; + } + + @Override + public boolean updateAnAIEntry(Update update) throws AAIServiceException { + return false; + } + + @Override + public QueryStatus backup(Map<String, String> map, SvcLogicContext svcLogicContext) throws SvcLogicException { + return null; + } + + @Override + public QueryStatus restore(Map<String, String> map, SvcLogicContext svcLogicContext) throws SvcLogicException { + return null; + } + + @Override + public QueryStatus isAvailable(String s, String s1, String s2, SvcLogicContext svcLogicContext) throws SvcLogicException { + return null; + } + + @Override + public QueryStatus exists(String s, String s1, String s2, SvcLogicContext svcLogicContext) throws SvcLogicException { + return null; + } + + @Override + public QueryStatus query(String s, boolean b, String s1, String key, String prefix, String s4, SvcLogicContext ctx) throws SvcLogicException { + if (s.equals("generic-vnf") && key.equals("vnf-id = 'test_VNF'") && ctx != null) { + for (Map.Entry<String, String> entry : mockAAI.entrySet()) { + ctx.setAttribute(prefix + "." + entry.getKey(), entry.getValue()); + } + return QueryStatus.SUCCESS; + + + } else if (key.equals("vnf-id = 'test_VNF1'")){ + return QueryStatus.NOT_FOUND; + } + else if (key.equals("vnf-id = 'test_VNF3'")){ + throw new SvcLogicException(); + } + else { + return QueryStatus.FAILURE; + } + + + } + + @Override + public QueryStatus reserve(String s, String s1, String s2, String s3, SvcLogicContext svcLogicContext) throws SvcLogicException { + return null; + } + + @Override + public QueryStatus save(String s, boolean b, boolean b1, String s1, Map<String, String> map, String s2, SvcLogicContext svcLogicContext) throws SvcLogicException { + return null; + } + + @Override + public QueryStatus release(String s, String s1, SvcLogicContext svcLogicContext) throws SvcLogicException { + return null; + } + + @Override + public QueryStatus delete(String s, String s1, SvcLogicContext svcLogicContext) throws SvcLogicException { + return null; + } + + @Override + public QueryStatus notify(String s, String s1, SvcLogicContext svcLogicContext) throws SvcLogicException { + return null; + } + + @Override + public QueryStatus update(String s, String key, Map<String, String> data, String prefix, SvcLogicContext ctx) throws SvcLogicException { + if (s.equals("generic-vnf") && key.equals("vnf-id = 'test_VNF'") && ctx != null) { + for (Map.Entry<String, String> entry : data.entrySet()) { + mockAAI.put(entry.getKey(), entry.getValue()); + } + return QueryStatus.SUCCESS; + + + } else if (key.equals("vnf-id = 'test_VNF1'")){ + return QueryStatus.NOT_FOUND; + } + else if (key.equals("vnf-id = 'test_VNF3'")){ + throw new SvcLogicException(); + } + else { + return QueryStatus.FAILURE; + } + + } +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/src/main/test/java/org/openecomp/appc/dg/aai/impl/AAIPluginImplTest.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/src/main/test/java/org/openecomp/appc/dg/aai/impl/AAIPluginImplTest.java new file mode 100644 index 000000000..8d6fea0cf --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-aai/src/main/test/java/org/openecomp/appc/dg/aai/impl/AAIPluginImplTest.java @@ -0,0 +1,260 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.aai.impl; + +import org.junit.*; +import org.junit.runner.RunWith; +import org.mockito.*; +import org.openecomp.appc.dg.aai.Constants; +import org.openecomp.appc.dg.aai.impl.AAIPluginImpl; +import org.openecomp.appc.dg.common.dao.DAOService; +import org.openecomp.appc.dg.common.impl.LicenseManagerImpl; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicResource; +import org.openecomp.sdnc.sli.aai.AAIClient; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.*; +import static org.powermock.api.support.SuppressCode.suppressConstructor; + + +@RunWith(PowerMockRunner.class) +@PrepareForTest({AAIPluginImpl.class, FrameworkUtil.class}) +public class AAIPluginImplTest { + private AAIPluginImpl aaiPlugin; + private AAIClientMock aaiClient; + + private final BundleContext bundleContext= Mockito.mock(BundleContext.class); + private final Bundle bundleService=Mockito.mock(Bundle.class); + private final ServiceReference sref=Mockito.mock(ServiceReference.class); + + String prefix = "aai.input.data"; + String vnfId = "test_VNF"; + String vnfId1 = "test_VNF1"; + String vnfId2 = "test_VNF2"; + String vnfId3 = "test_VNF3"; + + @Before + public void setUp() throws NoSuchFieldException, IllegalAccessException { + aaiClient = new AAIClientMock(); + PowerMockito.mockStatic(FrameworkUtil.class); + PowerMockito.when(FrameworkUtil.getBundle(Matchers.any(Class.class))).thenReturn(bundleService); + PowerMockito.when(bundleService.getBundleContext()).thenReturn(bundleContext); + PowerMockito.when(bundleContext.getServiceReference(Matchers.any(Class.class))).thenReturn(sref); + PowerMockito.when(bundleContext.getService(sref)).thenReturn(aaiClient); + aaiPlugin = new AAIPluginImpl(); + + + } + + + + + @Test + public void testPostGenericVnfData() throws Exception { + Map<String, String> params = new HashMap<>(); + params.put(prefix+"."+"license-key-uuid", "123"); + params.put(prefix+"."+"license-assignment-group-uuid", "1234"); + params.put(prefix+"."+"data.license-key", "12345"); + + HashMap<String, String> mockAAI = new HashMap<>(); + aaiClient.setMockAAI(mockAAI); + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("aai.vnfID", vnfId); + ctx.setAttribute("aai.prefix", prefix); + + aaiPlugin.postGenericVnfData(params, ctx); + + Assert.assertEquals("wrong license-key-uuid","123", mockAAI.get("license-key-uuid")); + Assert.assertEquals("wrong license-assignment-group-uuid","1234", mockAAI.get("license-assignment-group-uuid")); + Assert.assertEquals("wrong data.license-key","12345", mockAAI.get("data.license-key")); + } + + + @Test + public void testPostGenericVnfDataNegativeVnfNotFound() throws Exception { + Map<String, String> params = new HashMap<>(); + params.put(prefix+"."+"license-key-uuid", "123"); + params.put(prefix+"."+"license-assignment-group-uuid", "1234"); + params.put(prefix+"."+"data.license-key", "12345"); + + HashMap<String, String> mockAAI = new HashMap<>(); + + aaiClient.setMockAAI(mockAAI); + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("aai.vnfID", vnfId1); + ctx.setAttribute("aai.prefix", prefix); + + try { + aaiPlugin.postGenericVnfData(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertNotNull(ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE)); + } + + } + + + @Test + public void testPostGenericVnfDataNegativeFailure() throws Exception { + Map<String, String> params = new HashMap<>(); + params.put(prefix+"."+"license-key-uuid", "123"); + params.put(prefix+"."+"license-assignment-group-uuid", "1234"); + params.put(prefix+"."+"data.license-key", "12345"); + + HashMap<String, String> mockAAI = new HashMap<>(); + + aaiClient.setMockAAI(mockAAI); + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("aai.vnfID", vnfId2); + ctx.setAttribute("aai.prefix", prefix); + + try { + aaiPlugin.postGenericVnfData(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertNotNull(ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE)); + } + + } + + + @Test + public void testPostGenericVnfDataNegativeSvcLogicException() throws Exception { + Map<String, String> params = new HashMap<>(); + params.put(prefix+"."+"license-key-uuid", "123"); + params.put(prefix+"."+"license-assignment-group-uuid", "1234"); + params.put(prefix+"."+"data.license-key", "12345"); + + HashMap<String, String> mockAAI = new HashMap<>(); + + aaiClient.setMockAAI(mockAAI); + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("aai.vnfID", vnfId3); + ctx.setAttribute("aai.prefix", prefix); + + try { + aaiPlugin.postGenericVnfData(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertNotNull(ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE)); + } + + } + + @Test + public void testGetGenericVnfData() throws Exception { + String vnfNameKey = "vnf-name"; + String vnfType = "VSCP"; + String vnfTypeKey = "vnf-type"; + String provStatus = "Active"; + String provStatusKey = "prov-status"; + String orchestrationStatus = "Running"; + String orchestrationStatusKey = "orchestration-status"; + + Map<String, String> params = new HashMap<>(); + HashMap<String, String> mockAAI = new HashMap<>(); + mockAAI.put(vnfNameKey,vnfId); + mockAAI.put(vnfTypeKey,vnfType); + mockAAI.put(provStatusKey, provStatus); + mockAAI.put(orchestrationStatusKey, orchestrationStatus); + aaiClient.setMockAAI(mockAAI); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("aai.vnfID", vnfId); + ctx.setAttribute("aai.prefix", prefix); + + + aaiPlugin.getGenericVnfData(params, ctx); + + Assert.assertEquals("wrong "+vnfNameKey,vnfId, ctx.getAttribute(prefix + "." + vnfNameKey)); + Assert.assertEquals("wrong "+orchestrationStatusKey,orchestrationStatus, ctx.getAttribute(prefix + "." + orchestrationStatusKey)); + Assert.assertEquals("wrong "+vnfTypeKey,vnfType, ctx.getAttribute(prefix + "." + vnfTypeKey)); + Assert.assertEquals("wrong "+provStatusKey,provStatus, ctx.getAttribute(prefix + "." + provStatusKey )); + } + + + + + @Test + public void testGetGenericVnfDataNegativeVnfNotFound() throws Exception { + + Map<String, String> params = new HashMap<>(); + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("aai.vnfID", vnfId1); + ctx.setAttribute("aai.prefix", prefix); + + + try { + aaiPlugin.getGenericVnfData(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertNotNull(ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE)); + } + } + + + @Test + public void testGetGenericVnfDataNegativeFailure() throws Exception { + + Map<String, String> params = new HashMap<>(); + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("aai.vnfID", vnfId2); + ctx.setAttribute("aai.prefix", prefix); + + try { + aaiPlugin.getGenericVnfData(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertNotNull(ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE)); + } + } + + + @Test + public void testGetGenericVnfDataNegativeSvcLogicException() throws Exception { + + Map<String, String> params = new HashMap<>(); + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("aai.vnfID", vnfId3); + ctx.setAttribute("aai.prefix", prefix); + + try { + aaiPlugin.getGenericVnfData(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertNotNull(ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE)); + } + } + +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/.gitignore b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/pom.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/pom.xml new file mode 100644 index 000000000..e41a3cb86 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/pom.xml @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-shared</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-dg-common</artifactId> + <packaging>bundle</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dmaap-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-mockito</artifactId> + <version>1.6.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-junit4</artifactId> + <version>1.6.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-easymock</artifactId> + <version>1.6.2</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>appc-dg-common</Bundle-SymbolicName> + <Export-Package>org.openecomp.appc.dg.common,org.openecomp.appc.dg.common.objects,org.openecomp.appc.dg.common.utils</Export-Package> + <Private-Package>org.openecomp.appc.dg.common.impl.*</Private-Package> + <Import-Package>!org.apache.log,!org.apache.commons.logging,!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.jasypt.*,*</Import-Package> + <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/DCAEReporterPlugin.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/DCAEReporterPlugin.java new file mode 100644 index 000000000..a99038063 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/DCAEReporterPlugin.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.common; + +import java.util.Map; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + + +public interface DCAEReporterPlugin extends SvcLogicJavaPlugin { + void report(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + void reportSuccess(Map<String, String> params, SvcLogicContext ctx) throws APPCException; +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/JsonDgUtil.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/JsonDgUtil.java new file mode 100644 index 000000000..2b3fbf793 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/JsonDgUtil.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.common; + +import java.util.Map; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + + +public interface JsonDgUtil extends SvcLogicJavaPlugin { + void flatAndAddToContext(Map<String, String> params, SvcLogicContext ctx) throws APPCException; +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/LegacyUtil.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/LegacyUtil.java new file mode 100644 index 000000000..a356a1546 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/LegacyUtil.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.common; + +import java.util.Map; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + + + +public interface LegacyUtil extends SvcLogicJavaPlugin { + + void prepareRequest(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + void convertPositiveResponse(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + void convertNegativeResponse(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/Constants.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/Constants.java new file mode 100644 index 000000000..92d23e3a6 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/Constants.java @@ -0,0 +1,57 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.common.impl; + + + +class Constants { + + public static final String DG_ERROR_FIELD_NAME = "org.openecomp.appc.dg.error"; + public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; + public static final String API_VERSION_FIELD_NAME = "org.openecomp.appc.apiversion"; + public static final String REQ_ID_FIELD_NAME = "org.openecomp.appc.reqid"; + public static final String PAYLOAD = "payload"; + + enum LegacyAttributes { + Action("org.openecomp.appc.action"), + VMID("org.openecomp.appc.vmid"), + IdentityURL("org.openecomp.appc.identity.url"), + TenantID("org.openecomp.appc.tenant.id"); + + private String value; + LegacyAttributes(String value) {this.value = value;} + String getValue() {return value;} + }; + + enum LCMAttributes { + Action("input.action"), + Payload("input.payload"), + VMID("vm-id"), + IdentityURL("identity-url"), + TenantID("tenant.id"); + + private String value; + LCMAttributes(String value) {this.value = value;} + String getValue() {return value;} + }; + +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/DCAEReporterPluginImpl.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/DCAEReporterPluginImpl.java new file mode 100644 index 000000000..4458de10b --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/DCAEReporterPluginImpl.java @@ -0,0 +1,121 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.common.impl; + +import org.apache.commons.lang3.StringUtils; +import org.openecomp.appc.adapter.dmaap.EventSender; +import org.openecomp.appc.adapter.dmaap.DmaapDestination; +import org.openecomp.appc.adapter.dmaap.event.EventHeader; +import org.openecomp.appc.adapter.dmaap.event.EventMessage; +import org.openecomp.appc.adapter.dmaap.event.EventStatus; +import org.openecomp.appc.dg.common.DCAEReporterPlugin; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +import java.util.Map; + +public class DCAEReporterPluginImpl implements DCAEReporterPlugin { + + private EventSender eventSender; + + public DCAEReporterPluginImpl() { + BundleContext bctx = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); + ServiceReference sref = bctx.getServiceReference(EventSender.class); + eventSender = (EventSender) bctx.getService(sref); + } + + @Override + public void report(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + Integer errorReportCode = 501; + boolean bwcMode = Boolean.parseBoolean(ctx.getAttribute("isBwcMode")); + String errorDescription,apiVersion,eventId ; + errorDescription = getErrorDescriptionAndAddToCtx(bwcMode,params,ctx); + if(!bwcMode){ + apiVersion = ctx.getAttribute("input.common-header.api-ver"); + eventId = ctx.getAttribute("input.common-header.request-id"); + }else { + apiVersion = ctx.getAttribute(Constants.API_VERSION_FIELD_NAME); + eventId = ctx.getAttribute(Constants.REQ_ID_FIELD_NAME); + } + + EventMessage eventMessage = new EventMessage(new EventHeader((new java.util.Date()).toString(), apiVersion, eventId), new EventStatus(errorReportCode, errorDescription)); + eventSender.sendEvent(DmaapDestination.DCAE, eventMessage); + } + + private String getErrorDescriptionAndAddToCtx(boolean bwcMode, Map<String, String> params, SvcLogicContext ctx) { + String errorDescription; + if(!bwcMode) { + errorDescription = params.get(Constants.DG_OUTPUT_STATUS_MESSAGE); + if(StringUtils.isEmpty(errorDescription)) { + errorDescription = ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE); + }else { + addToContextIfNotContains(bwcMode,errorDescription,ctx); + } + }else{ + errorDescription = params.get(Constants.DG_ERROR_FIELD_NAME); + if(StringUtils.isEmpty(errorDescription)) { + errorDescription = ctx.getAttribute("org.openecomp.appc.dg.error"); + }else { + addToContextIfNotContains(bwcMode, errorDescription,ctx); + } + } + + if(StringUtils.isEmpty(errorDescription)) { + errorDescription = "Unknown"; + } + return errorDescription; + } + + private void addToContextIfNotContains(boolean bwcMode, String errorDescription, SvcLogicContext ctx) { + String errorDescriptionFromCtx; + if(!StringUtils.isEmpty(errorDescription)) { + String outputStatusMessageProperty = bwcMode ? "org.openecomp.appc.dg.error" : Constants.DG_OUTPUT_STATUS_MESSAGE; + errorDescriptionFromCtx = ctx.getAttribute(outputStatusMessageProperty); + if(StringUtils.isEmpty(errorDescriptionFromCtx)){ + ctx.setAttribute(outputStatusMessageProperty, errorDescription); + }else if (!errorDescriptionFromCtx.contains(errorDescription)){ + ctx.setAttribute(outputStatusMessageProperty, errorDescriptionFromCtx+ " | "+ errorDescription); + } + } + } + + + @Override + public void reportSuccess(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + Integer successReportCode = 500; + String successDescription, apiVersion, eventId; + successDescription = params.get(Constants.DG_OUTPUT_STATUS_MESSAGE); + apiVersion = ctx.getAttribute("input.common-header.api-ver"); + eventId = ctx.getAttribute("input.common-header.request-id"); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, successDescription); + + if (null == successDescription) { + successDescription = "Success"; + } + EventMessage eventMessage = new EventMessage(new EventHeader((new java.util.Date()).toString(), apiVersion, eventId), new EventStatus(successReportCode, successDescription)); + eventSender.sendEvent(DmaapDestination.DCAE, eventMessage); + } + +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/JsonDgUtilImpl.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/JsonDgUtilImpl.java new file mode 100644 index 000000000..95191132a --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/JsonDgUtilImpl.java @@ -0,0 +1,66 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.common.impl; + +import org.apache.commons.lang.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.openecomp.appc.dg.common.JsonDgUtil; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.util.JsonUtil; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.SvcLogicContext; + +import java.util.Map; + + +public class JsonDgUtilImpl implements JsonDgUtil { + private static final EELFLogger logger = EELFManager.getInstance().getLogger(JsonDgUtilImpl.class); + + @Override + public void flatAndAddToContext(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + + if (logger.isTraceEnabled()) { + logger.trace("Entering to flatAndAddToContext with params = "+ ObjectUtils.toString(params)+", SvcLogicContext = "+ObjectUtils.toString(ctx)); + } + try { + String paramName = Constants.PAYLOAD; + String payload = params.get(paramName); + if (payload == "") + payload = ctx.getAttribute("input.payload"); + if (!StringUtils.isEmpty(payload)) { + Map<String, String> flatMap = JsonUtil.convertJsonStringToFlatMap(payload); + if (flatMap != null && flatMap.size() > 0) { + for (Map.Entry<String, String> entry : flatMap.entrySet()) { + ctx.setAttribute(entry.getKey(), entry.getValue()); + } + } + } else { + logger.warn("input payload param value is empty (\"\") or null"); + } + } catch (Exception e) { + logger.error(e.toString()); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.toString()); + throw new APPCException(e); + } + } +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/LegacyUtilImpl.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/LegacyUtilImpl.java new file mode 100644 index 000000000..6354b2044 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/LegacyUtilImpl.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.common.impl; + +import java.util.Map; + +import org.openecomp.appc.dg.common.LegacyUtil; +import org.openecomp.appc.dg.common.utils.JSONUtil; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; + + + +public class LegacyUtilImpl implements LegacyUtil { + + @Override public void prepareRequest(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + ctx.setAttribute(Constants.LegacyAttributes.Action.getValue(), ctx.getAttribute(Constants.LCMAttributes.Action.getValue()).toLowerCase()); + + String payloadStr = ctx.getAttribute(Constants.LCMAttributes.Payload.getValue()); + Map<String,String> payloads = JSONUtil.extractPlainValues(payloadStr, + Constants.LCMAttributes.VMID.getValue(), Constants.LCMAttributes.IdentityURL.getValue(), Constants.LCMAttributes.TenantID.getValue()); + + ctx.setAttribute(Constants.LegacyAttributes.VMID.getValue(), payloads.get(Constants.LCMAttributes.VMID.getValue())); + ctx.setAttribute(Constants.LegacyAttributes.IdentityURL.getValue(), payloads.get(Constants.LCMAttributes.IdentityURL.getValue())); + ctx.setAttribute(Constants.LegacyAttributes.TenantID.getValue(), payloads.get(Constants.LCMAttributes.TenantID.getValue())); + + } + + @Override + public void convertPositiveResponse(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + } + + @Override + public void convertNegativeResponse(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + } +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/objects/ConnectionDetails.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/objects/ConnectionDetails.java new file mode 100644 index 000000000..d576555c4 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/objects/ConnectionDetails.java @@ -0,0 +1,65 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.common.objects; + + + +public class ConnectionDetails { + + private String host; + private int port; + private String username; + private String password; + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/utils/JAXBUtil.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/utils/JAXBUtil.java new file mode 100644 index 000000000..a298e9cca --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/utils/JAXBUtil.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.common.utils; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; + + + +public class JAXBUtil { + + public static <T> T toObject(String xml, Class<T> type) throws JAXBException { + + //create JAXB context + JAXBContext context = JAXBContext.newInstance(type); + + //Create Unmarshaller using JAXB context + Unmarshaller unmarshaller = context.createUnmarshaller(); + + InputStream xmlInputStream = new ByteArrayInputStream(xml.getBytes()); + BufferedReader reader = new BufferedReader(new InputStreamReader(xmlInputStream)); + + return type.cast(unmarshaller.unmarshal(reader)); + + } +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/utils/JSONUtil.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/utils/JSONUtil.java new file mode 100644 index 000000000..fe7197482 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/utils/JSONUtil.java @@ -0,0 +1,80 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.common.utils; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.io.Reader; +import java.util.*; + + +public class JSONUtil { + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + public static <T> T fromJson(String json, Class<T> clazz) { + + try { + return OBJECT_MAPPER.readValue(json, clazz); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static <T> T fromJson(Reader reader, Class<T> clazz) { + + try { + return OBJECT_MAPPER.readValue(reader, clazz); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static String toJson(Object object) { + + try { + return OBJECT_MAPPER.writeValueAsString(object); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static Map<String,String> extractPlainValues(String json, String ... names) { + if (null == names) return Collections.emptyMap(); + Map<String,String> values = new HashMap<>(); + try { + final JsonNode jsonNode = OBJECT_MAPPER.readTree(json); + for (String name : names) { + values.put(name, jsonNode.path(name).asText()); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + return values; + } + + + + +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..53b5367e4 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- + Starter Blueprint Camel Definition appc-aai-adapter-blueprint +--> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + + <bean id="JsonDgUtilBean" class="org.openecomp.appc.dg.common.impl.JsonDgUtilImpl"/> + <service id="JsonDgUtil" interface="org.openecomp.appc.dg.common.JsonDgUtil" ref="JsonDgUtilBean"/> + + <reference id="eventSenderRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.adapter.dmaap.EventSender" /> + + <bean id="DCAEReporterPluginBean" class="org.openecomp.appc.dg.common.impl.DCAEReporterPluginImpl" scope="singleton"/> + <service id="DCAEReporterPlugin" interface="org.openecomp.appc.dg.common.DCAEReporterPlugin" ref="DCAEReporterPluginBean"/> + + <bean id="legacyUtilBean" class="org.openecomp.appc.dg.common.impl.LegacyUtilImpl" scope="singleton"/> + <service id="legacyUtil" interface="org.openecomp.appc.dg.common.LegacyUtil" ref="legacyUtilBean"/> + +</blueprint> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..d8451ee8b --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,47 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + +org.openecomp.appc.netconf.db.url.netconfctl=jdbc:mysql://127.0.0.1:3306/test +org.openecomp.appc.netconf.db.user.netconfctl=test +org.openecomp.appc.netconf.db.pass.netconfctl=123456 + +org.openecomp.appc.db.url.sdnctl=jdbc:mysql://127.0.0.1:3306/test +org.openecomp.appc.db.user.sdnctl=test +org.openecomp.appc.db.pass.sdnctl=123456 + +org.openecomp.appc.netconf.db.url.sdnctl=jdbc:mysql://127.0.0.1:3306/test +org.openecomp.appc.netconf.db.user.sdnctl=test +org.openecomp.appc.netconf.db.pass.sdnctl=123456 + +### ### +### Properties commented out below provided in appc.properties ### +### ### +#event.pool.members=<MY_DMAAP_URL> +event.topic.write=APPC-TEST1 +event.client.key=VIlbtVl6YLhNUrtU +event.client.secret=64AG2hF4pYeG2pq7CT6XwUOT +#restconf.user=<RESTCONF_USER> +#restconf.pass=<RESTCONF_PASSWORD> + +org.openecomp.appc.adapter.netconf.VNFOperationalStateValidatorImpl-CONFIG_FILE=VnfGetOperationalStates diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/resources/xsd/vf-license-model.xsd b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/resources/xsd/vf-license-model.xsd new file mode 100644 index 000000000..9fb979609 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/main/resources/xsd/vf-license-model.xsd @@ -0,0 +1,88 @@ +<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <xs:element name="vf-license-model"> + <xs:complexType> + <xs:sequence> + <xs:element type="xs:string" name="vnf-id"/> + <xs:element type="xs:string" name="vendor-name"/> + <xs:element name="feature-group-list"> + <xs:complexType> + <xs:sequence> + <xs:element name="feature-group"> + <xs:complexType> + <xs:sequence> + <xs:element type="xs:string" name="feature-group-uuid"/> + <xs:element type="xs:string" name="name"/> + <xs:element type="xs:string" name="description"/> + <xs:element type="xs:string" name="att-part-number"/> + <xs:element name="entitlement-pool-list"> + <xs:complexType> + <xs:sequence> + <xs:element name="entitlement-pool"> + <xs:complexType> + <xs:sequence> + <xs:element type="xs:string" name="entitlement-pool-uuid"/> + <xs:element type="xs:string" name="name"/> + <xs:element type="xs:string" name="description"/> + <xs:element type="xs:string" name="manufacturer-reference-number"/> + <xs:element name="threshold-value"> + <xs:complexType> + <xs:sequence> + <xs:element type="xs:byte" name="value"/> + <xs:element type="xs:string" name="unit"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="entitlement-metric"> + <xs:complexType> + <xs:sequence> + <xs:element type="xs:string" name="value"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element type="xs:string" name="increments"/> + <xs:element name="aggregation-function"> + <xs:complexType> + <xs:sequence> + <xs:element type="xs:string" name="value"/> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="time"> + <xs:complexType> + <xs:sequence> + <xs:element type="xs:string" name="value"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + <xs:element name="license-key-group-list"> + <xs:complexType> + <xs:sequence> + <xs:element name="license-key-group"> + <xs:complexType> + <xs:sequence> + <xs:element type="xs:string" name="license-key-group-uuid"/> + <xs:element type="xs:string" name="name"/> + <xs:element type="xs:string" name="description"/> + <xs:element type="xs:string" name="type"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> +</xs:schema> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/DCAEReporterPluginImplTest.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/DCAEReporterPluginImplTest.java new file mode 100644 index 000000000..9b8290004 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/DCAEReporterPluginImplTest.java @@ -0,0 +1,154 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.common.impl; + +import org.junit.*; +import org.junit.runner.RunWith; +import org.mockito.*; +import org.openecomp.appc.adapter.dmaap.EventSender; +import org.openecomp.appc.adapter.dmaap.DmaapDestination; +import org.openecomp.appc.adapter.dmaap.event.EventMessage; +import org.openecomp.appc.dg.common.impl.Constants; +import org.openecomp.appc.dg.common.impl.DCAEReporterPluginImpl; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import java.util.HashMap; +import java.util.Map; + + +@RunWith(PowerMockRunner.class) +@PrepareForTest({DCAEReporterPluginImpl.class, FrameworkUtil.class}) +public class DCAEReporterPluginImplTest { + private SvcLogicContext ctx; + private Map<String, String> params; + + private final BundleContext bundleContext=Mockito.mock(BundleContext.class); + private final Bundle bundleService=Mockito.mock(Bundle.class); + private final ServiceReference sref=Mockito.mock(ServiceReference.class); + + + private DCAEReporterPluginImpl dcaeReporterPlugin; + private EventSenderMock eventSender; + + private String apiVer = "2.0.0"; + private String requestId = "123"; + private String error = "test-error"; + + @Before + public void setUp() throws NoSuchFieldException, IllegalAccessException { + eventSender = new EventSenderMock(); + PowerMockito.mockStatic(FrameworkUtil.class); + PowerMockito.when(FrameworkUtil.getBundle(Matchers.any(Class.class))).thenReturn(bundleService); + PowerMockito.when(bundleService.getBundleContext()).thenReturn(bundleContext); + PowerMockito.when(bundleContext.getServiceReference(Matchers.any(Class.class))).thenReturn(sref); + PowerMockito.when(bundleContext.getService(sref)).thenReturn(eventSender); + dcaeReporterPlugin = new DCAEReporterPluginImpl(); + + } + + + + + @Test + public void testReportBwcTrue() throws Exception { + + ctx = new SvcLogicContext(); + params = new HashMap<>(); + ctx.setAttribute("isBwcMode", "true"); + params.put(Constants.DG_ERROR_FIELD_NAME, error); + ctx.setAttribute(Constants.API_VERSION_FIELD_NAME, apiVer); + ctx.setAttribute(Constants.REQ_ID_FIELD_NAME, requestId); + + positiveAssert(); + } + + @Test + public void testReportErrorDescriptionNullBwcModeTrue() throws Exception { + + ctx = new SvcLogicContext(); + params = new HashMap<>(); + ctx.setAttribute("isBwcMode", "true"); + params.put(Constants.DG_ERROR_FIELD_NAME, null); + ctx.setAttribute(Constants.API_VERSION_FIELD_NAME, apiVer); + ctx.setAttribute(Constants.REQ_ID_FIELD_NAME, requestId); + + errorReasonNullAssert(); + } + + @Test + public void testReportErrorDescriptionNullBwcModeFalse() throws Exception { + + ctx = new SvcLogicContext(); + params = new HashMap<>(); + ctx.setAttribute("isBwcMode", "false"); + params.put("output.status.message", null); + ctx.setAttribute("input.common-header.api-ver", apiVer); + ctx.setAttribute("input.common-header.request-id", requestId); + + errorReasonNullAssert(); + } + + + private void errorReasonNullAssert() throws APPCException { + dcaeReporterPlugin.report(params, ctx); + DmaapDestination destination = eventSender.getDestination(); + EventMessage msg = eventSender.getMsg(); + Assert.assertEquals("wrong API version", apiVer, msg.getEventHeader().getApiVer()); + Assert.assertEquals("wrong requestId", requestId, msg.getEventHeader().getEventId()); + Assert.assertEquals("wrong error message", "Unknown", msg.getEventStatus().getReason()); + Assert.assertEquals("wrong destination", destination.name(), "DCAE"); + + } + + + private void positiveAssert() throws APPCException { + dcaeReporterPlugin.report(params, ctx); + DmaapDestination destination = eventSender.getDestination(); + EventMessage msg = eventSender.getMsg(); + Assert.assertEquals("wrong API version", apiVer, msg.getEventHeader().getApiVer()); + Assert.assertEquals("wrong requestId", requestId, msg.getEventHeader().getEventId()); + Assert.assertEquals("wrong error message", error, msg.getEventStatus().getReason()); + Assert.assertEquals("wrong destination", destination.name(), "DCAE"); + + } + + + @Test + public void testReportBwcFalse() throws Exception { + ctx = new SvcLogicContext(); + params = new HashMap<>(); + ctx.setAttribute("isBwcMode", "false"); + params.put("output.status.message", error); + ctx.setAttribute("input.common-header.api-ver", apiVer); + ctx.setAttribute("input.common-header.request-id", requestId); + + positiveAssert(); + + } + } diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/EventSenderMock.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/EventSenderMock.java new file mode 100644 index 000000000..0e6b1651b --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/EventSenderMock.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.common.impl; + +import java.util.Map; + +import org.openecomp.appc.adapter.dmaap.EventSender; +import org.openecomp.appc.adapter.dmaap.DmaapDestination; +import org.openecomp.appc.adapter.dmaap.event.EventMessage; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; + + +public class EventSenderMock implements EventSender { + EventMessage msg; + DmaapDestination destination; + + @Override + public boolean sendEvent(DmaapDestination destination, EventMessage msg) { + if (destination != null && msg != null){ + this.msg = msg; + this.destination = destination; + return true; + } + else{ + return false; + } + } + + @Override + public boolean sendEvent(DmaapDestination destination, Map<String, String> params, SvcLogicContext ctx) throws APPCException { + return false; + } + + public EventMessage getMsg() { + return msg; + } + + public DmaapDestination getDestination() { + return destination; + } +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/JsonDgUtilImplTest.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/JsonDgUtilImplTest.java new file mode 100644 index 000000000..70534872d --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/JsonDgUtilImplTest.java @@ -0,0 +1,145 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.common.impl; + +import ch.qos.logback.core.Appender; + +import org.junit.Assert; +import org.junit.Test; +import org.openecomp.appc.dg.common.impl.JsonDgUtilImpl; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; + +public class JsonDgUtilImplTest { + + private final Appender appender = mock(Appender.class); + + + @Test + public void testFlatAndAddToContext() throws Exception { + JsonDgUtilImpl jsonDgUtil = new JsonDgUtilImpl(); + String key = "payload"; + String testValueKey = "test-key"; + String testValueValue = "test-value"; + String testValueKey2 = "test-key2"; + String testValueValue2 = "test-value2"; + String payload = "{\"" + testValueKey + "\": \"" + testValueValue + "\",\""+testValueKey2+"\": \""+testValueValue2+"\"}"; + + SvcLogicContext ctx = new SvcLogicContext(); + Map<String, String> params = new HashMap<>(); + params.put(key, payload); + jsonDgUtil.flatAndAddToContext(params, ctx); + + + Assert.assertEquals(ctx.getAttribute(testValueKey), testValueValue); + Assert.assertEquals(ctx.getAttribute(testValueKey2), testValueValue2); + + + + } + + + @Test + public void testFlatAndAddToContextNegativeWrongPayload() throws Exception { + JsonDgUtilImpl jsonDgUtil = new JsonDgUtilImpl(); + String key = "payload"; + String testValueKey = "test-key"; + String testValueValue = "test-value"; + String testValueKey2 = "test-key2"; + String testValueValue2 = "test-value2"; + String payload = "{{\"" + testValueKey + "\": \"" + testValueValue + "\",\""+testValueKey2+"\": \""+testValueValue2+"\"}"; + + SvcLogicContext ctx = new SvcLogicContext(); + Map<String, String> params = new HashMap<>(); + params.put(key, payload); + try { + jsonDgUtil.flatAndAddToContext(params, ctx); + + } catch (APPCException e) { + Assert.assertNull(ctx.getAttribute(testValueKey)); + Assert.assertNull(ctx.getAttribute(testValueKey2)); + Assert.assertNotNull(ctx.getAttribute("output.status.message")); + } + + + } + + + @Test + public void testFlatAndAddToContextPayloadFromContext() throws Exception { + JsonDgUtilImpl jsonDgUtil = new JsonDgUtilImpl(); + String key = "payload"; + String testValueKey = "test-key"; + String testValueValue = "test-value"; + String testValueKey2 = "test-key2"; + String testValueValue2 = "test-value2"; + String payload = "{\"" + testValueKey + "\": \"" + testValueValue + "\",\""+testValueKey2+"\": \""+testValueValue2+"\"}"; + + SvcLogicContext ctx = new SvcLogicContext(); + Map<String, String> params = new HashMap<>(); + params.put(key, ""); + ctx.setAttribute("input.payload", payload); + jsonDgUtil.flatAndAddToContext(params, ctx); + + + Assert.assertEquals(ctx.getAttribute(testValueKey), testValueValue); + Assert.assertEquals(ctx.getAttribute(testValueKey2), testValueValue2); + } + + @Test + public void testFlatAndAddToContextNegativeNullPayload() throws Exception { + JsonDgUtilImpl jsonDgUtil = new JsonDgUtilImpl(); + String testValueKey = "test-key"; + String testValueKey2 = "test-key2"; + SvcLogicContext ctx = new SvcLogicContext(); + Map<String, String> params = new HashMap<>(); + jsonDgUtil.flatAndAddToContext(params, ctx); + + + Assert.assertNull(ctx.getAttribute(testValueKey)); + Assert.assertNull(ctx.getAttribute(testValueKey2)); + } + + + @Test + public void testFlatAndAddToContextNegativeEmptyPayload() throws Exception { + + JsonDgUtilImpl jsonDgUtil = new JsonDgUtilImpl(); + String key = "payload"; + String testValueKey = "test-key"; + String testValueKey2 = "test-key2"; + + SvcLogicContext ctx = new SvcLogicContext(); + Map<String, String> params = new HashMap<>(); + params.put(key, ""); + jsonDgUtil.flatAndAddToContext(params, ctx); + + Assert.assertNull(ctx.getAttribute(testValueKey)); + Assert.assertNull(ctx.getAttribute(testValueKey2)); + } +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-license-manager/.gitignore b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-license-manager/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-license-manager/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-license-manager/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-license-manager/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-license-manager/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-license-manager/pom.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-license-manager/pom.xml new file mode 100644 index 000000000..63cb7251c --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-license-manager/pom.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-shared</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-dg-license-manager</artifactId> + <packaging>bundle</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-common</artifactId> + <version>${project.version}</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-license-manager-api</artifactId> + <version>1.0.0</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>compile</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>appc-dg-license-manager</Bundle-SymbolicName> + <Export-Package>org.openecomp.appc.dg.licmgr</Export-Package> + <Export-Service>org.openecomp.appc.dg.licmgr.LicenseManagerPlugin</Export-Service> + <Private-Package>org.openecomp.appc.dg.licmgr.impl</Private-Package> + <Import-Package>org.openecomp.appc.licmgr,org.openecomp.appc.licmgr.exception,org.openecomp.appc.licmgr.objects,!org.apache.log,!org.apache.commons.logging,!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.jasypt.*,*</Import-Package> + <Embed-Dependency>appc-license-manager-api,appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-license-manager/src/main/java/org/openecomp/appc/dg/licmgr/LicenseManagerPlugin.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-license-manager/src/main/java/org/openecomp/appc/dg/licmgr/LicenseManagerPlugin.java new file mode 100644 index 000000000..6ca6b6ab5 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-license-manager/src/main/java/org/openecomp/appc/dg/licmgr/LicenseManagerPlugin.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.licmgr; + +import java.util.Map; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + + + +public interface LicenseManagerPlugin extends SvcLogicJavaPlugin { + /** + * Retrieves license model from APPC database and populate flags into svc context + * @param params map with parameters: + * org.openecomp.appc.vftype - the vnf type / service type; + * org.openecomp.appc.resource-version - the vnf version / service version + * @param ctx service logic context + * 1. supposed properties already in context: + * aai.input.data.entitlement-assignment-group-uuid - entitlement-group-uuid asset tag already stored in AAI + * aai.input.data.license-assignment-group-uuid - license-key-uuid asset tag already stored in AAI + * 2. properties and flags stored in context after bean execution: + * model.entitlement.pool.uuid - entitlement-group-uuid from license model + * model.license.key.uuid - license-key-uuid from license model + * is.acquire-entitlement.require + * is.release-entitlement.require + * is.acquire-license.require + * is.release-license.require + * + * @throws APPCException throws in case of any error + */ + void retrieveLicenseModel(Map<String, String> params, SvcLogicContext ctx) throws APPCException; +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-license-manager/src/main/java/org/openecomp/appc/dg/licmgr/impl/LicenseManagerPluginImpl.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-license-manager/src/main/java/org/openecomp/appc/dg/licmgr/impl/LicenseManagerPluginImpl.java new file mode 100644 index 000000000..536a9916e --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-license-manager/src/main/java/org/openecomp/appc/dg/licmgr/impl/LicenseManagerPluginImpl.java @@ -0,0 +1,145 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.licmgr.impl; + +import java.util.Map; + +import org.openecomp.appc.dg.licmgr.LicenseManagerPlugin; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.licmgr.Constants; +import org.openecomp.appc.licmgr.LicenseManager; +import org.openecomp.appc.licmgr.exception.DataAccessException; +import org.openecomp.appc.licmgr.objects.LicenseModel; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.SvcLogicContext; + + + +public class LicenseManagerPluginImpl implements LicenseManagerPlugin { + + private static EELFLogger logger = EELFManager.getInstance().getApplicationLogger(); + + // populated by blueprint framework + private LicenseManager licenseManager; + + public void setLicenseManager(LicenseManager licenseManager) { + this.licenseManager = licenseManager; + } + + /** + * Retrieves license model from APPC database and populate flags into svc context + * @param params map with parameters: + * org.openecomp.appc.vftype - the vnf type / service type; + * org.openecomp.appc.resource-version - the vnf version / service version + * @param ctx service logic context + * 1. supposed properties already in context: + * aai.input.data.entitlement-assignment-group-uuid - entitlement-group-uuid asset tag already stored in AAI + * aai.input.data.license-assignment-group-uuid - license-key-uuid asset tag already stored in AAI + * 2. properties and flags stored in context after bean execution: + * model.entitlement.pool.uuid - entitlement-group-uuid from license model + * model.license.key.uuid - license-key-uuid from license model + * is.acquire-entitlement.require + * is.release-entitlement.require + * is.acquire-license.require + * is.release-license.require + * is.aai-entitlement-update.require + * is.aai-license-update.require + * + * @throws APPCException throws in case of any error + */ + @Override + public void retrieveLicenseModel(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + + try { + + LicenseModel licenseModel = licenseManager.retrieveLicenseModel(params.get(Constants.VNF_TYPE_FIELD_NAME), params.get(Constants.VNF_RESOURCE_VERSION_FIELD_NAME)); + + String modelEntitlementPoolUuid = licenseModel.getEntitlementPoolUuid(); if (null == modelEntitlementPoolUuid) modelEntitlementPoolUuid = ""; + String aaiEntitlementPoolUuid = ctx.getAttribute(Constants.AAI_ENTITLMENT_POOL_UUID_NAME); if (null == aaiEntitlementPoolUuid) aaiEntitlementPoolUuid = ""; + boolean isAcquireEntitlementRequire = !modelEntitlementPoolUuid.isEmpty() && !modelEntitlementPoolUuid.equals(aaiEntitlementPoolUuid); + boolean isReleaseEntitlementRequire = !aaiEntitlementPoolUuid.isEmpty() && (isAcquireEntitlementRequire || modelEntitlementPoolUuid.isEmpty()); + boolean isAAIEntitlementUpdateRequire = isAcquireEntitlementRequire || isReleaseEntitlementRequire; + ctx.setAttribute(Constants.MODEL_ENTITLMENT_POOL_UUID_NAME, modelEntitlementPoolUuid); + ctx.setAttribute(Constants.IS_ACQUIRE_ENTITLEMENT_REQUIRE, Boolean.toString(isAcquireEntitlementRequire)); + ctx.setAttribute(Constants.IS_RELEASE_ENTITLEMENT_REQUIRE, Boolean.toString(isReleaseEntitlementRequire)); + ctx.setAttribute(Constants.IS_AAI_ENTITLEMENT_UPDATE_REQUIRE, Boolean.toString(isAAIEntitlementUpdateRequire)); + + + String modelLicenseKeyGroupUuid = licenseModel.getLicenseKeyGroupUuid(); if (null == modelLicenseKeyGroupUuid) modelLicenseKeyGroupUuid = ""; + String aaiLicenseKeyGroupUuid = ctx.getAttribute(Constants.AAI_LICENSE_KEY_UUID_NAME); if (null == aaiLicenseKeyGroupUuid) aaiLicenseKeyGroupUuid = ""; + String aaiLicenseKeyValue = ctx.getAttribute(Constants.AAI_LICENSE_KEY_VALUE); if (null == aaiLicenseKeyValue) aaiLicenseKeyValue = ""; + boolean isAcquireLicenseRequire = !modelLicenseKeyGroupUuid.isEmpty() && !modelLicenseKeyGroupUuid.equals(aaiLicenseKeyGroupUuid); + boolean isReleaseLicenseRequire = !aaiLicenseKeyGroupUuid.isEmpty() && (isAcquireLicenseRequire || modelLicenseKeyGroupUuid.isEmpty()); + boolean isAAILicenseUpdateRequire = isAcquireLicenseRequire || isReleaseLicenseRequire; + ctx.setAttribute(Constants.MODEL_LICENSE_KEY_UUID_NAME, modelLicenseKeyGroupUuid); + ctx.setAttribute(Constants.IS_ACQUIRE_LICENSE_REQUIRE, Boolean.toString(isAcquireLicenseRequire)); + ctx.setAttribute(Constants.IS_RELEASE_LICENSE_REQUIRE, Boolean.toString(isReleaseLicenseRequire)); + ctx.setAttribute(Constants.IS_AAI_LICENSE_UPDATE_REQUIRE, Boolean.toString(isAAILicenseUpdateRequire)); + + ctx.setAttribute("license-key", aaiLicenseKeyValue); + + } catch (DataAccessException le) { + logger.error("Error " + le.getMessage()); + ctx.setAttribute("output.status.message", le.getMessage()); + throw new APPCException(le); + } + + } + + + + //////// code uses jaxb license model, should be fixed + /* + final VfLicenseModel.FeatureGroupList featureGroupList = licenseModel.getFeatureGroupList(); + if (null != featureGroupList) { + final VfLicenseModel.FeatureGroupList.FeatureGroup featureGroup = featureGroupList.getFeatureGroup(); + if (null != featureGroup) { + final VfLicenseModel.FeatureGroupList.FeatureGroup.EntitlementPoolList + entitlementPoolList = featureGroup.getEntitlementPoolList(); + if (null != entitlementPoolList) { + final VfLicenseModel.FeatureGroupList.FeatureGroup.EntitlementPoolList.EntitlementPool + entitlementPool = entitlementPoolList.getEntitlementPool(); + if (null != entitlementPool) { + final String entitlementPoolUuid = entitlementPool.getEntitlementPoolUuid(); + // add entitlementPoolUuid into context + ctx.setAttribute(Constants.MODEL_ENTITLMENT_POOL_UUID_NAME, entitlementPoolUuid); + } + } + + final VfLicenseModel.FeatureGroupList.FeatureGroup.LicenseKeyGroupList + licenseKeyGroupList = featureGroup.getLicenseKeyGroupList(); + if (null != licenseKeyGroupList) { + final VfLicenseModel.FeatureGroupList.FeatureGroup.LicenseKeyGroupList.LicenseKeyGroup + licenseKeyGroup = licenseKeyGroupList.getLicenseKeyGroup(); + if (null != licenseKeyGroup) { + final String licenseKeyGroupUuid = licenseKeyGroup.getLicenseKeyGroupUuid(); + // add licenseKeyGroupUuid into context + ctx.setAttribute(Constants.MODEL_LICENSE_KEY_UUID_NAME, licenseKeyGroupUuid); + } + } + } + } + */ + + +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-license-manager/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-license-manager/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..ab2df8ba9 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-license-manager/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- + Starter Blueprint Camel Definition appc-aai-adapter-blueprint +--> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + + + <reference id="LicenseManagerRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.licmgr.LicenseManager" /> + + <bean id="LicenseManagerPluginBean" class="org.openecomp.appc.dg.licmgr.impl.LicenseManagerPluginImpl" scope="singleton"> + <property name="licenseManager" ref="LicenseManagerRef" /> + </bean> + <service id="LicenseManagerPlugin" interface="org.openecomp.appc.dg.licmgr.LicenseManagerPlugin" ref="LicenseManagerPluginBean"/> + +</blueprint> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/.gitignore b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/pom.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/pom.xml new file mode 100644 index 000000000..c9ec4d9b8 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/pom.xml @@ -0,0 +1,89 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-shared</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-dg-netconf</artifactId> + <packaging>bundle</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-netconf-adapter-bundle</artifactId> + <version>${project.version}</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-common</artifactId> + <version>${project.version}</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-mockito</artifactId> + <version>1.6.2</version> + <scope>test</scope> + + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-junit4</artifactId> + <version>1.6.2</version> + <scope>test</scope> + </dependency> + + + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>appc-dg-netconf</Bundle-SymbolicName> + <Export-Package>org.openecomp.appc.dg.netconf</Export-Package> + <Private-Package>org.openecomp.appc.dg.netconf.impl.*</Private-Package> + <Import-Package>!org.apache.log,!org.apache.commons.logging,!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.jasypt.*,*</Import-Package> + <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/java/org/openecomp/appc/dg/netconf/NetconfClientPlugin.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/java/org/openecomp/appc/dg/netconf/NetconfClientPlugin.java new file mode 100644 index 000000000..3b75f4070 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/java/org/openecomp/appc/dg/netconf/NetconfClientPlugin.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.netconf; + +import java.util.Map; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + + + +public interface NetconfClientPlugin extends SvcLogicJavaPlugin { + void configure(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + void operationStateValidation(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + void modifyConfiguration(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + void backupConfiguration(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + void getConfig(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + void getRunningConfig(Map<String, String> params, SvcLogicContext ctx) throws APPCException; +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/java/org/openecomp/appc/dg/netconf/NetconfDBPlugin.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/java/org/openecomp/appc/dg/netconf/NetconfDBPlugin.java new file mode 100644 index 000000000..a48be94c7 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/java/org/openecomp/appc/dg/netconf/NetconfDBPlugin.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.netconf; + +import java.util.Map; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + + + +public interface NetconfDBPlugin extends SvcLogicJavaPlugin { + void retrieveDSConfiguration(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + void retrieveVMDSConfiguration(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + void retrieveConfigFile(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + void retrieveConnectionDetails(Map<String, String> params, SvcLogicContext ctx) throws APPCException; +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/java/org/openecomp/appc/dg/netconf/impl/NetconfClientPluginImpl.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/java/org/openecomp/appc/dg/netconf/impl/NetconfClientPluginImpl.java new file mode 100644 index 000000000..d063b5d28 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/java/org/openecomp/appc/dg/netconf/impl/NetconfClientPluginImpl.java @@ -0,0 +1,316 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.netconf.impl; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.lang.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.openecomp.appc.adapter.netconf.*; +import org.openecomp.appc.adapter.netconf.util.Constants; +import org.openecomp.appc.dg.netconf.NetconfClientPlugin; +import org.openecomp.appc.exceptions.APPCException; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +import java.io.IOException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + + + +public class NetconfClientPluginImpl implements NetconfClientPlugin { + + private static final String NETCONF_CLIENT_FACTORY_NAME = "org.openecomp.appc.adapter.netconf.NetconfClientFactory"; + private static ObjectMapper mapper = new ObjectMapper(); + private static EELFLogger logger = EELFManager.getInstance().getApplicationLogger(); + + private NetconfDataAccessService dao; + private NetconfClientFactory clientFactory; + + public NetconfClientPluginImpl() { + BundleContext bctx = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); + ServiceReference srefNetconfClientFactory = bctx.getServiceReference(NetconfClientFactory.class); + clientFactory = (NetconfClientFactory) bctx.getService(srefNetconfClientFactory); + } + + public void setDao(NetconfDataAccessService dao) { + this.dao = dao; + this.dao.setSchema(Constants.NETCONF_SCHEMA); + } + + public void configure(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + + try { + NetconfClient client = clientFactory.GetNetconfClient(NetconfClientType.SSH); + try { + NetconfConnectionDetails connectionDetails = mapper.readValue(params.get("connection-details"), NetconfConnectionDetails.class); + String netconfMessage = params.get("file-content"); + client.connect(connectionDetails); + client.configure(netconfMessage); + } catch (IOException e) { + logger.error("Error " + e.getMessage()); + throw new APPCException(e); + } finally { + client.disconnect(); + } + } catch (Exception e) { + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage()); + logger.error("Error " + e.getMessage()); + throw e; + } + } + + @Override + public void operationStateValidation(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + if (logger.isTraceEnabled()) { + logger.trace("Entering to operationStateValidation with params = "+ ObjectUtils.toString(params)+", SvcLogicContext = "+ObjectUtils.toString(ctx)); + } + try{ + String paramName = Constants.VNF_TYPE_FIELD_NAME; + String vfType = params.get(paramName); + validateMandatoryParam(paramName, vfType); + VnfType vnfType = VnfType.getVnfType(vfType); + + paramName = Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME; + String vnfHostIpAddress = params.get(paramName); + validateMandatoryParam(paramName, vnfHostIpAddress); + + //get connectionDetails + String connectionDetailsStr = params.get(Constants.CONNECTION_DETAILS_FIELD_NAME); + NetconfConnectionDetails connectionDetails = null; + if(StringUtils.isEmpty(connectionDetailsStr)){ + connectionDetails = retrieveConnectionDetails(vnfType); + connectionDetails.setHost(vnfHostIpAddress); + ctx.setAttribute(Constants.CONNECTION_DETAILS_FIELD_NAME, mapper.writeValueAsString(connectionDetails)); + }else{ + connectionDetails = mapper.readValue(connectionDetailsStr, NetconfConnectionDetails.class); + } + if(connectionDetails == null){ + throw new IllegalStateException("missing connectionDetails for VnfType:"+vnfType.name()); + } + + //get operationsStateNetconfMessage + OperationalStateValidator operationalStateValidator = OperationalStateValidatorFactory.getOperationalStateValidator(vnfType); + String configurationFileName = operationalStateValidator.getConfigurationFileName(); + String operationsStateNetconfMessage = null; + if(!StringUtils.isEmpty(configurationFileName)){ + operationsStateNetconfMessage = retrieveConfigurationFileContent(configurationFileName); + } + + //connect checK Opertaions state and dissconnect + NetconfClient client = clientFactory.GetNetconfClient(NetconfClientType.SSH); + try { + client.connect(connectionDetails); + String response = null; + if(!StringUtils.isEmpty(operationsStateNetconfMessage)) { + response = client.exchangeMessage(operationsStateNetconfMessage); + } + operationalStateValidator.validateResponse(response); + } finally { + client.disconnect(); + } + } catch (APPCException e) { + logger.error(e.getMessage()); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.toString()); + throw e; + } + catch (Exception e) { + logger.error(e.toString()); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.toString()); + throw new APPCException(e); + } + } + + @Override + public void modifyConfiguration(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + this.configure(params, ctx); + } + + @Override + public void backupConfiguration(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + + NetconfClient client = null; + try { + if (logger.isDebugEnabled()) { + logger.debug("Entered backup to DEVICE_INTERFACE_LOG"); + } + + client = clientFactory.GetNetconfClient(NetconfClientType.SSH); + //get connection details + NetconfConnectionDetails connectionDetails = mapper.readValue(params.get("connection-details"), NetconfConnectionDetails.class); + //connect the client and get configuration + client.connect(connectionDetails); + String configuration = client.getConfiguration(); + + //store configuration in database + dao.logDeviceInteraction(null,null,getCurrentDateTime(),configuration); + + } catch (Exception e) { + logger.error("Error " + e.getMessage()); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage()); + throw new APPCException(e); + } finally { + //disconnect the client + if(client != null) { + client.disconnect(); + } + } + } + + @Override + public void getConfig(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + NetconfClient client = null; + String confId=params.get("conf-id"); + if(confId.equalsIgnoreCase("current")){ + try { + if (logger.isDebugEnabled()) { + logger.debug("Entered getConfig to DEVICE_INTERFACE_LOG"); + } + //get netconf client to get configuration + BundleContext bctx = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); + ServiceReference sref = bctx.getServiceReference(NETCONF_CLIENT_FACTORY_NAME); + NetconfClientFactory clientFactory = (NetconfClientFactory) bctx.getService(sref); + client = clientFactory.GetNetconfClient(NetconfClientType.SSH); + //get connection details + NetconfConnectionDetails connectionDetails = mapper.readValue(params.get("connection-details"), NetconfConnectionDetails.class); + //connect the client and get configuration + client.connect(connectionDetails); + String configuration = client.getConfiguration(); + if(configuration !=null){ + // logger.info("*************************************Configuration Output*************************************"); + // logger.info(configuration); + String fullConfig = ctx.getAttribute("fullConfig"); + fullConfig = fullConfig==null?"":fullConfig; + ctx.setAttribute("fullConfig",fullConfig + configuration); + + ctx.setAttribute("getConfig_Result","Success"); + String entityName=ctx.getAttribute("entity");//VM name + if(entityName!=null){ + ctx.setAttribute(entityName+".Configuration",configuration); + } + }else{ + ctx.setAttribute("getConfig_Result","failure"); + } + //store configuration in database + /*NetconfJDBC dsImpl = new NetconfJDBCImpl(); + dsImpl.logDeviceInteraction(null,null,getCurrentDateTime(),configuration);*/ + + } catch (Exception e) { + ctx.setAttribute("getConfig_Result","failure"); + logger.error("Error " + e.getMessage()); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage()); + throw new APPCException(e); + } finally { + //disconnect the client + if(client != null) { + client.disconnect(); + } + } + }else{ + logger.info("Current Conf id value is not supported"); + } + + } + + + @Override + public void getRunningConfig(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + NetconfClient client = null; + try { + logger.info("Entered getRunningConfig to DEVICE_INTERFACE_LOG"); + //get netconf client to get configuration + BundleContext bctx = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); + ServiceReference sref = bctx.getServiceReference(NETCONF_CLIENT_FACTORY_NAME); + NetconfClientFactory clientFactory = (NetconfClientFactory) bctx.getService(sref); + client = clientFactory.GetNetconfClient(NetconfClientType.SSH); + //get connection details + NetconfConnectionDetails connectionDetails = new NetconfConnectionDetails(); + connectionDetails.setHost(params.get("host-ip-address")); + connectionDetails.setUsername(params.get("user-name")); + connectionDetails.setPassword(params.get("password")); + connectionDetails.setPort(!("".equalsIgnoreCase(params.get("port-number")))?Integer.parseInt(params.get("port-number")):NetconfConnectionDetails.DEFAULT_PORT); + //connect the client and get configuration + client.connect(connectionDetails); + String configuration = client.getConfiguration(); + if(configuration !=null){ + // logger.info("*************************************Configuration Output*************************************"); + ctx.setAttribute("running-config", configuration); + + ctx.setAttribute("getRunningConfig_Result","Success"); + }else{ + ctx.setAttribute("getRunningConfig_Result","failure"); + } + } catch (Exception e) { + ctx.setAttribute("getRunningConfig_Result","failure"); + logger.error("Error " + e.getMessage()); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage()); + throw new APPCException(e); + } finally { + //disconnect the client + if(client != null) { + client.disconnect(); + } + } + } + + private String getCurrentDateTime() { + + DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + Date date = new Date(); + return dateFormat.format(date); + } + + private int getPort(String s) { + int port = 830; + if((s != null) && !s.isEmpty()) { + port = Integer.parseInt(s); + } + return port; + } + + void validateMandatoryParam(String paramName, String paramValue) { + if(StringUtils.isEmpty(paramValue)){ + throw new IllegalArgumentException("input "+paramName+" param is empty"); + } + } + + public NetconfConnectionDetails retrieveConnectionDetails( VnfType vnfType) throws APPCException{ + + NetconfConnectionDetails connectionDetails = new NetconfConnectionDetails(); + if (!dao.retrieveNetconfConnectionDetails(vnfType.getFamilyType().name(), connectionDetails)) { + logger.error("Missing configuration for " + vnfType.getFamilyType().name()); + throw new APPCException("Missing configuration for " + vnfType.getFamilyType().name() + " in " + Constants.DEVICE_AUTHENTICATION_TABLE_NAME); + } + return connectionDetails; + } + + public String retrieveConfigurationFileContent(String configFileName){ + return dao.retrieveConfigFileName(configFileName); + } + +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/java/org/openecomp/appc/dg/netconf/impl/NetconfDBPluginImpl.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/java/org/openecomp/appc/dg/netconf/impl/NetconfDBPluginImpl.java new file mode 100644 index 000000000..6fdfcc14c --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/java/org/openecomp/appc/dg/netconf/impl/NetconfDBPluginImpl.java @@ -0,0 +1,122 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.netconf.impl; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.Map; + +import org.openecomp.appc.adapter.netconf.NetconfConnectionDetails; +import org.openecomp.appc.adapter.netconf.NetconfDataAccessService; +import org.openecomp.appc.adapter.netconf.exception.DataAccessException; +import org.openecomp.appc.adapter.netconf.util.Constants; +import org.openecomp.appc.dg.netconf.NetconfDBPlugin; +import org.openecomp.appc.exceptions.APPCException; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.SvcLogicContext; + +public class NetconfDBPluginImpl implements NetconfDBPlugin { + + private static EELFLogger logger = EELFManager.getInstance().getApplicationLogger(); + private static ObjectMapper mapper = new ObjectMapper(); + + // populated by blueprint framework + private NetconfDataAccessService daoService; + + public void setDaoService(NetconfDataAccessService daoService) { + this.daoService = daoService; + this.daoService.setSchema(Constants.NETCONF_SCHEMA); + } + + public NetconfDBPluginImpl() { + } + + public void retrieveDSConfiguration(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + + try { + String fileContent = daoService.retrieveConfigFileName(params.get(Constants.CONFIGURATION_FILE_FIELD_NAME)); + ctx.setAttribute(Constants.FILE_CONTENT_FIELD_NAME, fileContent); + } catch(DataAccessException e) { + logger.error("Error " + e.getMessage()); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage()); + throw e; + } + + getConnection(params, ctx); + } + + @Override + public void retrieveVMDSConfiguration(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + logger.info("Setting entity value :" +params.get(Constants.RESOURCEKEY)); + ctx.setAttribute("entity", params.get(Constants.RESOURCEKEY)); + NetconfConnectionDetails connectionDetails = new NetconfConnectionDetails(); + try { + if (!daoService.retrieveNetconfConnectionDetails(params.get(Constants.RESOURCEKEY), connectionDetails)) { + ctx.setAttribute("retrieveVMDSConfiguration_Result","failure"); + logger.error("Missing configuration for " + params.get(Constants.VNF_TYPE_FIELD_NAME)); + throw new APPCException("Missing configuration for " + params.get(Constants.VNF_TYPE_FIELD_NAME) + " in " + Constants.DEVICE_AUTHENTICATION_TABLE_NAME); + } + // fileContent = dsImpl.retrieveConfigFileName(params.get(Constants.CONFIGURATION_FILE_FIELD_NAME)); + // ctx.setAttribute(Constants.FILE_CONTENT_FIELD_NAME, fileContent); + ctx.setAttribute(Constants.CONNECTION_DETAILS_FIELD_NAME, mapper.writeValueAsString(connectionDetails)); + ctx.setAttribute("retrieveVMDSConfiguration_Result","success"); + } catch(APPCException e) { + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage()); + throw e; + } catch(DataAccessException | JsonProcessingException e) { + logger.error("Error " + e.getMessage()); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage()); + throw new APPCException(e); + } + } + + @Override + public void retrieveConfigFile(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + String fileContent = daoService.retrieveConfigFileName(params.get(Constants.CONFIGURATION_FILE_FIELD_NAME)); + ctx.setAttribute(Constants.FILE_CONTENT_FIELD_NAME, fileContent); + } + + public void retrieveConnectionDetails(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + getConnection(params, ctx); + } + + private void getConnection(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + NetconfConnectionDetails connectionDetails = new NetconfConnectionDetails(); + try { + if (!daoService.retrieveNetconfConnectionDetails(params.get(Constants.VNF_TYPE_FIELD_NAME), connectionDetails)) { + logger.error("Missing configuration for " + params.get(Constants.VNF_TYPE_FIELD_NAME)); + throw new APPCException("Missing configuration for " + params.get(Constants.VNF_TYPE_FIELD_NAME) + " in " + Constants.DEVICE_AUTHENTICATION_TABLE_NAME); + } + connectionDetails.setHost(params.get(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME)); + ctx.setAttribute(Constants.CONNECTION_DETAILS_FIELD_NAME, mapper.writeValueAsString(connectionDetails)); + } catch(APPCException e) { + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage()); + throw e; + } catch(DataAccessException | JsonProcessingException e) { + logger.error("Error " + e.getMessage()); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage()); + throw new APPCException(e); + } + } +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..0b58ce0af --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- + Starter Blueprint Camel Definition appc-aai-adapter-blueprint +--> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + + <reference id="DataAccessServiceRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.adapter.netconf.NetconfDataAccessService" /> + + + <bean id="NetconfDBPluginBean" class="org.openecomp.appc.dg.netconf.impl.NetconfDBPluginImpl" scope="singleton"> + <property name="daoService" ref="DataAccessServiceRef" /> + </bean> + <service id="NetconfDBPlugin" interface="org.openecomp.appc.dg.netconf.NetconfDBPlugin" ref="NetconfDBPluginBean"/> + + <bean id="NetconfClientPluginBean" class="org.openecomp.appc.dg.netconf.impl.NetconfClientPluginImpl" scope="singleton"> + <property name="dao" ref="DataAccessServiceRef" /> + </bean> + <service id="NetconfClientPlugin" interface="org.openecomp.appc.dg.netconf.NetconfClientPlugin" ref="NetconfClientPluginBean"/> + +</blueprint> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/DAOServiceMock.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/DAOServiceMock.java new file mode 100644 index 000000000..38d74c300 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/DAOServiceMock.java @@ -0,0 +1,97 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.netconf.impl; + +import java.util.HashMap; + +import org.openecomp.appc.adapter.netconf.ConnectionDetails; +import org.openecomp.appc.adapter.netconf.NetconfConnectionDetails; +import org.openecomp.appc.adapter.netconf.NetconfDataAccessService; +import org.openecomp.appc.adapter.netconf.exception.DataAccessException; +import org.openecomp.sdnc.sli.resource.dblib.DbLibService; + +class DAOServiceMock implements NetconfDataAccessService { + + private String configFile; + private ConnectionDetails connection; + private HashMap<String, String> backupConf; + + @Override + public void setSchema(String schema) { + } + + @Override + public void setDbLibService(DbLibService dbLibService) { + } + + void setConfigFile(String configFile) { + this.configFile = configFile; + } + + public HashMap<String, String> getBackupConf() { + return backupConf; + } + + public void setConnection(ConnectionDetails connection) { + this.connection = connection; + } + + @Override + public String retrieveConfigFileName(String xmlID) throws DataAccessException { + if (!xmlID.equals("wrong")) { + return configFile; + } else { + throw new DataAccessException(); + } + } + + @Override + public boolean retrieveConnectionDetails(String vnfType, ConnectionDetails connectionDetails) throws + DataAccessException { + return false; + } + + @Override + public boolean retrieveNetconfConnectionDetails(String vnfType, NetconfConnectionDetails connectionDetails) throws + DataAccessException { + if (vnfType.equals("VNF")) { + connectionDetails.setHost(connection.getHost()); + connectionDetails.setPassword(connection.getPassword()); + connectionDetails.setPort(connection.getPort()); + connectionDetails.setUsername(connection.getUsername()); + + return true; + } else { + return false; + } + } + + @Override + public boolean logDeviceInteraction(String instanceId, String requestId, String creationDate, String logText) throws + DataAccessException { + this.backupConf = new HashMap<>(); + backupConf.put("creationDate", creationDate); + backupConf.put("logText", logText); + return true; + } + +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/MockOperationalStateValidatorImpl.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/MockOperationalStateValidatorImpl.java new file mode 100644 index 000000000..7109fe8e8 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/MockOperationalStateValidatorImpl.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.netconf.impl; + +import org.openecomp.appc.adapter.netconf.OperationalStateValidator; +import org.openecomp.appc.adapter.netconf.VnfType; +import org.openecomp.appc.exceptions.APPCException; + + +public class MockOperationalStateValidatorImpl implements OperationalStateValidator { + + private boolean validated; + private String configurationFileName; + + public boolean isValidated() { + return validated; + } + + @Override + public VnfType getVnfType() { + return null; + } + + @Override + public String getConfigurationFileName() { + return configurationFileName; + } + + @Override + public void validateResponse(String response) throws APPCException { + if (response.equals("wrong")) { + throw new APPCException(); + } else { + this.validated = true; + } + + } + + public void setConfigurationFileName(String configurationFileName) { + this.configurationFileName = configurationFileName; + } +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/NetconfClientFactoryMock.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/NetconfClientFactoryMock.java new file mode 100644 index 000000000..73dba9a29 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/NetconfClientFactoryMock.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.netconf.impl; + +import org.openecomp.appc.adapter.netconf.NetconfClient; +import org.openecomp.appc.adapter.netconf.NetconfClientFactory; +import org.openecomp.appc.adapter.netconf.NetconfClientType; +import org.openecomp.appc.adapter.netconf.jsch.NetconfClientJsch; +import org.openecomp.appc.adapter.netconf.odlconnector.NetconfClientRestconfImpl; + + +public class NetconfClientFactoryMock extends NetconfClientFactory { + + private final NetconfClientJschMock jschClient = new NetconfClientJschMock(); + + @Override + public NetconfClient GetNetconfClient(NetconfClientType type){ + + return jschClient; + + } +} + + diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/NetconfClientJschMock.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/NetconfClientJschMock.java new file mode 100644 index 000000000..5c01724f1 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/NetconfClientJschMock.java @@ -0,0 +1,100 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.netconf.impl; + +import org.openecomp.appc.adapter.netconf.NetconfClient; +import org.openecomp.appc.adapter.netconf.NetconfConnectionDetails; +import org.openecomp.appc.exceptions.APPCException; + + +public class NetconfClientJschMock implements NetconfClient { + + private boolean connection; + private String lastMessage; + private String answer = "answer"; + private String configuration; + private NetconfConnectionDetails lastConnectionDetails; + + public boolean isConnection() { + return connection; + } + + public String getLastMessage() { + return lastMessage; + } + + public String getAnswer() { + return answer; + } + + public String getConf() { + return configuration; + } + + public void setConf(String configuration) { + this.configuration = configuration; + } + + public void setAnswer(String answer) { + this.answer = answer; + } + + public NetconfConnectionDetails getLastConnectionDetails() { + return lastConnectionDetails; + } + + @Override + public void connect(NetconfConnectionDetails connectionDetails) throws APPCException { + this.connection = true; + this.lastConnectionDetails = connectionDetails; + + } + + @Override + public String exchangeMessage(String message) throws APPCException { + if (connection) { + this.lastMessage = message; + return answer; + } else return null; + } + + @Override + public void configure(String configuration) throws APPCException { + if (connection) { + this.configuration = configuration; + } + + } + + @Override + public String getConfiguration() throws APPCException { + if (connection) { + return configuration; + } else return null; + } + + @Override + public void disconnect() throws APPCException { + this.connection = false; + + } +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/NetconfClientPluginImplTest.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/NetconfClientPluginImplTest.java new file mode 100644 index 000000000..b3bb4858a --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/NetconfClientPluginImplTest.java @@ -0,0 +1,678 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.netconf.impl; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mockito; +import org.openecomp.appc.adapter.netconf.*; +import org.openecomp.appc.adapter.netconf.util.Constants; +import org.openecomp.appc.dg.netconf.impl.NetconfClientPluginImpl; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.lang.reflect.Field; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import static org.powermock.api.mockito.PowerMockito.when; + + + +@RunWith(PowerMockRunner.class) +@PrepareForTest({OperationalStateValidatorFactory.class, NetconfClientPluginImpl.class, FrameworkUtil.class, ObjectMapper.class}) + +public class NetconfClientPluginImplTest { + private NetconfClientPluginImpl netconfClientPlugin; + private NetconfDataAccessService dao; + private NetconfClientFactory clientFactory; + private Map<String, String> params; + + private final BundleContext bundleContext = Mockito.mock(BundleContext.class); + private final Bundle bundleService = Mockito.mock(Bundle.class); + private final ServiceReference sref1 = Mockito.mock(ServiceReference.class); + private final ServiceReference sref2 = Mockito.mock(ServiceReference.class); + private final ServiceReference sref3 = Mockito.mock(ServiceReference.class); + private static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; + + + String host = "http://www.test.com"; + String host1 = "http://www.test1.com"; + String vnfType = "VNF"; + int port = 8080; + String username = "test"; + String password = "test"; + String connectionDetails = "{\"host\":\"" + host + "\",\"port\":" + port + ",\"username\":\"" + username + "\",\"password\":\"" + password + "\",\"capabilities\":null,\"additionalProperties\":null}"; + String fileContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + + "<rpc message-id=\"101\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" + + "\t<get-config>\n" + + "\t\t<source>\n" + + "\t\t\t<running/>\n" + + "\t\t </source>\n" + + "\t</get-config>\n" + + "</rpc>'"; + String operationalState = "<rpc message-id=\"101\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" + + " <get>\n" + + " <filter>\n" + + " <ManagedElement xmlns=\"urn:org:openecomp:appc:Test\">\n" + + " <VnfFunction xmlns=\"urn:org:openecomop:appc:Test\">\n" + + " <ProcessorManagement>\n" + + " <MatedPair>\n" + + " <operationalState/>\n" + + " <PayloadProcessor>\n" + + " <operationalState/>\n" + + " </PayloadProcessor>\n" + + " </MatedPair>\n" + + " <SystemController>\n" + + " <operationalState/>\n" + + " </SystemController>\n" + + " </ProcessorManagement>\n" + + " </VnfFunction>\n" + + " </ManagedElement>\n" + + " </filter>\n" + + " </get>\n" + + "</rpc>\n"; + + + @Before + public void setUp() throws NoSuchFieldException, IllegalAccessException { + clientFactory = new NetconfClientFactoryMock(); + + } + + + @Test + public void testConfigure() throws Exception { + + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + + params = new HashMap<>(); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); + params.put(Constants.FILE_CONTENT_FIELD_NAME, fileContent); + + netconfClientPlugin.configure(params, ctx); + + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); + + try { + Assert.assertEquals("wrong configuration", fileContent, client.getConf()); + Assert.assertEquals("wrong host", host, client.getLastConnectionDetails().getHost()); + Assert.assertEquals("wrong port", port, client.getLastConnectionDetails().getPort()); + Assert.assertEquals("wrong username", username, client.getLastConnectionDetails().getUsername()); + Assert.assertEquals("wrong password", password, client.getLastConnectionDetails().getPassword()); + Assert.assertFalse(client.isConnection()); + } catch (Exception e) { + Assert.fail("failed with because of " + e.getCause()); + } + + + } + + + @Test + public void testConfigureNegativeIOException() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + + params = new HashMap<>(); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, "{" + connectionDetails); + params.put(Constants.FILE_CONTENT_FIELD_NAME, fileContent); + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); + + + try { + netconfClientPlugin.configure(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertNull(client.getLastConnectionDetails()); + Assert.assertNull(client.getConf()); + } + + } + + @Test + public void testOperationStateValidation() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + DAOServiceMock daoServiceMock = (DAOServiceMock) dao; + daoServiceMock.setConfigFile(fileContent); + + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); + client.setAnswer(operationalState); + + + params = new HashMap<>(); + params.put(Constants.VNF_TYPE_FIELD_NAME, vnfType); + params.put(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME, host1); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); + MockOperationalStateValidatorImpl validatorMock = new MockOperationalStateValidatorImpl(); + validatorMock.setConfigurationFileName("VnfGetRunningConfig"); + + PowerMockito.mockStatic(OperationalStateValidatorFactory.class); + when(OperationalStateValidatorFactory.getOperationalStateValidator(Matchers.any(VnfType.class))).thenReturn(validatorMock); + + netconfClientPlugin.operationStateValidation(params, ctx); + + Assert.assertTrue("validation process failed", validatorMock.isValidated()); + Assert.assertEquals(fileContent, client.getLastMessage()); + } + + + @Test + public void testOperationStateValidationNegativeJsonProcessingNullIllegalStateException() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + DAOServiceMock daoServiceMock = (DAOServiceMock) dao; + daoServiceMock.setConfigFile(fileContent); + + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); + client.setAnswer(operationalState); + + params = new HashMap<>(); + params.put(Constants.VNF_TYPE_FIELD_NAME, vnfType); + params.put(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME, host1); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); + MockOperationalStateValidatorImpl validatorMock = new MockOperationalStateValidatorImpl(); + validatorMock.setConfigurationFileName("VnfGetRunningConfig"); + + PowerMockito.mockStatic(OperationalStateValidatorFactory.class); + when(OperationalStateValidatorFactory.getOperationalStateValidator(Matchers.any(VnfType.class))).thenReturn(validatorMock); + substituteMapper(true); + + try { + netconfClientPlugin.operationStateValidation(params, ctx); + substituteMapper(false); + } catch (APPCException e) { + substituteMapper(false); + Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); + Assert.assertFalse(validatorMock.isValidated()); + Assert.assertNull(client.getLastMessage()); + } + } + + @Test + public void testOperationStateValidationNegativeConnectionDetailsAreNullNullPointerException() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + DAOServiceMock daoServiceMock = (DAOServiceMock) dao; + daoServiceMock.setConfigFile(fileContent); + + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); + client.setAnswer(operationalState); + + + params = new HashMap<>(); + params.put(Constants.VNF_TYPE_FIELD_NAME, vnfType); + params.put(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME, host1); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, null); + MockOperationalStateValidatorImpl validatorMock = new MockOperationalStateValidatorImpl(); + validatorMock.setConfigurationFileName("VnfGetRunningConfig"); + + PowerMockito.mockStatic(OperationalStateValidatorFactory.class); + when(OperationalStateValidatorFactory.getOperationalStateValidator(Matchers.any(VnfType.class))).thenReturn(validatorMock); + ObjectMapper mapper = PowerMockito.mock(ObjectMapper.class); + final NetconfConnectionDetails netconfConnectionDetails = null; + when(mapper.readValue(Matchers.anyString(), Matchers.any(Class.class))).thenReturn(netconfConnectionDetails); + + + try { + netconfClientPlugin.operationStateValidation(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); + Assert.assertFalse("validation process failed", validatorMock.isValidated()); + + } + } + + + @Test + public void testOperationStateValidationNegativeAppcException() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + DAOServiceMock daoServiceMock = (DAOServiceMock) dao; + daoServiceMock.setConfigFile(fileContent); + + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); + client.setAnswer("wrong"); + + + params = new HashMap<>(); + params.put(Constants.VNF_TYPE_FIELD_NAME, vnfType); + params.put(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME, host1); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); + MockOperationalStateValidatorImpl validatorMock = new MockOperationalStateValidatorImpl(); + validatorMock.setConfigurationFileName("VnfGetRunningConfig"); + + PowerMockito.mockStatic(OperationalStateValidatorFactory.class); + when(OperationalStateValidatorFactory.getOperationalStateValidator(Matchers.any(VnfType.class))).thenReturn(validatorMock); + + + try { + netconfClientPlugin.operationStateValidation(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); + Assert.assertFalse("validation process failed", validatorMock.isValidated()); + + } + } + + + @Test + public void testOperationStateValidatioConnectionDetailsInParamsAreEmpty() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + DAOServiceMock daoServiceMock = (DAOServiceMock) dao; + daoServiceMock.setConfigFile(fileContent); + + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); + client.setAnswer(operationalState); + ((DAOServiceMock) dao).setConnection(getConnectionDetails()); + + + params = new HashMap<>(); + params.put(Constants.VNF_TYPE_FIELD_NAME, vnfType); + params.put(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME, host1); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, ""); + MockOperationalStateValidatorImpl validatorMock = new MockOperationalStateValidatorImpl(); + validatorMock.setConfigurationFileName("VnfGetRunningConfig"); + + PowerMockito.mockStatic(OperationalStateValidatorFactory.class); + when(OperationalStateValidatorFactory.getOperationalStateValidator(Matchers.any(VnfType.class))).thenReturn(validatorMock); + + netconfClientPlugin.operationStateValidation(params, ctx); + + Assert.assertTrue("validation process failed", validatorMock.isValidated()); + Assert.assertEquals(fileContent, client.getLastMessage()); + } + + @Test + public void testOperationStateValidatioConnectionDetailsInParamsAreNull() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + DAOServiceMock daoServiceMock = (DAOServiceMock) dao; + daoServiceMock.setConfigFile(fileContent); + + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); + client.setAnswer(operationalState); + ((DAOServiceMock) dao).setConnection(getConnectionDetails()); + + + params = new HashMap<>(); + params.put(Constants.VNF_TYPE_FIELD_NAME, vnfType); + params.put(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME, host1); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, null); + MockOperationalStateValidatorImpl validatorMock = new MockOperationalStateValidatorImpl(); + validatorMock.setConfigurationFileName("VnfGetRunningConfig"); + + PowerMockito.mockStatic(OperationalStateValidatorFactory.class); + when(OperationalStateValidatorFactory.getOperationalStateValidator(Matchers.any(VnfType.class))).thenReturn(validatorMock); + + netconfClientPlugin.operationStateValidation(params, ctx); + + Assert.assertTrue("validation process failed", validatorMock.isValidated()); + Assert.assertEquals(fileContent, client.getLastMessage()); + } + + + @Test + public void testBackupConfiguration() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + params = new HashMap<>(); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); + client.setConf(fileContent); + netconfClientPlugin.backupConfiguration(params, ctx); + + DAOServiceMock mockdao = (DAOServiceMock) dao; + DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd"); + Date date = new Date(); + String creationDateExpected = dateFormat.format(date); + String creationDateActual = mockdao.getBackupConf().get("creationDate").substring(0, 10); + + + Assert.assertEquals("wrong configuration in db", fileContent, mockdao.getBackupConf().get("logText")); + Assert.assertEquals(creationDateExpected, creationDateActual); + + + } + + + @Test + public void testBackupConfigurationNegativeDgErrorFieldName() throws Exception { + shortInit(); + SvcLogicContext ctx = new SvcLogicContext(); + params = new HashMap<>(); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, "{" + connectionDetails); + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); + client.setConf(fileContent); + try { + netconfClientPlugin.backupConfiguration(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); + + DAOServiceMock mockdao = (DAOServiceMock) dao; + Assert.assertNull(mockdao.getBackupConf()); + } + + } + + @Test + public void testGetConfig() throws Exception { + fullInit(); + String entity = "123"; + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("entity", entity); + + params = new HashMap<>(); + params.put("conf-id", "current"); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); + client.setConf(fileContent); + + + netconfClientPlugin.getConfig(params, ctx); + + Assert.assertEquals("Success", ctx.getAttribute("getConfig_Result")); + Assert.assertEquals(fileContent, ctx.getAttribute("fullConfig")); + Assert.assertNotNull(ctx.getAttribute(entity + ".Configuration")); + Assert.assertEquals(fileContent, ctx.getAttribute(entity + ".Configuration")); + } + + + @Test + public void testGetConfigNegativeConfigurationNull() throws Exception { + fullInit(); + String entity = "123"; + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("entity", entity); + + params = new HashMap<>(); + params.put("conf-id", "current"); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); + + + netconfClientPlugin.getConfig(params, ctx); + + Assert.assertEquals("failure", ctx.getAttribute("getConfig_Result")); + Assert.assertNull(ctx.getAttribute("fullConfig")); + Assert.assertNull(ctx.getAttribute(entity + ".Configuration")); + Assert.assertNull(ctx.getAttribute(entity + ".Configuration")); + } + + + @Test + public void testGetConfigNegativeNotSupportedConfId() throws Exception { + fullInit(); + String entity = "123"; + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("entity", entity); + + params = new HashMap<>(); + params.put("conf-id", "current1"); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); + + + netconfClientPlugin.getConfig(params, ctx); + + Assert.assertNull(ctx.getAttribute("getConfig_Result")); + Assert.assertNull(ctx.getAttribute("fullConfig")); + Assert.assertNull(ctx.getAttribute(entity + ".Configuration")); + Assert.assertNull(ctx.getAttribute(entity + ".Configuration")); + } + + @Test + public void testGetConfigNegativeWronjJsonConnectionDetailsException() throws Exception { + fullInit(); + String entity = "123"; + + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("entity", entity); + + params = new HashMap<>(); + params.put("conf-id", "current"); + params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, "{" + connectionDetails); + + + try { + netconfClientPlugin.getConfig(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertEquals("failure", ctx.getAttribute("getConfig_Result")); + Assert.assertNull(ctx.getAttribute("fullConfig")); + Assert.assertNull(ctx.getAttribute(entity + ".Configuration")); + Assert.assertNull(ctx.getAttribute(entity + ".Configuration")); + Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); + } + + + } + + @Test + public void testGetRunningConfig() throws Exception { + fullInit(); + SvcLogicContext ctx = new SvcLogicContext(); + params = new HashMap<>(); + params.put("host-ip-address", host); + params.put("user-name", username); + params.put("password", password); + params.put("port-number", String.valueOf(port)); + + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); + client.setConf(fileContent); + + netconfClientPlugin.getRunningConfig(params, ctx); + + Assert.assertEquals("Success", ctx.getAttribute("getRunningConfig_Result")); + Assert.assertEquals(fileContent, ctx.getAttribute("running-config")); + Assert.assertEquals("success", ctx.getStatus()); + } + + @Test + public void testGetRunningConfigWithoutPortNumberDgErrorFieldNameException() throws Exception { + fullInit(); + SvcLogicContext ctx = new SvcLogicContext(); + params = new HashMap<>(); + params.put("host-ip-address", host); + params.put("user-name", username); + params.put("password", password); + + NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); + client.setConf(fileContent); + + try { + netconfClientPlugin.getRunningConfig(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertEquals("failure", ctx.getAttribute("getRunningConfig_Result")); + Assert.assertNull(ctx.getAttribute("running-config")); + Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); + } + + + } + + @Test + public void testGetRunningConfigNegativeConfigurationNull() throws Exception { + fullInit(); + SvcLogicContext ctx = new SvcLogicContext(); + params = new HashMap<>(); + params.put("host-ip-address", host); + params.put("user-name", username); + params.put("password", password); + params.put("port-number", String.valueOf(port)); + + netconfClientPlugin.getRunningConfig(params, ctx); + + Assert.assertEquals("failure", ctx.getAttribute("getRunningConfig_Result")); + Assert.assertNull(ctx.getAttribute("running-config")); + } + + @Test + public void testValidateMandatoryParamNegativeEmptyParamValue() throws Exception { + shortInit(); + String paramName = "test"; + String paramValue = ""; + + try { + netconfClientPlugin.validateMandatoryParam(paramName, paramValue); + Assert.assertTrue(false); + } catch (Exception e) { + Assert.assertTrue(true); + } + } + + @Test + public void testRetrieveConnectionDetails() throws Exception { + shortInit(); + DAOServiceMock daoServiceMock = (DAOServiceMock) dao; + daoServiceMock.setConfigFile(fileContent); + ConnectionDetails connectionDetails1 = getConnectionDetails(); + daoServiceMock.setConnection(connectionDetails1); + + NetconfConnectionDetails connectionDetailsActual = netconfClientPlugin.retrieveConnectionDetails(VnfType.VNF); + + + Assert.assertEquals("wrong host", connectionDetails1.getHost(), connectionDetailsActual.getHost()); + Assert.assertEquals("wrong password", connectionDetails1.getPassword(), connectionDetailsActual.getPassword()); + Assert.assertEquals("wrong port", connectionDetails1.getPort(), connectionDetailsActual.getPort()); + Assert.assertEquals("wrong usename", connectionDetails1.getUsername(), connectionDetailsActual.getUsername()); + } + + + @Test + public void testRetrieveConnectionDetailsNegativeMissingConfiguration() throws Exception { + shortInit(); + DAOServiceMock daoServiceMock = (DAOServiceMock) dao; + daoServiceMock.setConfigFile(fileContent); + ConnectionDetails connectionDetails1 = getConnectionDetails(); + daoServiceMock.setConnection(connectionDetails1); + + NetconfConnectionDetails connectionDetailsActual = null; + try { + connectionDetailsActual = netconfClientPlugin.retrieveConnectionDetails(VnfType.MOCK); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertNull(connectionDetailsActual); + } + + + } + + @Test + public void testRetrieveConfigurationFileContent() throws Exception { + shortInit(); + + DAOServiceMock daoServiceMock = (DAOServiceMock) dao; + daoServiceMock.setConfigFile(fileContent); + + Assert.assertEquals("wrong config in a database", fileContent, netconfClientPlugin.retrieveConfigurationFileContent("VnfGetRunningConfig")); + } + + private ConnectionDetails getConnectionDetails() { + + ConnectionDetails connectionDetails = new ConnectionDetails(); + connectionDetails.setPassword(password); + connectionDetails.setPort(port); + connectionDetails.setUsername(username); + connectionDetails.setHost(host); + return connectionDetails; + } + + + private void initDao() throws NoSuchFieldException, IllegalAccessException { + dao = new DAOServiceMock(); + PowerMockito.mockStatic(FrameworkUtil.class); + when(FrameworkUtil.getBundle(Matchers.any(Class.class))).thenReturn(bundleService); + when(bundleService.getBundleContext()).thenReturn(bundleContext); + when(bundleContext.getServiceReference(NetconfDataAccessService.class)).thenReturn(sref1); + when(bundleContext.getService(sref1)).thenReturn(dao); + + + } + + private void fullInit() throws NoSuchFieldException, IllegalAccessException { + initClientFactory(); + initClientFactory2(); + initDao(); + netconfClientPlugin = new NetconfClientPluginImpl(); + netconfClientPlugin.setDao(this.dao); + } + + private void shortInit() throws NoSuchFieldException, IllegalAccessException { + initClientFactory(); + initDao(); + netconfClientPlugin = new NetconfClientPluginImpl(); + netconfClientPlugin.setDao(this.dao); + } + + private void initClientFactory() throws NoSuchFieldException, IllegalAccessException { + + PowerMockito.mockStatic(FrameworkUtil.class); + when(FrameworkUtil.getBundle(Matchers.any(Class.class))).thenReturn(bundleService); + when(bundleService.getBundleContext()).thenReturn(bundleContext); + when(bundleContext.getServiceReference(NetconfClientFactory.class)).thenReturn(sref2); + when(bundleContext.getService(sref2)).thenReturn(clientFactory); + + } + + private void initClientFactory2() { + PowerMockito.mockStatic(FrameworkUtil.class); + when(FrameworkUtil.getBundle(Matchers.any(Class.class))).thenReturn(bundleService); + when(bundleService.getBundleContext()).thenReturn(bundleContext); + when(bundleContext.getServiceReference(Matchers.anyString())).thenReturn(sref3); + when(bundleContext.getService(sref3)).thenReturn(clientFactory); + } + + private void substituteMapper(boolean command) throws NoSuchFieldException, IllegalAccessException { + ObjectMapper mapper = new ObjectMapperMock(); + ObjectMapper mapper2 = new ObjectMapper(); + Field field = NetconfClientPluginImpl.class.getDeclaredField("mapper"); + field.setAccessible(true); + if (command) { + field.set(netconfClientPlugin, mapper); + } else { + field.set(netconfClientPlugin, mapper2); + } + } + +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/NetconfDBPluginImplTest.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/NetconfDBPluginImplTest.java new file mode 100644 index 000000000..a591648c4 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/NetconfDBPluginImplTest.java @@ -0,0 +1,250 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.netconf.impl; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.*; +import org.openecomp.appc.adapter.netconf.ConnectionDetails; +import org.openecomp.appc.adapter.netconf.NetconfConnectionDetails; +import org.openecomp.appc.adapter.netconf.NetconfDataAccessService; +import org.openecomp.appc.adapter.netconf.exception.DataAccessException; +import org.openecomp.appc.dg.netconf.impl.NetconfDBPluginImpl; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +import static org.powermock.api.support.SuppressCode.suppressConstructor; + +public class NetconfDBPluginImplTest { + private NetconfDBPluginImpl netconfDBPlugin; + private NetconfDataAccessService daoService; + private DAOServiceMock daoMock; + private Map<String, String> params; + private static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; + String host = "http://www.test.com"; + String host1 = "http://www.test1.com"; + int port = 8080; + String username = "test"; + String password = "test"; + String configContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + + "<rpc message-id=\"101\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" + + "\t<get-config>\n" + + "\t\t<source>\n" + + "\t\t\t<running/>\n" + + "\t\t </source>\n" + + "\t</get-config>\n" + + "</rpc>'"; + + + @Test + public void testRetrieveDSConfiguration() throws Exception { + init(); + params = new HashMap<>(); + params.put("org.openecomp.appc.vftype", "VNF"); + params.put("configuration-file-name", "VnfGetRunningConfig"); + SvcLogicContext ctx = new SvcLogicContext(); + netconfDBPlugin.retrieveDSConfiguration(params, ctx); + + Assert.assertEquals("lack of success of status", "success", ctx.getStatus()); + Assert.assertEquals("wrong config file content", configContent, ctx.getAttribute("file-content")); + } + + + @Test + public void testRetrieveDSConfigurationNegativeErrorFieldNameDaoException() throws Exception { + init(); + SvcLogicContext ctx = new SvcLogicContext(); + params = new HashMap<>(); + params.put("configuration-file-name", "wrong"); + + try { + netconfDBPlugin.retrieveDSConfiguration(params, ctx); + } catch (DataAccessException e) { + //Assert.assertNotNull(ctx.getAttribute("org.openecomp.appc.dg.error")); + Assert.assertNull(ctx.getAttribute("file-content")); + } + + + } + + @Test + public void testRetrieveVMDSConfiguration() throws Exception { + init(); + params = new HashMap<>(); + params.put("resourceKey", "VNF"); + SvcLogicContext ctx = new SvcLogicContext(); + netconfDBPlugin.retrieveVMDSConfiguration(params, ctx); + + Assert.assertEquals("lack of success of retrieveVMDSConfiguration_Result", "success", ctx.getAttribute("retrieveVMDSConfiguration_Result")); + Assert.assertEquals("wrong entity", "VNF", ctx.getAttribute("entity")); + assertConnectionDetails(ctx, host); + } + + @Test + public void testRetrieveVMDSConfigurationNegativeMissingConfiguration() throws Exception { + init(); + SvcLogicContext ctx = new SvcLogicContext(); + params = new HashMap<>(); + params.put("resourceKey", "MOCK"); + + try { + netconfDBPlugin.retrieveVMDSConfiguration(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + + Assert.assertEquals("failure", ctx.getAttribute("retrieveVMDSConfiguration_Result")); + } + } + + + @Test + public void testRetrieveVMDSConfigurationNegativeJsonProcessingException() throws Exception { + + SvcLogicContext ctx = new SvcLogicContext(); + params = new HashMap<>(); + params.put("resourceKey", "VNF"); + + init(); + substituteMapper(true); + try { + netconfDBPlugin.retrieveVMDSConfiguration(params, ctx); + substituteMapper(false); + Assert.assertTrue(false); + + } catch (APPCException e) { + substituteMapper(false); + Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); + + } + + } + + @Test + public void testRetrieveConfigFile() throws Exception { + init(); + SvcLogicContext ctx = new SvcLogicContext(); + params = new HashMap<>(); + params.put("configuration-file-name", "VnfGetRunningConfig"); + netconfDBPlugin.retrieveConfigFile(params, ctx); + + Assert.assertEquals("lack of success of status", "success", ctx.getStatus()); + Assert.assertEquals("wrong config file content", configContent, ctx.getAttribute("file-content")); + } + + @Test + public void testRetrieveConnectionDetails() throws Exception { + init(); + params = new HashMap<>(); + params.put("org.openecomp.appc.vftype", "VNF"); + params.put("vnf-host-ip-address", host1); + SvcLogicContext ctx = new SvcLogicContext(); + netconfDBPlugin.retrieveConnectionDetails(params, ctx); + + assertConnectionDetails(ctx, host1); + } + + @Test + public void testRetrieveConnectionDetailsNegativeJsonProcessingException() throws Exception { + init(); + params = new HashMap<>(); + params.put("org.openecomp.appc.vftype", "MOCK"); + params.put("vnf-host-ip-address", host1); + SvcLogicContext ctx = new SvcLogicContext(); + + try { + netconfDBPlugin.retrieveConnectionDetails(params, ctx); + Assert.assertTrue(false); + } catch (APPCException e) { + Assert.assertNull(ctx.getAttribute("connection-details")); + Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); + } + + } + + + @Test + public void testRetrieveConnectionDetailsNegativeMissingConfiguration() throws Exception { + init(); + params = new HashMap<>(); + params.put("org.openecomp.appc.vftype", "VNF"); + params.put("vnf-host-ip-address", host1); + SvcLogicContext ctx = new SvcLogicContext(); + substituteMapper(true); + + try { + netconfDBPlugin.retrieveConnectionDetails(params, ctx); + substituteMapper(false); + Assert.assertTrue(false); + } catch (APPCException e) { + substituteMapper(false); + Assert.assertNull(ctx.getAttribute("connection-details")); + Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); + } + + } + + private void assertConnectionDetails(SvcLogicContext ctx, String host) throws IOException { + String sConnectionDetails = ctx.getAttribute("connection-details"); + NetconfConnectionDetails connectionDetails = new ObjectMapper().readValue(sConnectionDetails, NetconfConnectionDetails.class); + Assert.assertEquals(host, connectionDetails.getHost()); + Assert.assertEquals(port, connectionDetails.getPort()); + Assert.assertEquals(username, connectionDetails.getUsername()); + Assert.assertEquals(password, connectionDetails.getPassword()); + Assert.assertNull(connectionDetails.getCapabilities()); + Assert.assertNull(connectionDetails.getAdditionalProperties()); + } + + private void init() { + netconfDBPlugin = new NetconfDBPluginImpl(); + daoService = new DAOServiceMock(); + netconfDBPlugin.setDaoService(daoService); + daoMock = (DAOServiceMock) daoService; + daoMock.setConfigFile(configContent); + daoMock.setConnection(getConnectionDetails()); + + } + + private ConnectionDetails getConnectionDetails() { + ConnectionDetails connectionDetails = new ConnectionDetails(); + connectionDetails.setHost(host); + connectionDetails.setUsername(username); + connectionDetails.setPort(port); + connectionDetails.setPassword(password); + return connectionDetails; + } + + private void substituteMapper(boolean command) throws NoSuchFieldException, IllegalAccessException { + ObjectMapper mapper = new ObjectMapperMock(); + ObjectMapper mapper2 = new ObjectMapper(); + Field field = NetconfDBPluginImpl.class.getDeclaredField("mapper"); + field.setAccessible(true); + if (command) { + field.set(netconfDBPlugin, mapper); + } else { + field.set(netconfDBPlugin, mapper2); + } + } +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/ObjectMapperMock.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/ObjectMapperMock.java new file mode 100644 index 000000000..6a7da63ee --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/ObjectMapperMock.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.netconf.impl; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; + + +public class ObjectMapperMock extends ObjectMapper { + + @Override + public String writeValueAsString(Object var1) throws JsonProcessingException { + throw new JsonProcessingException("") { + }; + + } + + @Override + public <T> T readValue(String var1, Class<T> var2) throws IOException, JsonParseException, JsonMappingException { + return null; + } +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/OperationStateValidatorFactoryMock.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/OperationStateValidatorFactoryMock.java new file mode 100644 index 000000000..1dea8eb86 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/OperationStateValidatorFactoryMock.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.netconf.impl; + +import org.apache.commons.lang3.NotImplementedException; +import org.openecomp.appc.adapter.netconf.*; + + +public class OperationStateValidatorFactoryMock extends OperationalStateValidatorFactory { + public static OperationalStateValidator getOperationalStateValidator(String vnfType) { + VnfType vnfTypeEnum = null; + try { + vnfTypeEnum = VnfType.getVnfType(vnfType); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Illegal value in vnfType. vnfType=" + vnfType, e); + } + return getOperationalStateValidator(vnfTypeEnum); + } + + public static OperationalStateValidator getOperationalStateValidator(VnfType vnfType) { + + return new MockOperationalStateValidatorImpl(); + + + } + + +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-features/.gitignore b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-features/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-features/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-features/pom.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-features/pom.xml new file mode 100644 index 000000000..edaecc2b8 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-features/pom.xml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-shared</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-dg-shared-features</artifactId> + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-ssh</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-netconf</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-aai</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-license-manager</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-common</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-features/src/main/resources/features.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-features/src/main/resources/features.xml new file mode 100644 index 000000000..3271f7ab8 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-features/src/main/resources/features.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="appc-dg-shared-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + <repository>mvn:org.openecomp.appc/appc-ssh-adapter-features/${project.version}/xml/features</repository> + <repository>mvn:org.openecomp.appc/appc-netconf-adapter-features/${project.version}/xml/features</repository> + <feature name='appc-dg-shared' description="appc-dg-shared" version='${project.version}'> + <feature version='${project.version}'>appc-ssh-adapter</feature> + <feature version='${project.version}'>appc-netconf-adapter</feature> + <bundle>mvn:org.openecomp.appc/appc-dg-common/${project.version}</bundle> + <bundle>mvn:org.openecomp.appc/appc-dg-ssh/${project.version}</bundle> + <bundle start-level="85" start="true">mvn:org.openecomp.appc/appc-dg-netconf/${project.version}</bundle> + <bundle>mvn:org.openecomp.appc/appc-dg-license-manager/${project.version}</bundle> + <bundle start-level="85" start="true">mvn:org.openecomp.appc/appc-dg-aai/${project.version}</bundle> + </feature> +</features> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-installer/.gitignore b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-installer/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-installer/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-installer/pom.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-installer/pom.xml new file mode 100644 index 000000000..0a00e4a08 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-installer/pom.xml @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-shared</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-dg-shared-installer</artifactId> + <name>APPC DG Shared - Karaf Installer</name> + <packaging>pom</packaging> + + <properties> + <application.name>appc-dg-shared</application.name> + <features.boot>appc-dg-shared</features.boot> + <features.repositories>mvn:org.openecomp.appc/appc-dg-shared-features/${project.version}/xml/features</features.repositories> + </properties> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-shared-features</artifactId> + <version>${project.version}</version> + <classifier>features</classifier> + <type>xml</type> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-ssh-adapter-features</artifactId> + <version>${project.version}</version> + <classifier>features</classifier> + <type>xml</type> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-netconf-adapter-features</artifactId> + <version>${project.version}</version> + <classifier>features</classifier> + <type>xml</type> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>mavne-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>false</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>true</attach> + <finalName>${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <excludeGroupIds>org.opendaylight</excludeGroupIds> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals> + <!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-installer/src/assembly/assemble_installer_zip.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..9fbaad8c5 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>adapter</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-installer/src/assembly/assemble_mvnrepo_zip.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..1ac5a82bc --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,47 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>adapter</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + +</assembly> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-installer/src/main/resources/etc/org.apache.cxf.osgi.cfg b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-installer/src/main/resources/etc/org.apache.cxf.osgi.cfg new file mode 100644 index 000000000..7ea1088a7 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-installer/src/main/resources/etc/org.apache.cxf.osgi.cfg @@ -0,0 +1 @@ +org.apache.cxf.servlet.context=/actions
\ No newline at end of file diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-installer/src/main/resources/scripts/install-feature.sh b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..1d769fada --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-shared-installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,40 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +#!/bin/bash + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -n -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/.gitignore b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/pom.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/pom.xml new file mode 100644 index 000000000..8a4315503 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/pom.xml @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-shared</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-dg-ssh</artifactId> + <packaging>bundle</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-ssh-adapter-api</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-common</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-ssh-adapter-tests</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>appc-dg-ssh</Bundle-SymbolicName> + <Export-Package>org.openecomp.appc.dg.ssh</Export-Package> + <Private-Package>org.openecomp.appc.dg.ssh.impl.*</Private-Package> + <Import-Package>!org.apache.log,!org.apache.commons.logging,!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.jasypt.*,*</Import-Package> + <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/java/org/openecomp/appc/dg/ssh/SshDBPlugin.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/java/org/openecomp/appc/dg/ssh/SshDBPlugin.java new file mode 100644 index 000000000..71569bc7b --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/java/org/openecomp/appc/dg/ssh/SshDBPlugin.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.ssh; + +import java.util.Map; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + +public interface SshDBPlugin extends SvcLogicJavaPlugin { + void retrieveConnectionDetails(Map<String, String> params, SvcLogicContext ctx) throws APPCException; +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/java/org/openecomp/appc/dg/ssh/SshService.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/java/org/openecomp/appc/dg/ssh/SshService.java new file mode 100644 index 000000000..0d2927ec3 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/java/org/openecomp/appc/dg/ssh/SshService.java @@ -0,0 +1,106 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.ssh; + +import java.util.Map; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + +/** + * Set of common methods that can be called from DG. + */ +public interface SshService extends SvcLogicJavaPlugin { + + /** + * Input parameter for SHH connection details + */ + String PARAM_IN_connection_details = "connection_details"; + + /** + * Input parameter for SSH command to be executed. + */ + String PARAM_IN_command = "command"; + + /* + String PARAM_IN_host = "host"; + String PARAM_IN_port = "port"; + String PARAM_IN_username = "username"; + String PARAM_IN_password = "password"; + */ + + /** + * Input parameter for SSH command timeout + */ + String PARAM_IN_timeout = "timeout"; + + /** + * Output parameter - SSH command execution status. + */ + String PARAM_OUT_status = "status"; + + /** + * Output parameter - content of SSH command stdout. + */ + String PARAM_OUT_stdout = "stdout"; + + /** + * Output parameter - content of SSH command stderr. + */ + String PARAM_OUT_stderr = "stderr"; + + /** + * Default SSH connection port. + */ + int DEF_port = 22; + + /** + * Default SSH command timeout + */ + long DEF_timeout = 120000; + + /** + * Default success status. + */ + int DEF_SUCCESS_STATUS = 0; + + /** + * Execute remote command over SSH. + * + * @param params contains list of input parameters required for the implementation + * @param ctx SLI service logic context + * @throws APPCException + */ + void exec(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + /** + * Execute remote command over SSH and check return status assuming that success status is 0. + * If non-zero status is returned - fail the execution by throwing exception with content written + * by command to stderr. + * + * @param params contains list of input parameters required for the implementation + * @param ctx SLI service logic context + * @throws APPCException + */ + void execWithStatusCheck(Map<String, String> params, SvcLogicContext ctx) throws APPCException; +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/java/org/openecomp/appc/dg/ssh/impl/SshDBPluginImpl.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/java/org/openecomp/appc/dg/ssh/impl/SshDBPluginImpl.java new file mode 100644 index 000000000..382d41894 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/java/org/openecomp/appc/dg/ssh/impl/SshDBPluginImpl.java @@ -0,0 +1,74 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.ssh.impl; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.Map; + +import org.openecomp.appc.adapter.ssh.Constants; +import org.openecomp.appc.adapter.ssh.SshConnectionDetails; +import org.openecomp.appc.adapter.ssh.SshDataAccessException; +import org.openecomp.appc.adapter.ssh.SshDataAccessService; +import org.openecomp.appc.dg.ssh.SshDBPlugin; +import org.openecomp.appc.exceptions.APPCException; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.SvcLogicContext; + +public class SshDBPluginImpl implements SshDBPlugin { + + private static EELFLogger logger = EELFManager.getInstance().getApplicationLogger(); + private static ObjectMapper mapper = new ObjectMapper(); + + private SshDataAccessService dataAccessService; + + public void setDataAccessService(SshDataAccessService dataAccessService) { + this.dataAccessService = dataAccessService; + } + + public void retrieveConnectionDetails(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + SshConnectionDetails connectionDetails = new SshConnectionDetails(); + String vnfType = ctx.getAttribute("aai.prefix")+"."+"vnf-type"; + try { + if (!dataAccessService.retrieveConnectionDetails(ctx.getAttribute(vnfType), connectionDetails)) { + logger.error("Missing configuration for " + params.get(vnfType)); + throw new APPCException("Missing configuration for " + params.get(vnfType) + " in " + Constants.DEVICE_AUTHENTICATION_TABLE_NAME); + } + connectionDetails.setHost(params.get(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME)); + ctx.setAttribute(Constants.CONNECTION_DETAILS_FIELD_NAME, mapper.writeValueAsString(connectionDetails)); + } catch(APPCException e) { + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage()); + throw e; + } catch(SshDataAccessException e) { + logger.error("Error " + e.getMessage()); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage()); + throw e; + } catch (JsonProcessingException e) { + logger.error("Error " + e.getMessage()); + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage()); + throw new APPCException(e); + } + } + +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/java/org/openecomp/appc/dg/ssh/impl/SshServiceImpl.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/java/org/openecomp/appc/dg/ssh/impl/SshServiceImpl.java new file mode 100644 index 000000000..5066f0a6f --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/java/org/openecomp/appc/dg/ssh/impl/SshServiceImpl.java @@ -0,0 +1,106 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.ssh.impl; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Map; + +import org.openecomp.appc.adapter.ssh.SshAdapter; +import org.openecomp.appc.adapter.ssh.SshConnection; +import org.openecomp.appc.adapter.ssh.SshConnectionDetails; +import org.openecomp.appc.dg.ssh.SshService; +import org.openecomp.appc.exceptions.APPCException; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.SvcLogicContext; + + +public class SshServiceImpl implements SshService { + + private static final EELFLogger logger = EELFManager.getInstance().getApplicationLogger(); + private static final ObjectMapper mapper = new ObjectMapper(); + + private SshAdapter sshAdapter; + + public void setSshAdapter(SshAdapter sshAdapter) { + this.sshAdapter = sshAdapter; + } + + @Override + public void exec(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + SshConnectionDetails connectionDetails = resolveConnectionDetails(params.get(PARAM_IN_connection_details)); + String command = params.get(PARAM_IN_command); + logger.debug("=> Connecting to SSH server..."); + SshConnection sshConnection = sshAdapter.getConnection(connectionDetails.getHost(), connectionDetails.getPort(), connectionDetails.getUsername(), connectionDetails.getPassword()); + sshConnection.connect(); + try { + logger.debug("=> Connected to SSH server..."); + logger.debug("=> Running SSH command..."); + long timeout = DEF_timeout; + String stimeout = params.get(PARAM_IN_timeout); + if ((stimeout != null && !stimeout.isEmpty())) { + timeout = Long.parseLong(stimeout); + } + sshConnection.setExecTimeout(timeout); + ByteArrayOutputStream stdout = new ByteArrayOutputStream(); + ByteArrayOutputStream stderr = new ByteArrayOutputStream(); + int status = sshConnection.execCommand(command, stdout, stderr); + String stdoutRes = stdout.toString(); + String stderrRes = stderr.toString(); + logger.debug("=> executed SSH command"); + ctx.setAttribute(PARAM_OUT_status, String.format("%01d", status)); + ctx.setAttribute(PARAM_OUT_stdout, stdoutRes); + ctx.setAttribute(PARAM_OUT_stderr, stderrRes); + } finally { + sshConnection.disconnect(); + } + } + + private SshConnectionDetails resolveConnectionDetails(String connectionDetailsStr) throws APPCException { + SshConnectionDetails connectionDetails = null; + try { + connectionDetails = mapper.readValue(connectionDetailsStr, SshConnectionDetails.class); + if (0 == connectionDetails.getPort()) connectionDetails.setPort(DEF_port); + } catch (IOException e) { + throw new APPCException(e); + } + return connectionDetails; + } + + @Override + public void execWithStatusCheck(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + exec(params, ctx); + int status = Integer.parseInt(ctx.getAttribute(PARAM_OUT_status)); + if(status != DEF_SUCCESS_STATUS) { + StringBuilder errmsg = new StringBuilder(); + errmsg.append("SSH command returned error status [").append(status).append(']'); + String stderr = ctx.getAttribute(PARAM_OUT_stderr); + if((stderr != null) && !stderr.isEmpty()) { + errmsg.append(". Error: [").append(stderr).append(']'); + } + throw new APPCException(errmsg.toString()); + } + } +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..11ab24025 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- + Starter Blueprint Camel Definition appc-aai-adapter-blueprint +--> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + + <reference id="sshAdapterRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.adapter.ssh.SshAdapter" /> + <bean id="sshServiceBean" class="org.openecomp.appc.dg.ssh.impl.SshServiceImpl" scope="singleton"> + <property name="sshAdapter" ref="sshAdapterRef" /> + </bean> + <service id="sshService" interface="org.openecomp.appc.dg.ssh.SshService" ref="sshServiceBean"/> + + <reference id="sshDAServiceRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.adapter.ssh.SshDataAccessService" /> + <bean id="sshDBPluginBean" class="org.openecomp.appc.dg.ssh.impl.SshDBPluginImpl" scope="singleton"> + <property name="dataAccessService" ref="sshDAServiceRef" /> + </bean> + <service id="sshDBPlugin" interface="org.openecomp.appc.dg.ssh.SshDBPlugin" ref="sshDBPluginBean"/> + +</blueprint> diff --git a/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/src/test/java/org/openecomp/appc/dg/ssh/impl/SshServiceImplTest.java b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/src/test/java/org/openecomp/appc/dg/ssh/impl/SshServiceImplTest.java new file mode 100644 index 000000000..a00d21100 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/appc-dg-ssh/src/test/java/org/openecomp/appc/dg/ssh/impl/SshServiceImplTest.java @@ -0,0 +1,170 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dg.ssh.impl; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.hamcrest.CoreMatchers; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.openecomp.appc.adapter.ssh.SshAdapterMock; +import org.openecomp.appc.adapter.ssh.SshConnectionDetails; +import org.openecomp.appc.adapter.ssh.SshConnectionMock; +import org.openecomp.appc.dg.ssh.SshService; +import org.openecomp.appc.dg.ssh.impl.SshServiceImpl; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +public class SshServiceImplTest { + + private static final ObjectMapper mapper = new ObjectMapper(); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testExec() throws APPCException, JsonProcessingException { + String host = "testhost"; + String username = "testuser"; + String password = "testpassword"; + String command = "cat keystonerc_Test"; + + SshServiceImpl sshService = new SshServiceImpl(); + SshAdapterMock sshAdapterMock = new SshAdapterMock(); + sshService.setSshAdapter(sshAdapterMock); + + System.out.println("=> Executing SSH command [" + command + "]..."); + + Map<String, String> params = new HashMap<>(); + params.put(SshService.PARAM_IN_connection_details, createConnectionDetails(host,username,password)); + params.put(SshService.PARAM_IN_command, command); + SvcLogicContext svcLogicContext = new SvcLogicContext(new Properties()); + sshService.exec(params, svcLogicContext); + int status = Integer.parseInt(svcLogicContext.getAttribute(SshService.PARAM_OUT_status)); + String stdout = svcLogicContext.getAttribute(SshService.PARAM_OUT_stdout); + String stderr = svcLogicContext.getAttribute(SshService.PARAM_OUT_stderr); + System.out.println("=> SSH command [" + command + "] status is [" + status + "]. stdout is [" + stdout + "]. stderr is [" + stderr + "]"); + + List<SshConnectionMock> connectionMocks = sshAdapterMock.getConnectionMocks(); + Assert.assertEquals(1, connectionMocks.size()); + SshConnectionMock connectionMock = connectionMocks.get(0); + Assert.assertNotNull(connectionMock); + Assert.assertEquals(host, connectionMock.getHost()); + Assert.assertEquals(SshService.DEF_port, connectionMock.getPort()); + Assert.assertEquals(username, connectionMock.getUsername()); + Assert.assertEquals(password, connectionMock.getPassword()); + Assert.assertEquals(1, connectionMock.getConnectCallCount()); + Assert.assertEquals(1, connectionMock.getDisconnectCallCount()); + List<String> executedCommands = connectionMock.getExecutedCommands(); + Assert.assertEquals(1, executedCommands.size()); + String executedCommand = executedCommands.get(0); + Assert.assertEquals(command, executedCommand); + } + + @Test + public void testExecWithStatusCheck() throws APPCException, JsonProcessingException { + String host = "testhost"; + String username = "testuser"; + String password = "testpassword"; + String command = "cat keystonerc_Test"; + + SshServiceImpl sshService = new SshServiceImpl(); + SshAdapterMock sshAdapterMock = new SshAdapterMock(); + sshService.setSshAdapter(sshAdapterMock); + + System.out.println("=> Executing SSH command [" + command + "]..."); + Map<String, String> params = new HashMap<>(); + params.put(SshService.PARAM_IN_connection_details, createConnectionDetails(host,username,password)); + params.put(SshService.PARAM_IN_command, command); + SvcLogicContext svcLogicContext = new SvcLogicContext(new Properties()); + sshService.execWithStatusCheck(params, svcLogicContext); + int status = Integer.parseInt(svcLogicContext.getAttribute(SshService.PARAM_OUT_status)); + String stdout = svcLogicContext.getAttribute(SshService.PARAM_OUT_stdout); + String stderr = svcLogicContext.getAttribute(SshService.PARAM_OUT_stderr); + System.out.println("=> SSH command [" + command + "] status is [" + status + "]. stdout is [" + stdout + "]. stderr is [" + stderr + "]"); + + List<SshConnectionMock> connectionMocks = sshAdapterMock.getConnectionMocks(); + Assert.assertEquals(1, connectionMocks.size()); + SshConnectionMock connectionMock = connectionMocks.get(0); + Assert.assertNotNull(connectionMock); + Assert.assertEquals(host, connectionMock.getHost()); + Assert.assertEquals(SshService.DEF_port, connectionMock.getPort()); + Assert.assertEquals(username, connectionMock.getUsername()); + Assert.assertEquals(password, connectionMock.getPassword()); + Assert.assertEquals(1, connectionMock.getConnectCallCount()); + Assert.assertEquals(1, connectionMock.getDisconnectCallCount()); + List<String> executedCommands = connectionMock.getExecutedCommands(); + Assert.assertEquals(1, executedCommands.size()); + String executedCommand = executedCommands.get(0); + Assert.assertEquals(command, executedCommand); + } + + /** + * Checks that execWithStatusCheck() throws appropriate exception if execution status != 0. + * + * @throws APPCException + * @throws JsonProcessingException + */ + @Test + public void testExecWithStatusCheckFail() throws APPCException, JsonProcessingException { + String host = "testhost"; + String username = "testuser"; + String password = "testpassword"; + String command = "cat keystonerc_Test"; + + int expectedStatus = 2; + String expectedErr = "Test failure"; + + SshServiceImpl sshService = new SshServiceImpl(); + SshAdapterMock sshAdapterMock = new SshAdapterMock(); + sshAdapterMock.setReturnStatus(expectedStatus); + sshAdapterMock.setReturnStderr(expectedErr); + sshService.setSshAdapter(sshAdapterMock); + + thrown.expect(APPCException.class); + thrown.expectMessage(CoreMatchers.containsString(expectedErr)); + + System.out.println("=> Executing SSH command [" + command + "]..."); + Map<String, String> params = new HashMap<>(); + params.put(SshService.PARAM_IN_connection_details, createConnectionDetails(host,username,password)); + params.put(SshService.PARAM_IN_command, command); + SvcLogicContext svcLogicContext = new SvcLogicContext(new Properties()); + // should fail, no need to perform further assertions + sshService.execWithStatusCheck(params, svcLogicContext); + } + + private String createConnectionDetails(String host, String username, String password) throws JsonProcessingException { + SshConnectionDetails connDetails = new SshConnectionDetails(); + connDetails.setHost(host); + connDetails.setUsername(username); + connDetails.setPassword(password); + return mapper.writeValueAsString(connDetails); + } + +} diff --git a/app-c/appc/appc-dg/appc-dg-shared/pom.xml b/app-c/appc/appc-dg/appc-dg-shared/pom.xml new file mode 100644 index 000000000..f2058bfb2 --- /dev/null +++ b/app-c/appc/appc-dg/appc-dg-shared/pom.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-dg-shared</artifactId> + <packaging>pom</packaging> + + <modules> + <module>appc-dg-common</module> + <module>appc-dg-ssh</module> + <module>appc-dg-aai</module> + <module>appc-dg-netconf</module> + <module>appc-dg-license-manager</module> + <module>appc-dg-shared-features</module> + <module>appc-dg-shared-installer</module> + </modules> +</project> diff --git a/app-c/appc/appc-dg/pom.xml b/app-c/appc/appc-dg/pom.xml new file mode 100644 index 000000000..f0748db89 --- /dev/null +++ b/app-c/appc/appc-dg/pom.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <parent> + <artifactId>appc</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>appc-dg</artifactId> + <packaging>pom</packaging> + + <modules> + <module>appc-dg-shared</module> + </modules> +</project> diff --git a/app-c/appc/appc-dispatcher/.gitignore b/app-c/appc/appc-dispatcher/.gitignore new file mode 100644 index 000000000..09e3bc9b2 --- /dev/null +++ b/app-c/appc/appc-dispatcher/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/app-c/appc/appc-dispatcher/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/.gitignore b/app-c/appc/appc-dispatcher/appc-command-executor/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-command-executor/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/.gitignore b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/pom.xml b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/pom.xml new file mode 100644 index 000000000..645f0b630 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/pom.xml @@ -0,0 +1,60 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-command-executor</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-command-executor-api</artifactId> + <packaging>bundle</packaging> + + <name>appc-command-executor-api</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>execution-queue-management-lib</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>domain-model-lib</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <!--<dependency>--> + <!--<groupId>org.apache.commons</groupId>--> + <!--<artifactId>commons-lang3</artifactId>--> + <!--<version>3.4</version>--> + <!--<scope>provided</scope>--> + <!--<type>bundle</type>--> + <!--</dependency>--> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Export-Package>org.openecomp.appc.executor,org.openecomp.appc.executor.objects,org.openecomp.appc.executor.conv,org.openecomp.appc.executor.helper</Export-Package> + <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic,javax.json;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Import-Package>!groovy.lang,!javax.*,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/CommandExecutor.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/CommandExecutor.java new file mode 100644 index 000000000..ac5223b93 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/CommandExecutor.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +/** + * + */ +package org.openecomp.appc.executor; + + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.executor.objects.CommandExecutorInput; + + + +public interface CommandExecutor { + /** + * Execute given command + * Create command request and enqueue it for execution. + * @param commandHeaderInput Contains CommandHeader, command , target Id , payload and conf ID (optional) + * @throws APPCException in case of error. + */ + void executeCommand(CommandExecutorInput commandHeaderInput) throws APPCException; +} diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/UnstableVNFException.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/UnstableVNFException.java new file mode 100644 index 000000000..3727cdb40 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/UnstableVNFException.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executor; + + +public class UnstableVNFException extends Exception{ + public UnstableVNFException(String message){ + super(message); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/conv/Converter.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/conv/Converter.java new file mode 100644 index 000000000..a9991e43e --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/conv/Converter.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executor.conv; + +import java.io.IOException; + +import org.openecomp.appc.executor.objects.Params; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + + +public class Converter { + + public static Params convJsonStringToParams(String inObj) throws IOException { + Params outObj = null; + if(inObj != null) { + outObj = new ObjectMapper().readValue(inObj, Params.class); + } + return outObj; + } + + public static String convParamsToJsonString(Params inObj) throws JsonProcessingException { + String outObj = null; + if(inObj != null) { + outObj = new ObjectMapper().writeValueAsString(inObj); + } + return outObj; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/CommandExecutorInput.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/CommandExecutorInput.java new file mode 100644 index 000000000..4cb5f1b99 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/CommandExecutorInput.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executor.objects; + +import org.openecomp.appc.domainmodel.lcm.RuntimeContext; + +public class CommandExecutorInput { + private RuntimeContext runtimeContext ; + private int ttl; + + + public RuntimeContext getRuntimeContext() { + return runtimeContext; + } + + public void setRuntimeContext(RuntimeContext runtimeContext) { + this.runtimeContext = runtimeContext; + } + + public int getTtl() { + return ttl; + } + + public void setTtl(int ttl) { + this.ttl = ttl; + } + + @Override + public String toString() { + return "CommandExecutorInput{" + + "runtimeContext=" + runtimeContext + + ", ttl=" + ttl + + '}'; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/CommandResponse.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/CommandResponse.java new file mode 100644 index 000000000..c973fcde1 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/CommandResponse.java @@ -0,0 +1,38 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executor.objects; + +import org.openecomp.appc.domainmodel.lcm.RuntimeContext; + + +public class CommandResponse { + + private RuntimeContext runtimeContext; + + public RuntimeContext getRuntimeContext() { + return runtimeContext; + } + + public void setRuntimeContext(RuntimeContext runtimeContext) { + this.runtimeContext = runtimeContext; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/LCMCommandStatus.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/LCMCommandStatus.java new file mode 100644 index 000000000..4e3a40e75 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/LCMCommandStatus.java @@ -0,0 +1,112 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executor.objects; + + +import org.apache.commons.lang3.StringUtils; +import org.openecomp.appc.util.MessageFormatter; + +import java.util.Map; + +public enum LCMCommandStatus { + + ACCEPTED(100,"ACCEPTED - request accepted"), + + //ERROR(2xx) – request can’t be handled due to some technical error + UNEXPECTED_ERROR(200,"UNEXPECTED ERROR - ${errorMsg}"), + + //REJECT(3xx) – request has been rejected due to some business reason (e.g. no such service-instance-id, command is not supported, etc) + REJECTED(300,"REJECTED - ${errorMsg}"), + INVALID_INPUT_PARAMETER(301,"INVALID INPUT PARAMETER - ${errorMsg}"),// TODO 77777777 to support "${paramName} with invalid value ${paramValue}" + MISSING_MANDATORY_PARAMETER(302,"MISSING MANDATORY PARAMETER - Parameter/s ${paramName} is/are missing" ), + REQUEST_PARSING_FAILED(303,"REQUEST PARSING FAILED - ${errorMsg}"), + NO_TRANSITION_DEFINE(304,"ACTION IS NOT ALLOWED - Action ${actionName} is not allowed for VNF in state ${currentState}"), + ACTION_NOT_SUPPORTED(305,"ACTION NOT SUPPORTED - ${actionName} action is not supported" ), + VNF_NOT_FOUND(306,"VNF NOT FOUND - VNF with ID ${vnfId} was not found" ), + DG_WORKFLOW_NOT_FOUND(307,"DG WORKFLOW NOT FOUND - No DG workflow found for the combination of ${dgModule} module ${dgName} name and ${dgVersion} version"),//TODO need to support it + WORKFLOW_NOT_FOUND(308,"WORKFLOW NOT FOUND - No workflow found for VNF type ${vnfTypeVersion} and ${actionName} action"), + UNSTABLE_VNF(309,"UNSTABLE VNF - VNF ${vnfId} is not stable to accept the command"), + LOCKING_FAILURE(310,"LOCKING FAILURE - ${errorMsg}" ), + EXPIRED_REQUEST(311,"EXPIRED REQUEST"), + DUPLICATE_REQUEST(312,"DUPLICATE REQUEST"), + + SUCCESS(400,"SUCCESS - request has been processed successfully"), + + + // FAILURE(5xx) – request processing results with failure. The FAILURE response is always transmitted asynchronously, via DMaaP. + DG_FAILURE(401,"DG FAILURE - ${errorMsg}"), + NO_TRANSITION_DEFINE_FAILURE(402,"NO TRANSITION DEFINE - No Transition Defined for ${actionName} action and ${currentState} state"), + UPDATE_AAI_FAILURE(403,"UPDATE_AAI_FAILURE - failed to update AAI. ${errorMsg}"), + EXPIRED_REQUEST_FAILURE(404,"EXPIRED REQUEST FAILURE - failed after accepted because TTL expired"), + UNEXPECTED_FAILURE(405,"UNEXPECTED FAILURE - ${errorMsg}"), + UNSTABLE_VNF_FAILURE(406,"UNSTABLE VNF FAILURE - VNF ${vnfId} is not stable to accept the command"), + + ; + + + public static final String errorDgMessageParamName = "errorDgMessage"; + + private int responseCode; + private String responseMessage; + + + + + LCMCommandStatus(int responseCode, String responseMessage) { + this.responseCode = responseCode; + this.responseMessage = responseMessage; + } + + public String getResponseMessage() { + return responseMessage; + } + + public int getResponseCode() { + return responseCode; + } + + + /** + * + * @return messageTemplate + */ + + + public String getFormattedMessage(Params params){ + Map<String,Object> paramsMap = params != null ? params.getParams() : null; + return MessageFormatter.format(getResponseMessage(),paramsMap); + + } + + public String getFormattedMessageWithCode(Params params){ + return getResponseCode()+"-" + getFormattedMessage(params); + } + + @Override + public String toString() { + return "LCMCommandStatus{" + + "responseCode=" + responseCode + + ", responseMessage='" + responseMessage + '\'' + + '}'; + } +} + diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/Params.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/Params.java new file mode 100644 index 000000000..8db4f6576 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/Params.java @@ -0,0 +1,57 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executor.objects; + +import java.lang.Object; +import java.util.HashMap; +import java.util.Map; + + +public class Params { + public static final String paramDgNameSpace = "dg.status.message.param."; + public static final String errorDgMessageParamName = "errorDgMessage"; + private Map<String, java.lang.Object> params; + + public Params() { + } + + public Map<String, java.lang.Object> getParams() { + return params; + } + + public void setParams(Map<String, java.lang.Object> params) { + this.params = params; + } + + public Params addParam(String paramName, java.lang.Object paramValue) { + params = params == null ? new HashMap<String, Object>() : params; + params.put(paramName, paramValue); + return this; + } + + @Override + public String toString() { + return "Params{" + + "params=" + params + + '}'; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/UniqueRequestIdentifier.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/UniqueRequestIdentifier.java new file mode 100644 index 000000000..0e33ca4c2 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/UniqueRequestIdentifier.java @@ -0,0 +1,123 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executor.objects; + + +import org.apache.commons.lang3.StringUtils; + + +public class UniqueRequestIdentifier { + private static final String IDENTIFIER_DELIMITER = "@"; + + private String originatorID; + private String requestID; + private String subRequestID; + + private UniqueRequestIdentifier(){ + + } + public UniqueRequestIdentifier(String originatorID, + String requestID, + String subRequestID) { + this(); + this.originatorID = originatorID; + this.requestID = requestID; + this.subRequestID = subRequestID; + } + + public String toIdentifierString(){ + StringBuilder stringBuilder = new StringBuilder(); + if(originatorID != null){ + stringBuilder.append(originatorID); + } + stringBuilder.append(IDENTIFIER_DELIMITER); + + if(requestID != null){ + stringBuilder.append(requestID); + } + stringBuilder.append(IDENTIFIER_DELIMITER); + + if(subRequestID != null){ + stringBuilder.append(subRequestID); + } + return stringBuilder.toString(); + } + + public static UniqueRequestIdentifier getUniqueRequestIdentifier(String identifierString){ + String[] splitIdentifier = identifierString.split(IDENTIFIER_DELIMITER); + if(splitIdentifier == null || splitIdentifier.length <2){ + throw new IllegalArgumentException("input identifierString is not valid "+identifierString); + } + String originatorID = splitIdentifier[0]; + String requestID = StringUtils.isEmpty(splitIdentifier[1])? null :splitIdentifier[1]; + String subRequestID = splitIdentifier.length>=3 ? splitIdentifier[2] : null; + return new UniqueRequestIdentifier(originatorID,requestID,subRequestID); + } + public String toString(){ + return "originatorID = " + originatorID + + " , requestID = " + requestID + + " , subRequestID = " + subRequestID; + } + @Override + public boolean equals(Object obj){ + if(obj ==null){ + return false; + } + if(!(obj instanceof UniqueRequestIdentifier)){ + return false; + } + UniqueRequestIdentifier identifier = (UniqueRequestIdentifier)obj; + if(this.originatorID == null){ + if(identifier.originatorID !=null) + return false; + } + else if(!this.originatorID.equals(identifier.originatorID)) + return false; + + if(this.requestID == null){ + if(identifier.requestID !=null) + return false; + } + else if(!this.requestID.equals(identifier.requestID)) + return false; + + if(this.subRequestID == null){ + if(identifier.subRequestID !=null) + return false; + } + else if(!this.subRequestID.equals(identifier.subRequestID)) + return false; + + return true; + } + @Override + public int hashCode(){ + final int prime = 31; + int result = 1; + result = result * prime + (this.originatorID == null ? 0 :this.originatorID.hashCode()); + result = result * prime + (this.requestID == null ? 0 :this.requestID.hashCode()); + result = result * prime + (this.subRequestID == null ? 0 :this.subRequestID.hashCode()); + return result; + } + + +} diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/.gitignore b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/pom.xml b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/pom.xml new file mode 100644 index 000000000..942bf7dd0 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/pom.xml @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + + <!-- + + 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. + --> + + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-command-executor</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-command-executor-core</artifactId> + <packaging>bundle</packaging> + + <name>appc-command-executor-core Bundle</name> + <description>appc-command-executor-core OSGi bundle project.</description> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-command-executor-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-workflow-management-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-request-handler-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>execution-queue-management-lib</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-data-access-lib</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dmaap-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-lifecycle-management-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.adaptors</groupId> + <artifactId>aai-service-provider</artifactId> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>domain-model-lib</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Export-Service>org.openecomp.appc.executor.CommandExecutor</Export-Service> + <Import-Package>org.openecomp.appc.executionqueue.*,org.openecomp.appc.executor,org.openecomp.appc.executor.objects,!groovy.lang,!javax.jms,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandExecutorImpl.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandExecutorImpl.java new file mode 100644 index 000000000..60a951722 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandExecutorImpl.java @@ -0,0 +1,153 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +/** + * + */ +package org.openecomp.appc.executor.impl; + + +import java.util.Date; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.lang.ObjectUtils; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.executionqueue.ExecutionQueueService; +import org.openecomp.appc.executionqueue.impl.ExecutionQueueServiceFactory; +import org.openecomp.appc.executor.CommandExecutor; +import org.openecomp.appc.executor.impl.objects.CommandRequest; +import org.openecomp.appc.executor.impl.objects.LCMCommandRequest; +import org.openecomp.appc.executor.impl.objects.LCMReadOnlyCommandRequest; +import org.openecomp.appc.executor.objects.CommandExecutorInput; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + + +public class CommandExecutorImpl implements CommandExecutor { + + private CommandTaskFactory executionTaskFactory ; + private static final EELFLogger logger = EELFManager.getInstance().getLogger(CommandExecutorImpl.class); + + private ExecutionQueueService executionQueueService; + private ExpiredMessageHandler expiredMessageHandler; + + public CommandExecutorImpl(){ + + } + + public void setExecutionQueueService(ExecutionQueueService executionQueueService) { + this.executionQueueService = executionQueueService; + } + + public void setExpiredMessageHandler(ExpiredMessageHandler expiredMessageHandler) { + this.expiredMessageHandler = expiredMessageHandler; + } + + public void initialize() { + logger.info("initialization started of CommandExecutorImpl"); + executionQueueService = ExecutionQueueServiceFactory.getExecutionQueueService(); + executionQueueService.registerMessageExpirationListener(expiredMessageHandler); + } + + public void setExecutionTaskFactory(CommandTaskFactory executionTaskFactory) { + this.executionTaskFactory = executionTaskFactory; + } + + /** + * Execute given command + * Create command request and enqueue it for execution. + * @param commandExecutorInput Contains CommandHeader, command , target Id , payload and conf ID (optional) + * @throws APPCException in case of error. + */ + @Override + public void executeCommand (CommandExecutorInput commandExecutorInput) throws APPCException{ + if (logger.isTraceEnabled()) { + logger.trace("Entering to executeCommand with CommandExecutorInput = "+ ObjectUtils.toString(commandExecutorInput)); + } + CommandRequest request = getCommandRequest(commandExecutorInput); + enqueRequest(request); + if (logger.isTraceEnabled()) { + logger.trace("Exiting from executeCommand"); + } + } + + private CommandRequest getCommandRequest(CommandExecutorInput commandExecutorInput){ + if (logger.isTraceEnabled()) { + logger.trace("Entering to getCommandRequest with CommandExecutorInput = "+ ObjectUtils.toString(commandExecutorInput)); + } + CommandRequest commandRequest; + + switch(commandExecutorInput.getRuntimeContext().getRequestContext().getAction()){ + case Sync: + commandRequest = new LCMReadOnlyCommandRequest(commandExecutorInput); + break; + case Audit: + commandRequest = new LCMReadOnlyCommandRequest(commandExecutorInput); + break; + default: + commandRequest = new LCMCommandRequest(commandExecutorInput); + break; + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting from getCommandRequest with (CommandRequest = "+ ObjectUtils.toString(commandRequest)+")"); + } + return commandRequest; + } + + @SuppressWarnings("unchecked") + private void enqueRequest(CommandRequest request) throws APPCException{ + if (logger.isTraceEnabled()) { + logger.trace("Entering to enqueRequest with CommandRequest = "+ ObjectUtils.toString(request)); + } + try { + CommandTask commandTask = getMessageExecutor(request.getCommandExecutorInput().getRuntimeContext().getRequestContext().getAction().name()); + commandTask.setCommandRequest(request); + long remainingTTL = getRemainingTTL(request); + executionQueueService.putMessage(commandTask,remainingTTL, TimeUnit.MILLISECONDS); + } catch (Exception e) { + logger.error("Exception: "+e.getMessage()); + throw new APPCException(e); + } + + if (logger.isTraceEnabled()) { + logger.trace("Exiting from enqueRequest"); + } + } + + private long getRemainingTTL(CommandRequest request) { + Date requestTimestamp = request.getCommandExecutorInput().getRuntimeContext().getRequestContext().getCommonHeader().getTimeStamp(); + int ttl = request.getCommandExecutorInput().getRuntimeContext().getRequestContext().getCommonHeader().getFlags().getTtl(); + return ttl*1000 + requestTimestamp.getTime() - System.currentTimeMillis(); + } + + private CommandTask getMessageExecutor(String action){ + if (logger.isTraceEnabled()) { + logger.trace("Entering to getMessageExecutor with command = "+ action); + } + CommandTask executionTask = executionTaskFactory.getExecutionTask(action); + if (logger.isTraceEnabled()) { + logger.trace("Exiting from getMessageExecutor"); + } + return executionTask; + } + + +} diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTask.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTask.java new file mode 100644 index 000000000..6418002c2 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTask.java @@ -0,0 +1,126 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executor.impl; + +import static com.att.eelf.configuration.Configuration.MDC_ALERT_SEVERITY; +import static com.att.eelf.configuration.Configuration.MDC_INSTANCE_UUID; +import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID; +import static com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN; +import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS; +import static com.att.eelf.configuration.Configuration.MDC_SERVICE_INSTANCE_ID; +import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME; + +import java.net.InetAddress; + +import org.openecomp.appc.domainmodel.lcm.RuntimeContext; +import org.openecomp.appc.domainmodel.lcm.Status; +import org.openecomp.appc.executor.impl.objects.CommandRequest; +import org.openecomp.appc.executor.objects.CommandResponse; +import org.openecomp.appc.executor.objects.LCMCommandStatus; +import org.openecomp.appc.executor.objects.Params; +import org.openecomp.appc.logging.LoggingConstants; +import org.openecomp.appc.requesthandler.RequestHandler; +import org.openecomp.appc.workflow.WorkFlowManager; +import org.openecomp.appc.workflow.objects.WorkflowRequest; +import org.openecomp.appc.workflow.objects.WorkflowResponse; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.slf4j.MDC; + +/** + * This abstract class is base class for all Command tasks. All command task must inherit this class. + */ + +public abstract class CommandTask<M> implements Runnable { + + protected RequestHandler requestHandler; + protected WorkFlowManager workflowManager; + + private CommandRequest commandRequest; + + public CommandRequest getCommandRequest() { + return commandRequest; + } + + public void setCommandRequest(CommandRequest commandRequest) { + this.commandRequest = commandRequest; + } + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(CommandTask.class); + + public void setWorkflowManager(WorkFlowManager workflowManager) { + this.workflowManager = workflowManager; + } + + public void setRequestHandler(RequestHandler requestHandler) { + this.requestHandler = requestHandler; + } + + CommandTask(){ + } + + public void onRequestCompletion(CommandRequest request, CommandResponse response , boolean isAAIUpdated) { + logger.debug("Entry: onRequestCompletion()"); + requestHandler.onRequestExecutionEnd(request.getCommandExecutorInput().getRuntimeContext(), isAAIUpdated); + } + + public abstract void onRequestCompletion(CommandRequest request, CommandResponse response); + + protected CommandResponse buildCommandResponse(CommandRequest request, WorkflowResponse response) { + + CommandResponse commandResponse = new CommandResponse(); + commandResponse.setRuntimeContext(request.getCommandExecutorInput().getRuntimeContext()); + return commandResponse; + } + + + public void execute() { + final RuntimeContext runtimeContext = commandRequest.getCommandExecutorInput().getRuntimeContext(); + MDC.put(MDC_KEY_REQUEST_ID, runtimeContext.getRequestContext().getCommonHeader().getRequestId()); + if (runtimeContext.getRequestContext().getActionIdentifiers().getServiceInstanceId() != null) + MDC.put(MDC_SERVICE_INSTANCE_ID, runtimeContext.getRequestContext().getActionIdentifiers().getServiceInstanceId()); + MDC.put(LoggingConstants.MDCKeys.PARTNER_NAME, runtimeContext.getRequestContext().getCommonHeader().getOriginatorId()); + MDC.put(MDC_SERVICE_NAME, runtimeContext.getRequestContext().getAction().name()); + try { + MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getCanonicalHostName()); //Don't change it to a .getLocalHostName() again please. It's wrong! + MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress()); + }catch(Exception e){ + logger.debug(e.getMessage()); + } + MDC.put(MDC_INSTANCE_UUID, ""); //TODO make instanse_UUID generation once during APPC-instanse deploying + + WorkflowRequest workflowRequest = new WorkflowRequest(); + workflowRequest.setRequestContext(runtimeContext.getRequestContext()); + workflowRequest.setResponseContext(runtimeContext.getResponseContext()); + workflowRequest.setVnfContext(runtimeContext.getVnfContext()); + + WorkflowResponse response = workflowManager.executeWorkflow(workflowRequest); + + CommandResponse commandResponse = buildCommandResponse(commandRequest, response); + this.onRequestCompletion(commandRequest,commandResponse); + } + + public static void fillStatus(Status status, LCMCommandStatus lcmCommandStatus, Params params) { + status.setCode(lcmCommandStatus.getResponseCode()); + status.setMessage(lcmCommandStatus.getFormattedMessage(params)); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTaskFactory.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTaskFactory.java new file mode 100644 index 000000000..610f0bca3 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTaskFactory.java @@ -0,0 +1,65 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executor.impl; + + +import org.openecomp.appc.domainmodel.lcm.VNFOperation; +import org.openecomp.appc.lifecyclemanager.LifecycleManager; +import org.openecomp.appc.requesthandler.RequestHandler; +import org.openecomp.appc.workflow.WorkFlowManager; + + + + +public class CommandTaskFactory { + +// private LCMCommandTask lcmCommandTask; +// private LCMReadonlyCommandTask LCMReadonlyCommandTask; + + private RequestHandler requestHandler; + private WorkFlowManager workflowManager; + private LifecycleManager lifecyclemanager; + + + public void setWorkflowManager(WorkFlowManager workflowManager) { + this.workflowManager = workflowManager; + } + + public void setRequestHandler(RequestHandler requestHandler) { + this.requestHandler = requestHandler; + } + + public void setLifecyclemanager(LifecycleManager lifecyclemanager) { + this.lifecyclemanager = lifecyclemanager; + } + + + public synchronized CommandTask getExecutionTask(String action){ + if (VNFOperation.Sync.toString().equals(action) || VNFOperation.Audit.toString().equals(action)){ + return new LCMReadonlyCommandTask(requestHandler,workflowManager); + }else { + return new LCMCommandTask(requestHandler,workflowManager, + lifecyclemanager); + } + } + +} diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommonMethods.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommonMethods.java new file mode 100644 index 000000000..6ecf76c3a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommonMethods.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executor.impl; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.util.HashMap; + + +class CommonMethods { + + private static final HashMap m = new HashMap(); + + static { + m.put(34, """); // < - less-than + m.put(60, "<"); // < - less-than + m.put(62, ">"); // > - greater-than + m.put(38, "&"); // & - Ampersand + } + + static String escapeHtml(String source) { + try { + StringWriter writer = new StringWriter((int) (source.length() * 1.5)); + escape(writer, source); + return writer.toString(); + } catch (IOException ioe) { + ioe.printStackTrace(); + return null; + } + } + + private static void escape(Writer writer, String str) throws IOException { + int len = str.length(); + for (int i = 0; i < len; i++) { + char c = str.charAt(i); + int ascii = (int) c; + String entityName = (String) m.get(ascii); + if (entityName == null) { + if (c > 0x7F) { + writer.write("&#"); + writer.write(Integer.toString(c, 10)); + writer.write(';'); + } else { + writer.write(c); + } + } else { + writer.write(entityName); + } + } + } + +} diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/ExpiredMessageHandler.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/ExpiredMessageHandler.java new file mode 100644 index 000000000..fc79c461f --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/ExpiredMessageHandler.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executor.impl; + +import org.openecomp.appc.executionqueue.MessageExpirationListener; +import org.openecomp.appc.executor.impl.objects.CommandRequest; +import org.openecomp.appc.requesthandler.RequestHandler; + + +public class ExpiredMessageHandler<M> implements MessageExpirationListener<M>{ + private RequestHandler requestHandler; + + public ExpiredMessageHandler(){ + + } + + public void setRequestHandler(RequestHandler requestHandler) { + this.requestHandler = requestHandler; + } + + @Override + public void onMessageExpiration(M message) { + CommandRequest commandRequest = (CommandRequest)message; + requestHandler.onRequestTTLEnd(commandRequest.getCommandExecutorInput().getRuntimeContext(), true); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/LCMCommandTask.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/LCMCommandTask.java new file mode 100644 index 000000000..6e64a546b --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/LCMCommandTask.java @@ -0,0 +1,261 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executor.impl; + + +import org.apache.commons.lang3.StringUtils; +import org.openecomp.appc.domainmodel.lcm.CommonHeader; +import org.openecomp.appc.domainmodel.lcm.Status; +import org.openecomp.appc.domainmodel.lcm.VNFOperation; +import org.openecomp.appc.executor.UnstableVNFException; +import org.openecomp.appc.executor.impl.objects.CommandRequest; +import org.openecomp.appc.executor.impl.objects.LCMCommandRequest; +import org.openecomp.appc.executor.objects.CommandResponse; +import org.openecomp.appc.executor.objects.LCMCommandStatus; +import org.openecomp.appc.executor.objects.Params; +import org.openecomp.appc.executor.objects.UniqueRequestIdentifier; +import org.openecomp.appc.lifecyclemanager.LifecycleManager; +import org.openecomp.appc.lifecyclemanager.objects.LifecycleException; +import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException; +import org.openecomp.appc.lifecyclemanager.objects.VNFOperationOutcome; +import org.openecomp.appc.requesthandler.RequestHandler; +import org.openecomp.appc.workflow.WorkFlowManager; +import org.openecomp.appc.workflow.objects.WorkflowResponse; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicException; +import org.openecomp.sdnc.sli.SvcLogicResource; +import org.openecomp.sdnc.sli.aai.AAIService; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +import java.util.HashMap; +import java.util.Map; + + +public class LCMCommandTask extends CommandTask<LCMCommandRequest> { + + private AAIService aaiService; + private LifecycleManager lifecyclemanager; + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(LCMCommandTask.class); + + public LCMCommandTask(RequestHandler requestHandler, WorkFlowManager workflowManager, + LifecycleManager lifecyclemanager){ + setRequestHandler(requestHandler); + setWorkflowManager(workflowManager); + setLifecyclemanager(lifecyclemanager); + getAAIservice(); + } + + public void setLifecyclemanager(LifecycleManager lifecyclemanager) { + this.lifecyclemanager = lifecyclemanager; + } + + + private void getAAIservice() { + BundleContext bctx = FrameworkUtil.getBundle(AAIService.class).getBundleContext(); + // Get AAIadapter reference + ServiceReference sref = bctx.getServiceReference(AAIService.class.getName()); + if (sref != null) { + logger.info("AAIService from bundlecontext"); + aaiService = (AAIService) bctx.getService(sref); + + } else { + logger.info("AAIService error from bundlecontext"); + logger.warn("Cannot find service reference for org.openecomp.sdnc.sli.aai.AAIService"); + + } + } + + + @Override + public void onRequestCompletion(CommandRequest request, CommandResponse response) { + + boolean isAAIUpdated = false; + try { + + final int statusCode = request.getCommandExecutorInput().getRuntimeContext().getResponseContext().getStatus().getCode(); + + if (logger.isDebugEnabled()) { + logger.debug("Workflow Execution Status = "+ statusCode); + } + + boolean isSuccess = statusCode == 100 || statusCode == 400; + + if (isSuccess && VNFOperation.Terminate == request.getCommandExecutorInput().getRuntimeContext().getRequestContext().getAction()) { + SvcLogicContext ctx = new SvcLogicContext(); + ctx = getVnfdata(request.getCommandExecutorInput().getRuntimeContext().getVnfContext().getId(), "vnf", ctx); + isAAIUpdated = aaiService.deleteGenericVnfData(request.getCommandExecutorInput().getRuntimeContext().getVnfContext().getId(), ctx.getAttribute("vnf.resource-version")); + } + else{ + isAAIUpdated = updateAAI(request.getCommandExecutorInput().getRuntimeContext().getVnfContext().getId() , false, isSuccess); + } + logger.debug("isAAIUpdated = " + isAAIUpdated); + } + catch(Exception e1) { + logger.error("Exception = " + e1); + throw new RuntimeException(e1); + } + finally { + super.onRequestCompletion(request, response , isAAIUpdated); + } + } + + @Override + public void run() { + LCMCommandRequest request = (LCMCommandRequest)getCommandRequest(); + boolean isAAIUpdated; + final String vnfId = request.getCommandExecutorInput().getRuntimeContext().getVnfContext().getId(); + final String vnfType = request.getCommandExecutorInput().getRuntimeContext().getVnfContext().getType(); + try { + final CommonHeader commonHeader = request.getCommandExecutorInput().getRuntimeContext().getRequestContext().getCommonHeader(); + final boolean forceFlag = commonHeader.getFlags().isForce(); + UniqueRequestIdentifier requestIdentifier = new UniqueRequestIdentifier(commonHeader.getOriginatorId(), + commonHeader.getRequestId(), commonHeader.getSubRequestId()); + String requestIdentifierString = requestIdentifier.toIdentifierString(); + requestHandler.onRequestExecutionStart(vnfId,false, requestIdentifierString, forceFlag); + + final String currentStatus = request.getCommandExecutorInput().getRuntimeContext().getVnfContext().getStatus(); + final VNFOperation action = request.getCommandExecutorInput().getRuntimeContext().getRequestContext().getAction(); + + final String nextState = lifecyclemanager.getNextState(vnfType, currentStatus, action.name()); + + SvcLogicContext ctx = new SvcLogicContext(); + ctx=getVnfdata(vnfId, "onRequestExecutionStart", ctx); + isAAIUpdated= postVnfdata(vnfId, nextState,"onRequestExecutionStart",ctx); + } catch (NoTransitionDefinedException e) { + logger.error("Error getting Next State for AAI Update: " + e.getMessage(), e); + Status status = request.getCommandExecutorInput().getRuntimeContext().getResponseContext().getStatus(); + Params params = new Params().addParam("actionName",e.event).addParam("currentState",e.currentState); + fillStatus(status, LCMCommandStatus.NO_TRANSITION_DEFINE_FAILURE, params); + isAAIUpdated = false; + } catch (UnstableVNFException e) { + logger.error(e.getMessage(), e); + Status status = request.getCommandExecutorInput().getRuntimeContext().getResponseContext().getStatus(); + Params params = new Params().addParam("vnfId",vnfId); + fillStatus(status, LCMCommandStatus.UNSTABLE_VNF_FAILURE, params); + isAAIUpdated = false; + }catch (Exception e) { + logger.error("Error before Request Execution starts.", e); + Status status = request.getCommandExecutorInput().getRuntimeContext().getResponseContext().getStatus(); + String errorMsg = StringUtils.isEmpty(e.getMessage()) ? e.toString() : e.getMessage(); + Params params = new Params().addParam("errorMsg",errorMsg); + fillStatus(status, LCMCommandStatus.UNEXPECTED_FAILURE, params); + isAAIUpdated = false; + } + + if (isAAIUpdated){ + super.execute(); + }else{ + String errorMsg = "Error updating A& AI before Workflow execution"; + logger.error(errorMsg); + WorkflowResponse response = new WorkflowResponse(); + response.setResponseContext(request.getCommandExecutorInput().getRuntimeContext().getResponseContext()); + CommandResponse commandResponse = super.buildCommandResponse(request, response); + this.onRequestCompletion(request,commandResponse); + } + } + + + + private boolean updateAAI(String vnf_id , boolean isTTLEnd , boolean executionStatus) + { + String orchestrationStatus = null; + String nextState; + boolean callbackResponse; + VNFOperationOutcome outcome; + SvcLogicContext ctx = new SvcLogicContext(); + try { + ctx=getVnfdata(vnf_id, "onRequestExecutionEnd",ctx); + orchestrationStatus=ctx.getAttribute("onRequestExecutionEnd.orchestration-status"); + + if(isTTLEnd){ + outcome = VNFOperationOutcome.FAILURE; + } + else if(executionStatus){ + outcome = VNFOperationOutcome.SUCCESS; + } + else{ + outcome = VNFOperationOutcome.FAILURE; + } + nextState = lifecyclemanager.getNextState(null,orchestrationStatus, outcome.toString()) ; + callbackResponse= postVnfdata(vnf_id, nextState,"onRequestExecutionEnd",ctx); + logger.debug("AAI posting status: " + callbackResponse); + + } catch (NoTransitionDefinedException e) { + logger.debug("Transition not defined for State = " + orchestrationStatus); + callbackResponse =false; + } catch (LifecycleException e) { + logger.debug("State or command not registered with State Machine. State = " + orchestrationStatus); + callbackResponse =false; + } + return callbackResponse; + } + + + private SvcLogicContext getVnfdata(String vnf_id, String prefix,SvcLogicContext ctx) { + String key="vnf-id = '"+ vnf_id+"'"; + logger.debug("inside getVnfdata=== "+key); + try { + SvcLogicResource.QueryStatus response = aaiService.query("generic-vnf", false, null, key,prefix, null, ctx); + if(SvcLogicResource.QueryStatus.NOT_FOUND.equals(response)){ + logger.warn("VNF " + vnf_id + " not found while updating A&AI"); + throw new RuntimeException("VNF not found for vnf_id = "+ vnf_id); + } + else if(SvcLogicResource.QueryStatus.FAILURE.equals(response)){ + throw new RuntimeException("Error Querying AAI with vnfID = " +vnf_id); + } + logger.info("AAIResponse: " + response.toString()); + } catch (SvcLogicException e) { + logger.error("Error in getVnfdata "+ e); + throw new RuntimeException(e); + } + return ctx; + } + + private boolean postVnfdata(String vnf_id, String status,String prefix,SvcLogicContext ctx) { + String key="vnf-id = '"+ vnf_id+"'"; + logger.debug("inside postVnfdata=== "+key); + Map<String, String> data = new HashMap<>(); + data.put("orchestration-status", status); + try { + SvcLogicResource.QueryStatus response = aaiService.update("generic-vnf", key, data, prefix, ctx); + if(SvcLogicResource.QueryStatus.NOT_FOUND.equals(response)){ + logger.warn("VNF " + vnf_id + " not found while updating A&AI"); + return false; + } + logger.info("AAIResponse: " + response.toString()); + if(response.toString().equals("SUCCESS")) + { + return true; + } + } catch (SvcLogicException e) { + logger.error("Error in postVnfdata "+ e); + throw new RuntimeException(e); + } + return false; + } + +} diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/LCMReadonlyCommandTask.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/LCMReadonlyCommandTask.java new file mode 100644 index 000000000..137a2e4b5 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/LCMReadonlyCommandTask.java @@ -0,0 +1,81 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executor.impl; + + +import org.apache.commons.lang3.StringUtils; +import org.openecomp.appc.domainmodel.lcm.CommonHeader; +import org.openecomp.appc.domainmodel.lcm.Status; +import org.openecomp.appc.executor.UnstableVNFException; +import org.openecomp.appc.executor.impl.objects.CommandRequest; +import org.openecomp.appc.executor.impl.objects.LCMCommandRequest; +import org.openecomp.appc.executor.impl.objects.LCMReadOnlyCommandRequest; +import org.openecomp.appc.executor.objects.CommandResponse; +import org.openecomp.appc.executor.objects.LCMCommandStatus; +import org.openecomp.appc.executor.objects.Params; +import org.openecomp.appc.executor.objects.UniqueRequestIdentifier; +import org.openecomp.appc.requesthandler.RequestHandler; +import org.openecomp.appc.workflow.WorkFlowManager; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +public class LCMReadonlyCommandTask extends CommandTask<LCMReadOnlyCommandRequest> { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(LCMReadonlyCommandTask.class); + + public LCMReadonlyCommandTask(RequestHandler requestHandler, WorkFlowManager workflowManager){ + + setRequestHandler(requestHandler); + setWorkflowManager(workflowManager); + } + + + @Override + public void onRequestCompletion(CommandRequest request, CommandResponse response) { + super.onRequestCompletion(request, response, true); + } + + @Override + public void run() { + LCMReadOnlyCommandRequest request = (LCMReadOnlyCommandRequest)getCommandRequest(); + final CommonHeader commonHeader = request.getCommandExecutorInput().getRuntimeContext().getRequestContext().getCommonHeader(); + final boolean forceFlag = commonHeader.getFlags().isForce(); + UniqueRequestIdentifier requestIdentifier = new UniqueRequestIdentifier(commonHeader.getOriginatorId(), commonHeader.getRequestId(), commonHeader.getSubRequestId()); + String requestIdentifierString = requestIdentifier.toIdentifierString(); + final String vnfId = request.getCommandExecutorInput().getRuntimeContext().getVnfContext().getId(); + try { + requestHandler.onRequestExecutionStart(vnfId,true, requestIdentifierString, forceFlag); + super.execute(); + } catch (UnstableVNFException e) { + logger.error(e.getMessage(), e); + Status status = request.getCommandExecutorInput().getRuntimeContext().getResponseContext().getStatus(); + Params params = new Params().addParam("vnfId",vnfId); + fillStatus(status, LCMCommandStatus.UNSTABLE_VNF_FAILURE, params); + }catch (Exception e) { + logger.error("Error during runing LCMReadonlyCommandTask.", e); + Status status = request.getCommandExecutorInput().getRuntimeContext().getResponseContext().getStatus(); + String errorMsg = StringUtils.isEmpty(e.getMessage()) ? e.toString() : e.getMessage(); + Params params = new Params().addParam("errorMsg",errorMsg); + fillStatus(status, LCMCommandStatus.UNEXPECTED_FAILURE, params); + } + } +} diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/CommandRequest.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/CommandRequest.java new file mode 100644 index 000000000..a1384c7bb --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/CommandRequest.java @@ -0,0 +1,89 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executor.impl.objects; + +import java.util.Date; + +import org.openecomp.appc.executor.objects.CommandExecutorInput; + +@SuppressWarnings("unused") +public class CommandRequest { + + + private CommandExecutorInput commandExecutorInput; + private Date commandInTimeStamp; + + public CommandRequest(CommandExecutorInput commandExecutorInput) { + this.commandExecutorInput = commandExecutorInput; + } + + + public CommandExecutorInput getCommandExecutorInput() { + return commandExecutorInput; + } + + public void setCommandExecutorInput(CommandExecutorInput commandExecutorInput) { + this.commandExecutorInput = commandExecutorInput; + } + + public Date getCommandInTimeStamp() { + return commandInTimeStamp; + } + + public void setCommandInTimeStamp(Date commandInTimeStamp) { + this.commandInTimeStamp = commandInTimeStamp; + } + + // @Override + // public boolean isTTLExpired() { + // Calendar tempTimeStamp = addTTLToRequestTime(); + // long currentTime = System.currentTimeMillis(); + // long tempTimeStampWithTTL = tempTimeStamp.getTimeInMillis() ; + // return currentTime > tempTimeStampWithTTL; + // } + // + // @Override + // public int getRemainingTTL(TimeUnit timeunit) { + // long tempTimeStampWithTTL = addTTLToRequestTime().getTimeInMillis() ; + // long currentTime = System.currentTimeMillis(); + // long remainingTTL = tempTimeStampWithTTL - currentTime; + // return (int)(tempTimeStampWithTTL - currentTime); + // } + // private Calendar addTTLToRequestTime() + // { + // Date timeInRequest = this.getCommandInTimeStamp(); + // int ttlValue = this.getCommandContext().getTtl(); + // Calendar tempTimeStamp = Calendar.getInstance(); + // tempTimeStamp.setTime(timeInRequest); + // tempTimeStamp.add(Calendar.SECOND, ttlValue); + // return tempTimeStamp; + // } + + + @Override + public String toString() { + return "CommandRequest{" + + "commandExecutorInput=" + commandExecutorInput + + ", commandInTimeStamp=" + commandInTimeStamp + + '}'; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/LCMCommandRequest.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/LCMCommandRequest.java new file mode 100644 index 000000000..45111d6c1 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/LCMCommandRequest.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executor.impl.objects; + +import org.openecomp.appc.executor.objects.CommandExecutorInput; + + +public class LCMCommandRequest extends CommandRequest { + + public LCMCommandRequest(CommandExecutorInput commandExecutorInput) { + super(commandExecutorInput); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/LCMReadOnlyCommandRequest.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/LCMReadOnlyCommandRequest.java new file mode 100644 index 000000000..4d76973e2 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/LCMReadOnlyCommandRequest.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executor.impl.objects; + +import org.openecomp.appc.executor.objects.CommandExecutorInput; + + + +public class LCMReadOnlyCommandRequest extends CommandRequest { + + public LCMReadOnlyCommandRequest(CommandExecutorInput commandExecutorInput) { + super(commandExecutorInput); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..4c5589885 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- + Starter Blueprint Camel Definition appc-command-executor-blueprint +--> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + <bean id="commandExecutorBean" class="org.openecomp.appc.executor.impl.CommandExecutorImpl" + scope="singleton" init-method="initialize"> + <property name="executionTaskFactory" ref="CommandExecutionTaskFactory"/> + <property name="expiredMessageHandler" ref="expiredMessageHandlerBean"/> + </bean> + + <bean id="CommandExecutionTaskFactory" class="org.openecomp.appc.executor.impl.CommandTaskFactory" scope="singleton" > + <property name="requestHandler" ref="RequestHandlerRef" /> + <property name="workflowManager" ref="WorkFlowManagerRef" /> + <property name="lifecyclemanager" ref="LifecyclemanagerRef" /> + </bean> + + <bean id="expiredMessageHandlerBean" class="org.openecomp.appc.executor.impl.ExpiredMessageHandler" + scope="singleton"> + <property name="requestHandler" ref="RequestHandlerRef" /> + </bean> + + <reference id="WorkFlowManagerRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.workflow.WorkFlowManager" /> + <reference id="RequestHandlerRef" availability="optional" activation="eager" interface="org.openecomp.appc.requesthandler.RequestHandler" /> + <reference id="LifecyclemanagerRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.lifecyclemanager.LifecycleManager" /> + + <service id="commandExecutorService" interface="org.openecomp.appc.executor.CommandExecutor" ref="commandExecutorBean"/> +</blueprint> diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..2e5f26a0f --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,48 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + + +#Property below provided by appc.properties +#dmaap.poolMembers=<DMAAP_IP>:3904 + +dmaap.topic.read=APPC-TEST2 +dmaap.topic.write=APPC-TEST2 +dmaap.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]} +dmaap.client.name=APPC-TEST-CLIENT-CMD-EXECUTOR-MAIN +dmaap.client.name.id=0 +#dmaap.client.key=random +#dmaap.client.secret=random + +dmaap.threads.queuesize.min=1 +dmaap.threads.queuesize.max=1000 +dmaap.threads.poolsize.min=2 +dmaap.threads.poolsize.max=2 + +# +# This needs to be changed so that the action can be appended to the end of the URL path +# +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:topology-service +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider: diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/java/org/openecomp/appc/executor/TestCommandExecutionTask.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/java/org/openecomp/appc/executor/TestCommandExecutionTask.java new file mode 100644 index 000000000..0504c3998 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/java/org/openecomp/appc/executor/TestCommandExecutionTask.java @@ -0,0 +1,312 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executor; +/** + * + */ + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.openecomp.appc.domainmodel.lcm.*; +import org.openecomp.appc.executor.impl.CommandTask; +import org.openecomp.appc.executor.impl.CommandTaskFactory; +import org.openecomp.appc.executor.impl.LCMCommandTask; +import org.openecomp.appc.executor.impl.LCMReadonlyCommandTask; +import org.openecomp.appc.executor.impl.objects.CommandRequest; +import org.openecomp.appc.executor.impl.objects.LCMCommandRequest; +import org.openecomp.appc.executor.impl.objects.LCMReadOnlyCommandRequest; +import org.openecomp.appc.executor.objects.*; +import org.openecomp.appc.lifecyclemanager.LifecycleManager; +import org.openecomp.appc.requesthandler.RequestHandler; +import org.openecomp.appc.workflow.WorkFlowManager; +import org.openecomp.appc.workflow.objects.WorkflowRequest; +import org.openecomp.appc.workflow.objects.WorkflowResponse; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicException; +import org.openecomp.sdnc.sli.SvcLogicResource; +import org.openecomp.sdnc.sli.aai.AAIService; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import static junit.framework.Assert.assertEquals; +import static org.mockito.Matchers.*; + + + +@RunWith(PowerMockRunner.class) +@PrepareForTest( {FrameworkUtil.class, CommandTask.class, LCMCommandTask.class}) +public class TestCommandExecutionTask { + + private static final String TTL_FLAG= "TTL"; + private static final String API_VERSION= "2.0.0"; + private static final String ORIGINATOR_ID= "1"; + private LCMCommandTask executionTask; + private LCMReadonlyCommandTask LCMReadonlyCommandTask; + private CommandTaskFactory factory ; + + private RequestHandler requestHandler; + private WorkFlowManager workflowManager; + private AAIService aaiService; + private LifecycleManager lifecyclemanager; + + private final BundleContext bundleContext=Mockito.mock(BundleContext.class); + private final Bundle bundleService=Mockito.mock(Bundle.class); + private final ServiceReference sref=Mockito.mock(ServiceReference.class); + + @Before + public void init() throws SvcLogicException { + + // *** + AAIService aaiService = Mockito.mock(AAIService.class);; + PowerMockito.mockStatic(FrameworkUtil.class); + PowerMockito.when(FrameworkUtil.getBundle(AAIService.class)).thenReturn(bundleService); + PowerMockito.when(bundleService.getBundleContext()).thenReturn(bundleContext); + PowerMockito.when(bundleContext.getServiceReference(AAIService.class.getName())).thenReturn(sref); + PowerMockito.when(bundleContext.getService(sref)).thenReturn(aaiService); + PowerMockito.when(aaiService.query(anyString(),anyBoolean(),anyString(),anyString(),anyString(),anyString(),(SvcLogicContext)anyObject())).thenAnswer(new Answer<SvcLogicResource.QueryStatus>() { + @Override + public SvcLogicResource.QueryStatus answer(InvocationOnMock invocation) throws Throwable { + Object[] args = invocation.getArguments(); + SvcLogicContext ctx =(SvcLogicContext)args[6]; + String prefix = (String)args[4]; + String key = (String)args[3]; + if(key.contains("'28'")){ + return SvcLogicResource.QueryStatus.FAILURE ; + }else if ( key.contains("'8'")) { + return SvcLogicResource.QueryStatus.NOT_FOUND ; + }else { + ctx.setAttribute(prefix + ".vnf-type", "FIREWALL"); + ctx.setAttribute(prefix + ".orchestration-status", "INSTANTIATED"); + } + return SvcLogicResource.QueryStatus.SUCCESS ; + } + }); + PowerMockito.when(aaiService.update(anyString(),anyString(),(Map)anyObject(),anyString(),(SvcLogicContext)anyObject())).thenReturn(SvcLogicResource.QueryStatus.SUCCESS); + + requestHandler = Mockito.mock(RequestHandler.class); + workflowManager = Mockito.mock(WorkFlowManager.class); + lifecyclemanager = Mockito.mock(LifecycleManager.class ); + + executionTask = new LCMCommandTask(requestHandler,workflowManager,lifecyclemanager); + LCMReadonlyCommandTask = new LCMReadonlyCommandTask(requestHandler,workflowManager); + factory = new CommandTaskFactory(); + factory.setLifecyclemanager(lifecyclemanager); + factory.setWorkflowManager(workflowManager); + factory.setRequestHandler(requestHandler); + Mockito.when(workflowManager.executeWorkflow((WorkflowRequest)anyObject())).thenReturn(getWorkflowResponse () ); + } + + + @Test + public void testFactory(){ + CommandTask task; + task = factory.getExecutionTask("Configure"); + assertEquals(LCMCommandTask.class,task.getClass() ); + task = factory.getExecutionTask("Sync"); + assertEquals(LCMReadonlyCommandTask.class,task.getClass() ); + + } + + + + @Test + public void testOnRequestCompletion(){ + Mockito.doNothing().when(requestHandler).onRequestTTLEnd((RuntimeContext) anyObject(),anyBoolean()); + LCMCommandRequest request = getLCMCommandRequest("FIREWALL",30,new Date(), "11" ,setTTLInFlags("30"), VNFOperation.Configure, "1", "1.0"); + CommandResponse response = getCommandResponse(VNFOperation.Configure, true, "11", "","1"); + executionTask.onRequestCompletion(request, response); + } + + @Test + public void testRunGetConfig(){ + LCMReadOnlyCommandRequest request = getConfigCommandRequest("FIREWALL",30,new Date(), "11" ,setTTLInFlags("30"),VNFOperation.Sync, "1", "1.0"); + LCMReadonlyCommandTask.setCommandRequest(request); + LCMReadonlyCommandTask.run(); + } + + @Test + public void testRun(){ + LCMCommandRequest request = getLCMCommandRequest("FIREWALL",30,new Date(), "11" ,setTTLInFlags("30"),VNFOperation.Sync, "1", "1.0"); + executionTask.setCommandRequest(request); + executionTask.run(); + } + + @Test + public void testRunNegative(){ + LCMCommandRequest request = getLCMCommandRequest("FIREWALL",30,new Date(), "11" ,setTTLInFlags("30"),VNFOperation.Sync, "1", "1.0"); + executionTask.setCommandRequest(request); + executionTask.run(); + } + + + CommandResponse getCommandResponse(VNFOperation action , boolean success, String responseId, String payload, String vnfId){ + CommandResponse commandResponse = new CommandResponse(); + RuntimeContext runtimeContext = new RuntimeContext(); + commandResponse.setRuntimeContext(runtimeContext); + ResponseContext responseContext = new ResponseContext(); + runtimeContext.setResponseContext(responseContext); + RequestContext requestContext = new RequestContext(); + runtimeContext.setRequestContext(requestContext); + CommonHeader commonHeader = new CommonHeader(); + requestContext.setCommonHeader(commonHeader); + responseContext.setCommonHeader(commonHeader); + Flags flags = new Flags(); + commonHeader.setFlags(flags); + ActionIdentifiers actionIdentifiers = new ActionIdentifiers(); + requestContext.setActionIdentifiers(actionIdentifiers); + VNFContext vnfContext = new VNFContext(); + runtimeContext.setVnfContext(vnfContext); + requestContext.setAction(action); + runtimeContext.setRpcName(action.name().toLowerCase()); + commonHeader.setApiVer(API_VERSION); + Status status = new Status(); + status.setCode(100); + responseContext.setStatus(status); + commonHeader.setRequestId(responseId); + responseContext.setPayload(payload); + commonHeader.setTimestamp(new Date()); + vnfContext.setId(vnfId); + return commandResponse; + } + + + + @Test + public void testPositiveFlow_configure() { + + Date timeStamp = new Date(); + String requestId = "1"; + + CommandExecutorInput commandExecutorInput = pouplateCommandExecutorInput("FIREWALL",30, "1.0", timeStamp, API_VERSION, requestId, ORIGINATOR_ID, "", VNFOperation.Configure, "33", ""); + CommandRequest request = new CommandRequest(commandExecutorInput); + } + + + private Map<String,Object> setTTLInFlags( String value){ + Map<String,Object> flags = new HashMap<String,Object>(); + if( value != null || !("".equalsIgnoreCase(value))){ + flags.put(TTL_FLAG, value); + } + return flags; + } + + + private LCMReadOnlyCommandRequest getConfigCommandRequest(String vnfType , Integer ttl , Date timeStamp, String requestId, + Map<String,Object> flags, VNFOperation command , String vnfId, String vnfVersion ){ + + CommandExecutorInput commandExecutorInput = pouplateCommandExecutorInput(vnfType, ttl, vnfVersion, timeStamp, API_VERSION, requestId, ORIGINATOR_ID, "", command, vnfId, ""); + LCMReadOnlyCommandRequest request = new LCMReadOnlyCommandRequest(commandExecutorInput); + + return request; + } + + private LCMCommandRequest getLCMCommandRequest(String vnfType , Integer ttl ,Date timeStamp, String requestId, + Map<String,Object> flags, VNFOperation command , String vnfId, String vnfVersion ){ + + CommandExecutorInput commandExecutorInput = pouplateCommandExecutorInput(vnfType, ttl, vnfVersion, timeStamp, API_VERSION, requestId, ORIGINATOR_ID, "", command, vnfId, ""); + LCMCommandRequest request = new LCMCommandRequest(commandExecutorInput); + + return request; + } + + public WorkflowResponse getWorkflowResponse (){ + WorkflowResponse wfResponse = new WorkflowResponse(); + ResponseContext responseContext = createResponseContextWithSuObjects(); + wfResponse.setResponseContext(responseContext); + responseContext.setPayload(""); + wfResponse.getResponseContext().getStatus().setCode(100); + return wfResponse; + } + + private CommandExecutorInput pouplateCommandExecutorInput(String vnfType, int ttl, String vnfVersion, Date timeStamp, String apiVersion, String requestId, String originatorID, String subRequestID, VNFOperation action, String vnfId , String payload){ + CommandExecutorInput commandExecutorInput = createCommandExecutorInputWithSubObjects(); + RuntimeContext runtimeContext = commandExecutorInput.getRuntimeContext(); + RequestContext requestContext = runtimeContext.getRequestContext(); + ResponseContext responseContext = createResponseContextWithSuObjects(); + runtimeContext.setResponseContext(responseContext); + + requestContext.getCommonHeader().getFlags().setTtl(ttl); + requestContext.getCommonHeader().setApiVer(apiVersion); + requestContext.getCommonHeader().setTimestamp(timeStamp); + requestContext.getCommonHeader().setRequestId(requestId); + requestContext.getCommonHeader().setSubRequestId(subRequestID); + requestContext.getCommonHeader().setOriginatorId(originatorID); + requestContext.setAction(action); + requestContext.setPayload(payload); + requestContext.getActionIdentifiers().setVnfId(vnfId); + VNFContext vnfContext = runtimeContext.getVnfContext(); + vnfContext.setType(vnfType); + vnfContext.setId(vnfId); + vnfContext.setVersion(vnfVersion); + return commandExecutorInput; + } + + private CommandExecutorInput createCommandExecutorInputWithSubObjects() { + CommandExecutorInput commandExecutorInput = new CommandExecutorInput(); + RuntimeContext runtimeContext = createRuntimeContextWithSubObjects(); + commandExecutorInput.setRuntimeContext(runtimeContext); + return commandExecutorInput; + } + + private RuntimeContext createRuntimeContextWithSubObjects() { + RuntimeContext runtimeContext = new RuntimeContext(); + RequestContext requestContext = new RequestContext(); + runtimeContext.setRequestContext(requestContext); + CommonHeader commonHeader = new CommonHeader(); + requestContext.setCommonHeader(commonHeader); + Flags flags = new Flags(); + commonHeader.setFlags(flags); + ActionIdentifiers actionIdentifiers = new ActionIdentifiers(); + requestContext.setActionIdentifiers(actionIdentifiers); + VNFContext vnfContext = new VNFContext(); + runtimeContext.setVnfContext(vnfContext); + return runtimeContext; + + } + + private ResponseContext createResponseContextWithSuObjects(){ + ResponseContext responseContext = new ResponseContext(); + CommonHeader commonHeader = new CommonHeader(); + Flags flags = new Flags(); + Status status = new Status(); + responseContext.setCommonHeader(commonHeader); + responseContext.setStatus(status); + commonHeader.setFlags(flags); + return responseContext; + } + +} + diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/java/org/openecomp/appc/executor/TestCommandExecutor.java b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/java/org/openecomp/appc/executor/TestCommandExecutor.java new file mode 100644 index 000000000..473e14e88 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/java/org/openecomp/appc/executor/TestCommandExecutor.java @@ -0,0 +1,157 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executor; +/** + * + */ + + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.openecomp.appc.domainmodel.lcm.*; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.executionqueue.ExecutionQueueService; +import org.openecomp.appc.executor.impl.CommandExecutorImpl; +import org.openecomp.appc.executor.impl.CommandTaskFactory; +import org.openecomp.appc.executor.impl.LCMCommandTask; +import org.openecomp.appc.executor.impl.LCMReadonlyCommandTask; +import org.openecomp.appc.executor.objects.CommandExecutorInput; +import org.openecomp.appc.lifecyclemanager.LifecycleManager; +import org.openecomp.appc.requesthandler.RequestHandler; +import org.openecomp.appc.workflow.WorkFlowManager; + +import java.util.Date; +import java.util.concurrent.TimeUnit; + +import static junit.framework.Assert.assertTrue; + + +@SuppressWarnings("deprecation") +public class TestCommandExecutor { + + private static final String TTL_FLAG= "TTL"; + private static final String API_VERSION= "2.0.0"; + private static final String ORIGINATOR_ID= "1"; + + CommandExecutorImpl commandExecutor; + + CommandTaskFactory executionTaskFactory; + + private RequestHandler requestHandler; + private WorkFlowManager workflowManager; + private LifecycleManager lifecyclemanager; + + private ExecutionQueueService executionQueueService; + + @Before + public void init()throws Exception { + requestHandler= Mockito.mock(RequestHandler.class); + lifecyclemanager= Mockito.mock(LifecycleManager.class); + workflowManager= Mockito.mock(WorkFlowManager.class); + + executionQueueService = Mockito.mock(ExecutionQueueService.class); + + commandExecutor = new CommandExecutorImpl(); + executionTaskFactory = Mockito.mock(CommandTaskFactory.class); + commandExecutor.setExecutionTaskFactory(executionTaskFactory); + commandExecutor.setExecutionQueueService(executionQueueService); + LCMCommandTask lcmCommandTask = Mockito.mock(LCMCommandTask.class); + LCMReadonlyCommandTask LCMReadonlyCommandTask = Mockito.mock(LCMReadonlyCommandTask.class); + Mockito.when(executionTaskFactory.getExecutionTask("Configure")).thenReturn(lcmCommandTask); + Mockito.when(executionTaskFactory.getExecutionTask("Sync")).thenReturn(LCMReadonlyCommandTask); +// Mockito.when(executionQueueService.putMessage((Runnable) Mockito.anyObject(),Mockito.anyLong(),(TimeUnit)Mockito.anyObject())).thenReturn(true); + + } + + + @Test + public void testPositiveFlow_LCM(){ + //Map <String,Object> flags = setTTLInFlags("30"); + Date timeStamp = new Date(); + String requestId = "1"; + CommandExecutorInput commandExecutorInput = pouplateCommandExecutorInput("FIREWALL", 30, "1.0", timeStamp, API_VERSION, requestId, ORIGINATOR_ID, "2", VNFOperation.Configure, "15", "") ; + try { + commandExecutor.executeCommand(commandExecutorInput); + } catch (APPCException e) { + Assert.fail(e.toString()); + } + + } + + @Test + public void testPositiveFlow_GetConfig(){ + Date timeStamp = new Date(); + String requestId = "1"; + + CommandExecutorInput commandExecutorInput = pouplateCommandExecutorInput("FIREWALL", 30, "1.0", timeStamp, API_VERSION, requestId, ORIGINATOR_ID, "2", VNFOperation.Sync,"15","") ; + try { + commandExecutor.executeCommand(commandExecutorInput); + } catch (APPCException e) { + Assert.fail(e.toString()); + } + + } + + + private CommandExecutorInput pouplateCommandExecutorInput(String vnfType, int ttl, String vnfVersion, Date timeStamp, String apiVersion, String requestId, String originatorID, String subRequestID, VNFOperation action, String vnfId , String payload){ + CommandExecutorInput commandExecutorInput = createCommandExecutorInputWithSubObjects(); + RuntimeContext runtimeContext = commandExecutorInput.getRuntimeContext(); + RequestContext requestContext = runtimeContext.getRequestContext(); + requestContext.getCommonHeader().getFlags().setTtl(ttl); + requestContext.getCommonHeader().setApiVer(apiVersion); + requestContext.getCommonHeader().setTimestamp(timeStamp); + requestContext.getCommonHeader().setRequestId(requestId); + requestContext.getCommonHeader().setSubRequestId(subRequestID); + requestContext.getCommonHeader().setOriginatorId(originatorID); + requestContext.setAction(action); + requestContext.setPayload(payload); + requestContext.getActionIdentifiers().setVnfId(vnfId); + VNFContext vnfContext = runtimeContext.getVnfContext(); + vnfContext.setType(vnfType); + vnfContext.setId(vnfId); + vnfContext.setVersion(vnfVersion); + return commandExecutorInput; + } + + private CommandExecutorInput createCommandExecutorInputWithSubObjects() { + CommandExecutorInput commandExecutorInput = new CommandExecutorInput(); + RuntimeContext runtimeContext = new RuntimeContext(); + commandExecutorInput.setRuntimeContext(runtimeContext); + RequestContext requestContext = new RequestContext(); + runtimeContext.setRequestContext(requestContext); + CommonHeader commonHeader = new CommonHeader(); + requestContext.setCommonHeader(commonHeader); + Flags flags = new Flags(); + commonHeader.setFlags(flags); + ActionIdentifiers actionIdentifiers = new ActionIdentifiers(); + requestContext.setActionIdentifiers(actionIdentifiers); + VNFContext vnfContext = new VNFContext(); + runtimeContext.setVnfContext(vnfContext); + return commandExecutorInput; + } + + + +} + diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..74552a9d7 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/resources/org/openecomp/appc/default.properties @@ -0,0 +1,102 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded to supply configuration options +#org.openecomp.appc.bootstrap.file=executor-test.properties +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + + +# +# Certificate keystore and truststore +# +#org.openecomp.sdnc.sli.aai.ssl.trust=<jks_FILE_HERE> +#org.openecomp.sdnc.sli.aai.ssl.trust.psswd=adminadmin +#org.openecomp.sdnc.sli.aai.ssl.key=<p12_FILE_HERE> +#org.openecomp.sdnc.sli.aai.ssl.key.psswd=adminadmin +org.openecomp.sdnc.sli.aai.host.certificate.ignore=true +org.openecomp.sdnc.sli.aai.certificate.trust.all=true + + +# +# Configuration file for A&AI Adapter +# + +# OPEN SOURCE - EXTERNAL A&AI INSTANCE IN TEST ENVIRONMENT +org.openecomp.sdnc.sli.aai.uri=https://10.0.1.1:8443 + +org.openecomp.sdnc.sli.aai.path.query=/aai/v8/search/sdn-zone-query + +# service instance +org.openecomp.sdnc.sli.aai.path.svcinst=/aai/v8/business/customers/customer/{customer-id}/service-subscriptions/service-subscription/{service-type}/service-instances +org.openecomp.sdnc.sli.aai.path.svcinst.query=/aai/v8/search/generic-query?key=service-instance.service-instance-id:{svc-instance-id}&start-node-type=service-instance&include=service-instance + +# complex +org.openecomp.sdnc.sli.aai.path.complexes=/aai/v8/cloud-infrastructure/complexes +org.openecomp.sdnc.sli.aai.path.complex=/aai/v8/cloud-infrastructure/complexes/complex/{physical-location-id} + +# vservers +org.openecomp.sdnc.sli.aai.path.vservers=/aai/v8/cloud-infrastructure/tenants/tenant/{tenant-id}/vservers +org.openecomp.sdnc.sli.aai.path.vserver =/aai/v8/cloud-infrastructure/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id} + +# generic-vnf +org.openecomp.sdnc.sli.aai.path.generic.vnfs=/aai/v8/network/generic-vnfs/generic-vnf/ +org.openecomp.sdnc.sli.aai.path.generic.vnf=/aai/v8/network/generic-vnfs/generic-vnf/{vnf-id} + +# +# Formatting +# +org.openecomp.sdnc.sli.aai.param.format=filter=%s:%s +org.openecomp.sdnc.sli.aai.param.vnf_type=vnf-type +org.openecomp.sdnc.sli.aai.param.physical.location.id=physical-location-id +org.openecomp.sdnc.sli.aai.param.service.type=service-type + +org.openecomp.appc.logging.path=${user.home},etc,../etc,. +org.openecomp.appc.logging.file=logback.xml + +org.openecomp.appc.db.url.%s", schema), ""); +org.openecomp.appc.db.user.%s", schema), ""); +org.openecomp.appc.db.pass.%s", schema), ""); + + +#Property below provided by appc.properties +#dmaap.poolMembers=<DMAAP_IP>:3904 + +dmaap.topic.read=APPC-TEST2 +dmaap.topic.write=APPC-TEST2 +#dmaap.topic.read.filter={"class":"Assigned","field":"request"} +dmaap.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]} +dmaap.client.name=APPC-TEST-CLIENT-CMD-EXECUTOR-TEST +dmaap.client.name.id=0 +#dmaap.client.key=random +#dmaap.client.secret=random + +dmaap.threads.queuesize.min=1 +dmaap.threads.queuesize.max=1000 +dmaap.threads.poolsize.min=2 +dmaap.threads.poolsize.max=2 + + +# +# This needs to be changed so that the action can be appended to the end of the URL path +# +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:topology-service +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider: diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-features/.gitignore b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-features/.gitignore new file mode 100644 index 000000000..2992ae832 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-features/.gitignore @@ -0,0 +1,3 @@ +/target/ +/bin/ +/.settings/ diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-features/pom.xml b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-features/pom.xml new file mode 100644 index 000000000..420c25ca4 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-features/pom.xml @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-command-executor</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <name>appc-command-executor-features</name> + <artifactId>appc-command-executor-features</artifactId> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-command-executor-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-command-executor-core</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> +<!-- <plugin> --> + <!-- launches the feature test, which validates that your karaf feature + can be installed inside of a karaf container. It doesn't validate that your + functionality works correctly, just that you have all of the dependent bundles + defined correctly. --> +<!-- <groupId>org.apache.maven.plugins</groupId> --> +<!-- <artifactId>maven-surefire-plugin</artifactId> --> +<!-- <version>2.16</version> --> +<!-- <configuration> --> +<!-- <systemPropertyVariables> --> +<!-- <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId> --> +<!-- <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId> --> +<!-- <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version> --> +<!-- </systemPropertyVariables> --> +<!-- <dependenciesToScan> --> +<!-- <dependency>org.opendaylight.yangtools:features-test</dependency> --> +<!-- </dependenciesToScan> --> +<!-- <classpathDependencyExcludes> --> + <!-- The dependencies which bring in AbstractDataBrokerTest class brings + in a second PaxExam container which results in the feature tests failing + with a message similar to: "ERROR o.ops4j.pax.exam.spi.PaxExamRuntime - Ambiguous + TestContainer ..." This excludes the container we don't want to use. --> +<!-- <classpathDependencyExcludes>org.ops4j.pax.exam:pax-exam-container-native</classpathDependencyExcludes> --> +<!-- </classpathDependencyExcludes> --> +<!-- </configuration> --> +<!-- </plugin> --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + + <!-- Skipping ODL feature test --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <skipTests>true</skipTests> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-features/src/main/resources/features.xml b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-features/src/main/resources/features.xml new file mode 100644 index 000000000..48846fc73 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/appc-command-executor-features/src/main/resources/features.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="appc-command-executor-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + + <feature name='appc-command-executor' description="application executor" version='${project.version}'> + <bundle>mvn:org.openecomp.appc/execution-queue-management-lib/${project.version}</bundle> + <bundle>mvn:org.openecomp.appc/appc-command-executor-api/${project.version}</bundle> + <bundle>mvn:org.openecomp.appc/appc-command-executor-core/${project.version}</bundle> + <!--<bundle>mvn:org.apache.commons/commons-lang3/3.4</bundle>--> + </feature> + +</features> diff --git a/app-c/appc/appc-dispatcher/appc-command-executor/pom.xml b/app-c/appc/appc-dispatcher/appc-command-executor/pom.xml new file mode 100644 index 000000000..d028d1899 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-command-executor/pom.xml @@ -0,0 +1,22 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-command-executor</artifactId> + <packaging>pom</packaging> + <name>APPC Command Executor</name> + <description>APPC Command Executor</description> + + <!-- ================================================================================== --> + <!-- The modules we build --> + <!-- ================================================================================== --> + <modules> + <module>appc-command-executor-api</module> + <module>appc-command-executor-core</module> + <module>appc-command-executor-features</module> + </modules> + +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/.gitignore b/app-c/appc/appc-dispatcher/appc-dispatcher-common/.gitignore new file mode 100644 index 000000000..09e3bc9b2 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.gitignore b/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/pom.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/pom.xml new file mode 100644 index 000000000..8ab6095a6 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/pom.xml @@ -0,0 +1,41 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher-common</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-data-access-lib</artifactId> + <packaging>jar</packaging> + + <name>appc-data-access-lib</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + <scope>compile</scope> + </dependency> + </dependencies> +</project> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/AppcJdbcConnectionFactory.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/AppcJdbcConnectionFactory.java new file mode 100644 index 000000000..4b38e6610 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/AppcJdbcConnectionFactory.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dao.util; + +import java.sql.Connection; +import java.sql.SQLException; + +public class AppcJdbcConnectionFactory implements JdbcConnectionFactory { + + private String schema; + + public void setSchema(String schema) { + this.schema = schema; + } + + public Connection openDbConnection() { + try { + return DBUtils.getConnection(schema); + } catch(SQLException e) { + throw new JdbcRuntimeException(Messages.EXP_APPC_JDBC_CONNECT.format(schema), e); + } + } + + public void closeDbConnection(Connection connection) { + try { + connection.close(); + } catch(SQLException e) { + throw new JdbcRuntimeException(Messages.EXP_APPC_JDBC_DISCONNECT.format(schema), e); + } + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DBUtils.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DBUtils.java new file mode 100644 index 000000000..294d948a0 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DBUtils.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dao.util; + +import java.sql.*; + +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; + +@Deprecated +public class DBUtils { + private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; + private static final Configuration configuration = ConfigurationFactory.getConfiguration(); + static { + try { + String driver = JDBC_DRIVER; + Class.forName(driver); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + + public static Connection getConnection(String schema) throws SQLException { + DriverManager.registerDriver(new com.mysql.jdbc.Driver()); + String dbURL = configuration.getProperty(String.format("org.openecomp.appc.db.url.%s", schema), ""); + String userName = configuration.getProperty(String.format("org.openecomp.appc.db.user.%s", schema), ""); + String password = configuration.getProperty(String.format("org.openecomp.appc.db.pass.%s", schema), ""); + return DriverManager.getConnection(dbURL, userName, password); + } + + public static boolean clearResources(ResultSet resultSet, PreparedStatement ptmt, Connection connection) { + boolean clearFlag = false; + try { + if (resultSet != null) + resultSet.close(); + if (ptmt != null) + ptmt.close(); + if (connection != null) + connection.close(); + clearFlag = true; + } catch (SQLException e) { + + } + return clearFlag; + + } + + /*public static DbLibService getDBLibService(){ + DbLibService dblibSvc = null; + BundleContext bctx = FrameworkUtil.getBundle(SvcLogicDblibStore.class).getBundleContext(); + ServiceReference sref = bctx.getServiceReference("org.openecomp.sdnc.sli.resource.dblib.DBResourceManager"); + if (sref == null) { +// LOG.warn("Could not find service reference for DBLIB service (org.openecomp.sdnc.sli.resource.dblib.DBResourceManager)"); + } + else { + dblibSvc = (DbLibService)bctx.getService(sref); + if (dblibSvc == null) + { +// LOG.warn("Could not find service reference for DBLIB service (org.openecomp.sdnc.sli.resource.dblib.DBResourceManager)"); + } + } + return dblibSvc; + }*/ +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DefaultJdbcConnectionFactory.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DefaultJdbcConnectionFactory.java new file mode 100644 index 000000000..31db1e76e --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DefaultJdbcConnectionFactory.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dao.util; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +public abstract class DefaultJdbcConnectionFactory implements JdbcConnectionFactory { + + private static boolean driverRegistered = false; + + private String jdbcURL; + private String jdbcUserName; + private String jdbcPassword; + + public void setJdbcURL(String jdbcURL) { + this.jdbcURL = jdbcURL; + } + + public void setJdbcUserName(String jdbcUserName) { + this.jdbcUserName = jdbcUserName; + } + + public void setJdbcPassword(String jdbcPassword) { + this.jdbcPassword = jdbcPassword; + } + + + protected abstract void registedDriver() throws SQLException; + + @Override + public Connection openDbConnection() { + try { + if(!driverRegistered) { + registedDriver(); + driverRegistered = true; + } + return DriverManager.getConnection(jdbcURL, jdbcUserName, jdbcPassword); + } catch(SQLException e) { + throw new JdbcRuntimeException(Messages.EXP_JDBC_CONNECT.format(jdbcURL), e); + } + } + + @Override + public void closeDbConnection(Connection connection) { + try { + connection.close(); + } catch(SQLException e) { + throw new JdbcRuntimeException(Messages.EXP_JDBC_DISCONNECT.format(jdbcURL), e); + } + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcConnectionFactory.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcConnectionFactory.java new file mode 100644 index 000000000..3bd38320b --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcConnectionFactory.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dao.util; + +import java.sql.Connection; + +public interface JdbcConnectionFactory { + + Connection openDbConnection(); + void closeDbConnection(Connection connection); +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcRuntimeException.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcRuntimeException.java new file mode 100644 index 000000000..7b0682906 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcRuntimeException.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dao.util; + +public class JdbcRuntimeException extends RuntimeException { + + public JdbcRuntimeException(String message) { + super(message); + } + + public JdbcRuntimeException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/Messages.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/Messages.java new file mode 100644 index 000000000..8c97188bd --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/Messages.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.dao.util; + +public enum Messages { + EXP_JDBC_CONNECT("Error connecting to JDBC URL [%s]."), + EXP_JDBC_DISCONNECT("Error closing JDBC connection to URL [%s]."), + EXP_APPC_JDBC_CONNECT("Error connecting to JDBC using properties for schema [%s]"), + EXP_APPC_JDBC_DISCONNECT("Error closing JDBC connection for schema [%s]."); + + private String message; + + Messages(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + public String format(Object... s) { + return String.format(message, s); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/.gitignore b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/pom.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/pom.xml new file mode 100644 index 000000000..5722d18ea --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/pom.xml @@ -0,0 +1,36 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher-common</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>domain-model-lib</artifactId> + <packaging>bundle</packaging> + + <name>domain-model-lib</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Export-Package>org.openecomp.appc.domainmodel.lcm</Export-Package> + <Embed-Transitive>true</Embed-Transitive> + + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ActionIdentifiers.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ActionIdentifiers.java new file mode 100644 index 000000000..dc01e8f20 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ActionIdentifiers.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.domainmodel.lcm; + + +public class ActionIdentifiers { + private String serviceInstanceId; + private String vnfId; + private String vnfcName; + private String vServerId; + + public String getServiceInstanceId() { + return serviceInstanceId; + } + + public void setServiceInstanceId(String serviceInstanceId) { + this.serviceInstanceId = serviceInstanceId; + } + + public String getVnfId() { + return vnfId; + } + + public void setVnfId(String vnfId) { + this.vnfId = vnfId; + } + + public String getVnfcName() { + return vnfcName; + } + + public void setVnfcName(String vnfcName) { + this.vnfcName = vnfcName; + } + + public String getVserverId() { + return vServerId; + } + + public void setvServerId(String vServerId) { + this.vServerId = vServerId; + } + + @Override + public String toString() { + return "ActionIdentifiers{" + + "serviceInstanceId='" + serviceInstanceId + '\'' + + ", vnfId='" + vnfId + '\'' + + ", vnfcName='" + vnfcName + '\'' + + ", vServerId='" + vServerId + '\'' + + '}'; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/CommonHeader.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/CommonHeader.java new file mode 100644 index 000000000..0819a58d5 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/CommonHeader.java @@ -0,0 +1,95 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.domainmodel.lcm; + +import java.util.Date; + + +public class CommonHeader { + + private Flags flags; + private Date timestamp; + private String apiVer; + private String originatorId; + private String requestId; + private String subRequestId; + + public Flags getFlags() { + return flags; + } + + public void setFlags(Flags flags) { + this.flags = flags; + } + + public Date getTimeStamp() { + return timestamp; + } + + public void setTimestamp(Date timestamp) { + this.timestamp = timestamp; + } + + public String getApiVer() { + return apiVer; + } + + public void setApiVer(String apiVer) { + this.apiVer = apiVer; + } + + public String getOriginatorId() { + return originatorId; + } + + public void setOriginatorId(String originatorId) { + this.originatorId = originatorId; + } + + public String getRequestId() { + return requestId; + } + + public void setRequestId(String requestId) { + this.requestId = requestId; + } + + public String getSubRequestId() { + return subRequestId; + } + + public void setSubRequestId(String subRequestId) { + this.subRequestId = subRequestId; + } + + @Override + public String toString() { + return "CommonHeader{" + + "flags=" + flags + + ", timestamp=" + timestamp + + ", apiVer='" + apiVer + '\'' + + ", originatorId='" + originatorId + '\'' + + ", requestId='" + requestId + '\'' + + ", subRequestId='" + subRequestId + '\'' + + '}'; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Flags.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Flags.java new file mode 100644 index 000000000..4f4ddba35 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Flags.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.domainmodel.lcm; + + +public class Flags { + + private boolean force; + private int ttl; + private Mode mode; + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + + public int getTtl() { + return ttl; + } + + public void setTtl(int ttl) { + this.ttl = ttl; + } + + public Mode getMode() { + return mode; + } + + public void setMode(Mode mode) { + this.mode = mode; + } + + public void setMode(String mode) { + this.mode = Mode.valueOf(mode); + } + + @Override + public String toString() { + return "Flags{" + + "force=" + force + + ", ttl=" + ttl + + ", mode=" + mode + + '}'; + } + + public enum Mode { + EXCLUSIVE, + NORMAL + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RequestContext.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RequestContext.java new file mode 100644 index 000000000..c37262498 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RequestContext.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.domainmodel.lcm; + +import java.util.HashMap; +import java.util.Map; + + +public class RequestContext { + + private CommonHeader commonHeader; + private ActionIdentifiers actionIdentifiers; + private VNFOperation action; + private String payload; + private Map<String, String> additionalContext; + + public CommonHeader getCommonHeader() { + return commonHeader; + } + + public void setCommonHeader(CommonHeader commonHeader) { + this.commonHeader = commonHeader; + } + + public ActionIdentifiers getActionIdentifiers() { + return actionIdentifiers; + } + + public void setActionIdentifiers(ActionIdentifiers actionIdentifiers) { + this.actionIdentifiers = actionIdentifiers; + } + + public VNFOperation getAction() { + return action; + } + + public void setAction(VNFOperation action) { + this.action = action; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + public Map<String, String> getAdditionalContext() { + return additionalContext; + } + + public void setAdditionalContext(Map<String, String> additionalContext) { + this.additionalContext = additionalContext; + } + + public void addKeyValueToAdditionalContext(String key, String value ){ + if (this.additionalContext == null) { + this.additionalContext = new HashMap<>(); + } + this.additionalContext.put(key, value); + } + + @Override + public String toString() { + return "RequestContext{" + + "commonHeader=" + commonHeader + + ", actionIdentifiers=" + actionIdentifiers + + ", action=" + action + + ", payload='" + payload + '\'' + + ", additionalContext=" + additionalContext + + '}'; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ResponseContext.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ResponseContext.java new file mode 100644 index 000000000..81fba28ee --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ResponseContext.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.domainmodel.lcm; + +import java.util.HashMap; +import java.util.Map; + + +public class ResponseContext { + private CommonHeader commonHeader; + private Status status; + private String payload; + private Map<String, String> additionalContext; + + public CommonHeader getCommonHeader() { + return commonHeader; + } + + public void setCommonHeader(CommonHeader commonHeader) { + this.commonHeader = commonHeader; + } + + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + public Map<String, String> getAdditionalContext() { + return additionalContext; + } + + public void setAdditionalContext(Map<String, String> additionalContext) { + this.additionalContext = additionalContext; + } + + public void addKeyValueToAdditionalContext(String key, String value ){ + if (this.additionalContext == null) { + this.additionalContext = new HashMap<>(); + } + this.additionalContext.put(key, value); + } + + @Override + public String toString() { + return "ResponseContext{" + + "commonHeader=" + commonHeader + + ", status=" + status + + ", payload='" + payload + '\'' + + ", additionalContext=" + additionalContext + + '}'; + } + +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RuntimeContext.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RuntimeContext.java new file mode 100644 index 000000000..fd2bcffbf --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RuntimeContext.java @@ -0,0 +1,97 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.domainmodel.lcm; + +import java.util.Date; + + +public class RuntimeContext { + + private RequestContext requestContext; + private ResponseContext responseContext; + private VNFContext vnfContext; + + //TODO move fields timeStart abd isLockAcquired to a better place + private Date timeStart; + private boolean isLockAcquired; + private String rpcName; + + public String getRpcName() { + return rpcName; + } + + public void setRpcName(String rpcName) { + this.rpcName = rpcName; + } + + public Date getTimeStart() { + return timeStart; + } + + public boolean isLockAcquired() { + return isLockAcquired; + } + + public void setIsLockAcquired(boolean isLockAcquired) { + this.isLockAcquired = isLockAcquired; + } + + public void setTimeStart(Date timeStart) { + this.timeStart = timeStart; + } + + public RequestContext getRequestContext() { + return requestContext; + } + + public void setRequestContext(RequestContext requestContext) { + this.requestContext = requestContext; + } + + public ResponseContext getResponseContext() { + return responseContext; + } + + public void setResponseContext(ResponseContext responseContext) { + this.responseContext = responseContext; + } + + public VNFContext getVnfContext() { + return vnfContext; + } + + public void setVnfContext(VNFContext vnfContext) { + this.vnfContext = vnfContext; + } + + @Override + public String toString() { + return "RuntimeContext{" + + "requestContext=" + requestContext + + ", responseContext=" + responseContext + + ", vnfContext=" + vnfContext + + ", timeStart=" + timeStart + + ", isLockAcquired=" + isLockAcquired + + ", rpcName='" + rpcName + '\'' + + '}'; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Status.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Status.java new file mode 100644 index 000000000..a5fbefa9c --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Status.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.domainmodel.lcm; + + +public class Status { + + private int code; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String value) { + this.message = value; + } + + @Override + public String toString() { + return "Status{" + + "code='" + code + '\'' + + ", message='" + message + '\'' + + '}'; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFContext.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFContext.java new file mode 100644 index 000000000..4e2570139 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFContext.java @@ -0,0 +1,73 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.domainmodel.lcm; + + +public class VNFContext { + private String id; + private String type; + private String version; + private String status; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + + @Override + public String toString() { + return "VNFContext{" + + "id='" + id + '\'' + + ", type='" + type + '\'' + + ", version='" + version + '\'' + + ", status='" + status + '\'' + + '}'; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFOperation.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFOperation.java new file mode 100644 index 000000000..c61901eb3 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFOperation.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.domainmodel.lcm; + +public enum VNFOperation { + + Configure, Test, HealthCheck, Start, Terminate, Restart, Rebuild, Stop, ModifyConfig, Backup, Snapshot, + SoftwareUpload, LiveUpgrade, Rollback, Sync, Audit, Test_lic, Migrate, Evacuate, + Lock(true), Unlock(true), CheckLock(true); + + private boolean builtIn; + + VNFOperation(boolean builtIn) { + this.builtIn = builtIn; + } + + VNFOperation() { + this(false); + } + + /** + * Operations handled directly by the RequestHandler without further call to DG are built-in operations. + */ + public boolean isBuiltIn() { + return builtIn; + } + + public static VNFOperation findByString(String operationName) { + for(VNFOperation operation: VNFOperation.values()) { + if(operation.name().equals(operationName)) { + return operation; + } + } + return null; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.gitignore b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/pom.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/pom.xml new file mode 100644 index 000000000..cfa75c0b2 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/pom.xml @@ -0,0 +1,48 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher-common</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>execution-queue-management-lib</artifactId> + <packaging>bundle</packaging> + + <name>execution-queue-management-lib</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.att.eelf</groupId> + <artifactId>eelf-core</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Export-Package>org.openecomp.appc.executionqueue,org.openecomp.appc.executionqueue.impl</Export-Package> + <Import-Package>!groovy.lang,!javax.*,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.apache.commons.lang3,!org.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/ExecutionQueueService.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/ExecutionQueueService.java new file mode 100644 index 000000000..c93920083 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/ExecutionQueueService.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executionqueue; + +import java.util.concurrent.TimeUnit; + +import org.openecomp.appc.exceptions.APPCException; + +public interface ExecutionQueueService<M extends Runnable> { + void putMessage(M message) throws APPCException; + void putMessage(M message, long timeout, TimeUnit unit) throws APPCException; + void registerMessageExpirationListener(MessageExpirationListener listener); +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/MessageExpirationListener.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/MessageExpirationListener.java new file mode 100644 index 000000000..cd5cbeab1 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/MessageExpirationListener.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executionqueue; + +public interface MessageExpirationListener<M> { + void onMessageExpiration(M message); +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/helper/Util.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/helper/Util.java new file mode 100644 index 000000000..835e881aa --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/helper/Util.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executionqueue.helper; + +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; + +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; + +public class Util { + + private static final Configuration configuration = ConfigurationFactory.getConfiguration(); + + public static int DEFAULT_QUEUE_SIZE = 10; + public static int DEFAULT_THREADPOOL_SIZE = 10; + + public static int getExecutionQueSize(){ + String sizeStr = configuration.getProperty("appc.dispatcher.executionqueue.backlog.size", String.valueOf(DEFAULT_QUEUE_SIZE)); + int size = DEFAULT_QUEUE_SIZE; + try{ + size = Integer.parseInt(sizeStr); + } + catch (NumberFormatException e){ + + } + return size; + } + + public static int getThreadPoolSize(){ + String sizeStr = configuration.getProperty("appc.dispatcher.executionqueue.threadpool.size", String.valueOf(DEFAULT_THREADPOOL_SIZE)); + int size = DEFAULT_THREADPOOL_SIZE; + try{ + size = Integer.parseInt(sizeStr); + } + catch (NumberFormatException e){ + + } + return size; + } + + public static ThreadFactory getThreadFactory(final boolean isDaemon){ + return new ThreadFactory() { + final ThreadFactory factory = Executors.defaultThreadFactory(); + public Thread newThread(Runnable r) { + Thread t = factory.newThread(r); + t.setDaemon(isDaemon); + return t; + } + }; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceFactory.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceFactory.java new file mode 100644 index 000000000..01e4358e9 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceFactory.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executionqueue.impl; + +import org.openecomp.appc.executionqueue.ExecutionQueueService; + +public class ExecutionQueueServiceFactory { + + private static ExecutionQueueService executionQueueService =null; + + public static ExecutionQueueService getExecutionQueueService(){ + if(executionQueueService == null){ + synchronized (ExecutionQueueServiceFactory.class){ + if(executionQueueService == null) + executionQueueService = new ExecutionQueueServiceImpl(); + } + } + return executionQueueService; + } + +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceImpl.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceImpl.java new file mode 100644 index 000000000..c2be1b4ac --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceImpl.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executionqueue.impl; + +import java.util.Calendar; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.executionqueue.ExecutionQueueService; +import org.openecomp.appc.executionqueue.MessageExpirationListener; +import org.openecomp.appc.executionqueue.impl.object.QueueMessage; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +public class ExecutionQueueServiceImpl<M extends Runnable> implements ExecutionQueueService<M> { + + private static final EELFLogger logger = + EELFManager.getInstance().getLogger(ExecutionQueueServiceImpl.class); + + ExecutionQueueServiceImpl(){ + + } + + @Override + public void putMessage(M message) throws APPCException { + this.putMessage(message,-1,null); + } + + @Override + public void putMessage(M message, long timeout, TimeUnit unit) throws APPCException{ + QueueMessage queueMessage = null; + + try { + Date expirationTime = calculateExpirationTime(timeout,unit); + queueMessage = new QueueMessage(message,expirationTime); + QueueManager queueManager = QueueManager.getInstance(); + boolean enqueueTask = queueManager.enqueueTask(queueMessage); + if(!enqueueTask){ + throw new APPCException("failed to put message in queue"); + } + } catch (Exception e) { + logger.error("Error in putMessage method of ExecutionQueueServiceImpl" + e.getMessage()); + throw new APPCException(e); + } + } + + @Override + public void registerMessageExpirationListener(MessageExpirationListener listener) { + QueueManager.getInstance().setListener(listener); + } + + private Date calculateExpirationTime(long timeToLive, TimeUnit unit) { + Date expirationTime = null; + if(timeToLive > 0){ + long currentTime = System.currentTimeMillis(); + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(currentTime + unit.toMillis(timeToLive)); + expirationTime = cal.getTime(); + } + return expirationTime; + } + +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/QueueManager.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/QueueManager.java new file mode 100644 index 000000000..2d4907fa1 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/QueueManager.java @@ -0,0 +1,108 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executionqueue.impl; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; + +import org.openecomp.appc.executionqueue.MessageExpirationListener; +import org.openecomp.appc.executionqueue.helper.Util; +import org.openecomp.appc.executionqueue.impl.object.QueueMessage; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +public class QueueManager { + + private LinkedBlockingQueue<QueueMessage> queue; + + private MessageExpirationListener listener; + + private static int MAX_QUEUE_SIZE = Util.getExecutionQueSize(); + + private static int MAX_THREAD_SIZE = Util.getThreadPoolSize(); + + private ExecutorService messageExecutor; + + private static final EELFLogger logger = + EELFManager.getInstance().getLogger(QueueManager.class); + + private QueueManager(){ + init(); + } + + private static class QueueManagerHolder { + private static final QueueManager INSTANCE = new QueueManager(); + } + + public static QueueManager getInstance() { + return QueueManagerHolder.INSTANCE; + } + + private void init(){ + queue = new LinkedBlockingQueue(MAX_QUEUE_SIZE); + messageExecutor = Executors.newFixedThreadPool(MAX_THREAD_SIZE,Util.getThreadFactory(true)); + + for(int i=0;i<MAX_THREAD_SIZE;i++){ + messageExecutor.submit(new Runnable() { + @Override + public void run() { + while (true){ + try{ + QueueMessage queueMessage = queue.take(); + if(messageExpired(queueMessage)){ + logger.debug("Message expired "+ queueMessage.getMessage()); + if(listener != null){ + listener.onMessageExpiration(queueMessage.getMessage()); + } + else{ + logger.warn("Listener not available for expired message "); + } + } + else{ + queueMessage.getMessage().run(); + } + } catch (Exception e) { + logger.error("Error in startMessagePolling method of ExecutionQueueServiceImpl" + e.getMessage()); + } + } + } + }); + } + } + + public void setListener(MessageExpirationListener listener) { + this.listener = listener; + } + + public boolean enqueueTask(QueueMessage queueMessage) { + return queue.offer(queueMessage); + } + + private boolean messageExpired(QueueMessage queueMessage) { + if(queueMessage.getExpirationTime() != null){ + return queueMessage.getExpirationTime().getTime() < System.currentTimeMillis(); + } + return false; + } + +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/object/QueueMessage.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/object/QueueMessage.java new file mode 100644 index 000000000..bbf805871 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/object/QueueMessage.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executionqueue.impl.object; + +import java.util.Date; + + +public class QueueMessage<M extends Runnable> { + M message; + Date expirationTime; + public QueueMessage(M message, Date expirationTime){ + this.message = message; + this.expirationTime = expirationTime; + } + + public M getMessage() { + return message; + } + + public Date getExpirationTime() { + return expirationTime; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Listener.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Listener.java new file mode 100644 index 000000000..294ae61b1 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Listener.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executionqueue; + +import org.openecomp.appc.executionqueue.MessageExpirationListener; + + +public class Listener implements MessageExpirationListener { + + boolean listenerExecuted = false; + + public boolean isListenerExecuted() { + return listenerExecuted; + } + + @Override + public void onMessageExpiration(Object message) { + listenerExecuted = true; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Message.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Message.java new file mode 100644 index 000000000..61c847842 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Message.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executionqueue; + + +public class Message implements Runnable { + + boolean runExecuted = false; + + public boolean isRunExecuted() { + return runExecuted; + } + + @Override + public void run() { + this.runExecuted = true; + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/TestExecutionQueueService.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/TestExecutionQueueService.java new file mode 100644 index 000000000..a8a20c10a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/TestExecutionQueueService.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.executionqueue; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.executionqueue.ExecutionQueueService; +import org.openecomp.appc.executionqueue.impl.ExecutionQueueServiceFactory; +import org.powermock.api.mockito.PowerMockito; + +import java.util.concurrent.TimeUnit; + + +public class TestExecutionQueueService { + + @Test + public void testPositiveFlow(){ + Message message = new Message(); + ExecutionQueueService service = ExecutionQueueServiceFactory.getExecutionQueueService(); + try { + service.putMessage(message); + waitFor(5000); + Assert.assertTrue(message.isRunExecuted()); + } catch (APPCException e) { + Assert.fail(e.toString()); + } + } + +// @Test + public void testTimeout(){ + ExecutionQueueService service = ExecutionQueueServiceFactory.getExecutionQueueService(); + Message message = new Message(); + Listener listener = new Listener(); + service.registerMessageExpirationListener(listener); + try { + service.putMessage(message,1, TimeUnit.MILLISECONDS); + waitFor(5000); + Assert.assertTrue(listener.isListenerExecuted()); + } catch (APPCException e) { + e.printStackTrace(); + } + } + + private void waitFor(long milliSeconds){ + try { + Thread.sleep(milliSeconds); + } catch (InterruptedException e) { + Assert.fail(e.toString()); + } + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.gitignore b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.gitignore new file mode 100644 index 000000000..09e3bc9b2 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.gitignore b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/pom.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/pom.xml new file mode 100644 index 000000000..c5560ab1f --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/pom.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>lock-manager-lib</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + + <artifactId>lock-manager-api</artifactId> + <packaging>bundle</packaging> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Export-Package>org.openecomp.appc.lockmanager.api</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockException.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockException.java new file mode 100644 index 000000000..c5a94f9e1 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockException.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lockmanager.api; + + +public class LockException extends Exception { + + public LockException(String message) { + super(message); + } + + public LockException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockManager.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockManager.java new file mode 100644 index 000000000..eebe5e24f --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockManager.java @@ -0,0 +1,69 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lockmanager.api; + +/** + * Enables locking and unlocking of a resource by id. + * If the resource is locked, only lock owner can reacquire the lock or unlock the resource. + */ +public interface LockManager { + + /** + * Lock resource without timeout. Lock never expires. + * + * @param resource resource id + * @param owner lock owner id + * @return true - if lock is acquired, false - if the resource was already locked by the owner + * @throws LockException thrown if resource is already locked by other owner + */ + boolean acquireLock(String resource, String owner) throws LockException; + + /** + * Lock resource with timeout. After the timeout resource becomes unlocked. + * + * @param resource resource id + * @param owner lock owner id + * @param timeout in milliseconds, after this timeout lock will expire and resource becomes unlocked, + * timeout == 0 means that the lock never expires - same as call acquireLock() without timeout parameter + * @return true - if lock is acquired, false - if the resource was already locked by the owner + * @throws LockException thrown if resource is already locked by other owner + */ + boolean acquireLock(String resource, String owner, long timeout) throws LockException; + + /** + * Unlock resource. + * + * @param resource resource id + * @param owner lock owner id + * @throws LockException thrown if resource is locked by other owner + */ + void releaseLock(String resource, String owner) throws LockException; + + /** + * check resource lock status. + * + * @param resource resource id + */ + + boolean isLocked(String resource); + +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockRuntimeException.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockRuntimeException.java new file mode 100644 index 000000000..682cd6e27 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockRuntimeException.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lockmanager.api; + +public class LockRuntimeException extends RuntimeException { + + public LockRuntimeException(String message) { + super(message); + } + + public LockRuntimeException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/.gitignore b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/pom.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/pom.xml new file mode 100644 index 000000000..560661dfb --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/pom.xml @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>lock-manager-lib</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <name>lock-manager-features</name> + <artifactId>lock-manager-features</artifactId> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>lock-manager-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>lock-manager-impl</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <!--<plugin> + <!– launches the feature test, which validates that your karaf feature + can be installed inside of a karaf container. It doesn't validate that your + functionality works correctly, just that you have all of the dependent bundles + defined correctly. –> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.16</version> + <configuration> + <systemPropertyVariables> + <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId> + <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId> + <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version> + </systemPropertyVariables> + <dependenciesToScan> + <dependency>org.opendaylight.yangtools:features-test</dependency> + </dependenciesToScan> + <classpathDependencyExcludes> + <!– The dependencies which bring in AbstractDataBrokerTest class + brings in a second PaxExam container which results in the feature tests failing + with a message similar to: "ERROR o.ops4j.pax.exam.spi.PaxExamRuntime - Ambiguous + TestContainer ..." This excludes the container we don't want to use. –> + <classpathDependencyExcludes>org.ops4j.pax.exam:pax-exam-container-native</classpathDependencyExcludes> + </classpathDependencyExcludes> + </configuration> + </plugin>--> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + + <!-- Skipping ODL feature test --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <skipTests>true</skipTests> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/src/main/resources/features.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/src/main/resources/features.xml new file mode 100644 index 000000000..ed51ca775 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/src/main/resources/features.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="lock-manager-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + + <feature name='lock-manager' description="lock-manager" version='${project.version}'> + <bundle start-level="80" start="true">mvn:org.openecomp.appc/lock-manager-api/${project.version}</bundle> + <bundle start-level="85" start="true">mvn:org.openecomp.appc/lock-manager-impl/${project.version}</bundle> + </feature> + +</features> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.gitignore b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.gitignore new file mode 100644 index 000000000..09e3bc9b2 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/pom.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/pom.xml new file mode 100644 index 000000000..8ca41399a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/pom.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>lock-manager-lib</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + + <artifactId>lock-manager-impl</artifactId> + <packaging>bundle</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>lock-manager-api</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + <version>${mysql.connector.version}</version> + <type>jar</type> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-data-access-lib</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.att.eelf</groupId> + <artifactId>eelf-core</artifactId> + <version>${eelf.version}</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Export-Service>org.openecomp.appc.lockmanager.api.LockManager</Export-Service> + <Import-Package>org.openecomp.appc.lockmanager.api.*,*</Import-Package> + <Private-Package>org.openecomp.appc.lockmanager.impl.*</Private-Package> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Import-Package>!org.apache.log,!org.apache.commons.logging,!groovy.lang,!javax.jms,!javax.mail.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.jasypt.*,*</Import-Package> + <Embed-Dependency>appc-common,appc-data-access-lib,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImpl.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImpl.java new file mode 100644 index 000000000..309e2790c --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImpl.java @@ -0,0 +1,130 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lockmanager.impl.inmemory; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.openecomp.appc.lockmanager.api.LockException; +import org.openecomp.appc.lockmanager.api.LockManager; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + + +public class LockManagerInMemoryImpl implements LockManager { + + private static LockManagerInMemoryImpl instance = null; + private Map<String, LockValue> lockedVNFs; + + private static final EELFLogger debugLogger = EELFManager.getInstance().getDebugLogger(); + + private LockManagerInMemoryImpl() { + lockedVNFs = new ConcurrentHashMap<>(); + } + + public static LockManager getLockManager() { + if(instance == null) { + instance = new LockManagerInMemoryImpl(); + } + return instance; + } + + @Override + public boolean acquireLock(String resource, String owner) throws LockException { + return acquireLock(resource, owner, 0); + } + + @Override + public boolean acquireLock(String resource, String owner, long timeout) throws LockException { + debugLogger.debug("Try to acquire lock on resource " + resource + " with owner " + owner); + long now = System.currentTimeMillis(); + LockValue lockValue = lockedVNFs.get(resource); + if (lockValue != null) { + if (lockIsMine(lockValue, owner, now) || hasExpired(lockValue, now)) { + setExpirationTime(resource, owner, timeout, now); + debugLogger.debug("Locked successfully resource " + resource + " with owner " + owner + " for " + timeout + " ms"); + return hasExpired(lockValue, now); + } + else { + debugLogger.debug("Owner " + owner + " tried to lock resource " + resource + " but it is already locked by owner " + lockValue.getOwner()); + throw new LockException("Owner " + owner + " tried to lock resource " + resource + " but it is already locked by owner " + lockValue.getOwner()); + } + } + else { + setExpirationTime(resource, owner, timeout, now); + debugLogger.debug("Locked successfully resource " + resource + " with owner " + owner + " for " + timeout + " ms"); + return true; + } + } + + @Override + public void releaseLock(String resource, String owner) throws LockException { + debugLogger.debug("Try to release lock on resource " + resource + " with owner " + owner); + long now = System.currentTimeMillis(); + LockValue lockValue = lockedVNFs.get(resource); + if (lockValue != null) { + if (!hasExpired(lockValue, now)) { + if (isOwner(lockValue, owner)) { + debugLogger.debug("Unlocked successfully resource " + resource + " with owner " + owner); + lockedVNFs.remove(resource); + } + else { + debugLogger.debug("Unlock failed. Tried to release lock on resource " + resource + " from owner " + owner + " but it is held by a different owner"); + throw new LockException("Unlock failed. Tried to release lock on resource " + resource + " from owner " + owner + " but it is held by a different owner"); + } + } + else { + lockedVNFs.remove(resource); + debugLogger.debug("Unlock failed. lock on resource " + resource + " has expired"); + throw new LockException("Unlock failed. lock on resource " + resource + " has expired"); + } + + } + else { + debugLogger.debug("Tried to release lock on resource " + resource + " from owner " + owner + " but there is not lock on this resource"); + throw new LockException("Tried to release lock on resource " + resource + " from owner " + owner + " but there is not lock on this resource"); + } + } + + @Override + public boolean isLocked(String resource) { + return lockedVNFs.get(resource)!=null?true:false; + } + + private boolean lockIsMine(LockValue lockValue, String owner, long now) { + return isOwner(lockValue, owner) && !hasExpired(lockValue, now); + } + + private boolean isOwner(LockValue lockValue, String owner) { + return lockValue.getOwner() != null && lockValue.getOwner().equals(owner); + } + + private boolean hasExpired(LockValue lockValue, long now) { + return (lockValue.getExpirationTime() != 0 && now > lockValue.getExpirationTime()); + } + + private void setExpirationTime(String resource, String owner, long timeout, long now) { + long expirationTime = timeout == 0 ? 0 : now + timeout; + LockValue lockValue = new LockValue(owner, expirationTime); + lockedVNFs.put(resource, lockValue); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockValue.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockValue.java new file mode 100644 index 000000000..abdd494d9 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockValue.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lockmanager.impl.inmemory; + + +public class LockValue { + + private String owner; + private long expirationTime; + + LockValue(String owner, long expirationTime) { + this.owner = owner; + this.expirationTime = expirationTime; + } + + String getOwner() { + return owner; + } + + long getExpirationTime() { + return expirationTime; + } + +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/JdbcLockManager.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/JdbcLockManager.java new file mode 100644 index 000000000..97a5cc339 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/JdbcLockManager.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lockmanager.impl.sql; + +import java.sql.Connection; + +import org.openecomp.appc.dao.util.JdbcConnectionFactory; +import org.openecomp.appc.lockmanager.api.LockManager; + +public abstract class JdbcLockManager implements LockManager { + + private static final String DEF_TABLE_LOCK_MANAGEMENT = "LOCK_MANAGEMENT"; + + private JdbcConnectionFactory connectionFactory; + protected String tableName = DEF_TABLE_LOCK_MANAGEMENT; + + public void setConnectionFactory(JdbcConnectionFactory connectionFactory) { + this.connectionFactory = connectionFactory; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + + protected Connection openDbConnection() { + return connectionFactory.openDbConnection(); + } + + protected void closeDbConnection(Connection connection) { + connectionFactory.closeDbConnection(connection); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/Messages.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/Messages.java new file mode 100644 index 000000000..0399726b5 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/Messages.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lockmanager.impl.sql; + +public enum Messages { + + ERR_NULL_LOCK_OWNER("Cannot acquire lock for resource [%s]: lock owner must be specified"), + ERR_LOCK_LOCKED_BY_OTHER("Cannot lock resource [%s] for [%s]: already locked by [%s]"), + ERR_UNLOCK_NOT_LOCKED("Error unlocking resource [%s]: resource is not locked"), + ERR_UNLOCK_LOCKED_BY_OTHER("Error unlocking resource [%s] by [%s]: resource is locked by [%s]"), + EXP_LOCK("Error locking resource [%s]."), + EXP_UNLOCK("Error unlocking resource [%s]."), + ; + + private String message; + + Messages(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + public String format(Object... s) { + return String.format(message, s); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/MySqlConnectionFactory.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/MySqlConnectionFactory.java new file mode 100644 index 000000000..4ccd0c453 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/MySqlConnectionFactory.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lockmanager.impl.sql; + +import java.sql.DriverManager; +import java.sql.SQLException; + +import org.openecomp.appc.dao.util.DefaultJdbcConnectionFactory; + +public class MySqlConnectionFactory extends DefaultJdbcConnectionFactory { + + protected void registedDriver() throws SQLException { + DriverManager.registerDriver(new com.mysql.jdbc.Driver()); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/LockRecord.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/LockRecord.java new file mode 100644 index 000000000..d66804488 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/LockRecord.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lockmanager.impl.sql.optimistic; + +class LockRecord { + + private String resource; + private String owner; + private long updated; + private long timeout; + private long ver; + + LockRecord(String resource) { + this.resource = resource; + } + + public String getResource() { + return resource; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public long getUpdated() { + return updated; + } + + public void setUpdated(long updated) { + this.updated = updated; + } + + public long getTimeout() { + return timeout; + } + + public void setTimeout(long timeout) { + this.timeout = timeout; + } + + public long getVer() { + return ver; + } + + public void setVer(long ver) { + this.ver = ver; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManager.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManager.java new file mode 100644 index 000000000..e80133620 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManager.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lockmanager.impl.sql.optimistic; + +import java.sql.SQLException; + +public class MySqlLockManager extends SqlLockManager { + + @Override + protected boolean isDuplicatePkError(SQLException e) { + return (e.getErrorCode() == 1062); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/SqlLockManager.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/SqlLockManager.java new file mode 100644 index 000000000..52c75d2b2 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/SqlLockManager.java @@ -0,0 +1,263 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lockmanager.impl.sql.optimistic; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.openecomp.appc.lockmanager.api.LockException; +import org.openecomp.appc.lockmanager.api.LockRuntimeException; +import org.openecomp.appc.lockmanager.impl.sql.JdbcLockManager; +import org.openecomp.appc.lockmanager.impl.sql.Messages; + +abstract class SqlLockManager extends JdbcLockManager { + + private static final String SQL_LOAD_LOCK_RECORD = "SELECT * FROM %s WHERE RESOURCE_ID=?"; + private static final String SQL_INSERT_LOCK_RECORD = "INSERT INTO %s (RESOURCE_ID, OWNER_ID, UPDATED, TIMEOUT, VER) VALUES (?, ?, ?, ?, ?)"; + private static final String SQL_UPDATE_LOCK_RECORD = "UPDATE %s SET OWNER_ID=?, UPDATED=?, TIMEOUT=?, VER=? WHERE RESOURCE_ID=? AND VER=?"; +// private static final String SQL_DELETE_LOCK_RECORD = "DELETE FROM %s WHERE RESOURCE_ID=? AND VER=?"; + private static final String SQL_CURRENT_TIMESTAMP = "SELECT CURRENT_TIMESTAMP()"; + + private String sqlLoadLockRecord; + private String sqlInsertLockRecord; + private String sqlUpdateLockRecord; +// private String sqlDeleteLockRecord; + + @Override + public boolean acquireLock(String resource, String owner) throws LockException { + return acquireLock(resource, owner, 0); + } + + @Override + public boolean acquireLock(String resource, String owner, long timeout) throws LockException { + if(owner == null) { + throw new LockRuntimeException(Messages.ERR_NULL_LOCK_OWNER.format(resource)); + } + boolean res = false; + Connection connection = openDbConnection(); + try { + res = lockResource(connection, resource, owner, timeout); + } finally { + closeDbConnection(connection); + } + return res; + } + + @Override + public void releaseLock(String resource, String owner) throws LockException { + Connection connection = openDbConnection(); + try { + unlockResource(connection, resource, owner); + } finally { + closeDbConnection(connection); + } + } + + @Override + public boolean isLocked(String resource) { + Connection connection=openDbConnection(); + try { + LockRecord lockRecord=loadLockRecord(connection,resource); + if(lockRecord==null){ + return false; + }else{ + if(lockRecord.getOwner()==null){ + return false; + }else if(isLockExpired(lockRecord, connection)){ + return false; + }else{ + return true; + } + } + } catch (SQLException e) { + throw new LockRuntimeException(Messages.EXP_LOCK.format(resource)); + }finally { + closeDbConnection(connection); + } + } + + private boolean lockResource(Connection connection, String resource, String owner, long timeout) throws LockException { + try { + boolean res = false; + LockRecord lockRecord = loadLockRecord(connection, resource); + if(lockRecord != null) { + // lock record already exists + String currentOwner = lockRecord.getOwner(); + if(currentOwner != null) { + if(isLockExpired(lockRecord, connection)) { + currentOwner = null; + } else if(!owner.equals(currentOwner)) { + throw new LockException(Messages.ERR_LOCK_LOCKED_BY_OTHER.format(resource, owner, currentOwner)); + } + } + // set new owner on the resource lock record + if(!updateLockRecord(connection, resource, owner, timeout, lockRecord.getVer())) { + // try again - maybe same owner updated the record + lockResource(connection, resource, owner, timeout); + } + if(currentOwner == null) { + // no one locked the resource before + res = true; + } + } else { + // resource record does not exist in lock table => create new record + try { + addLockRecord(connection, resource, owner, timeout); + res = true; + } catch(SQLException e) { + if(isDuplicatePkError(e)) { + // try again - maybe same owner inserted the record + lockResource(connection, resource, owner, timeout); + } else { + throw e; + } + } + } + return res; + } catch(SQLException e) { + throw new LockRuntimeException(Messages.EXP_LOCK.format(resource), e); + } + } + + protected boolean isDuplicatePkError(SQLException e) { + return e.getSQLState().startsWith("23"); + } + + private void unlockResource(Connection connection, String resource, String owner) throws LockException { + try { + LockRecord lockRecord = loadLockRecord(connection, resource); + if(lockRecord != null) { + // check if expired + if(isLockExpired(lockRecord, connection)) { + // lock is expired => no lock + lockRecord = null; + } + } + if((lockRecord == null) || (lockRecord.getOwner() == null)) { + // resource is not locked + throw new LockException(Messages.ERR_UNLOCK_NOT_LOCKED.format(resource)); + } + String currentOwner = lockRecord.getOwner(); + if(!owner.equals(currentOwner)) { + throw new LockException(Messages.ERR_UNLOCK_LOCKED_BY_OTHER.format(resource, owner, currentOwner)); + } + if (!updateLockRecord(connection, resource, null, 0, lockRecord.getVer())) { + unlockResource(connection, resource, owner); + } + // TODO delete record from table on lock release? +// deleteLockRecord(connection, resource, lockRecord.getVer()); + } catch(SQLException e) { + throw new LockRuntimeException(Messages.EXP_UNLOCK.format(resource), e); + } + } + + protected LockRecord loadLockRecord(Connection connection, String resource) throws SQLException { + LockRecord res = null; + if(sqlLoadLockRecord == null) { + sqlLoadLockRecord = String.format(SQL_LOAD_LOCK_RECORD, tableName); + } + try(PreparedStatement statement = connection.prepareStatement(sqlLoadLockRecord)) { + statement.setString(1, resource); + try(ResultSet resultSet = statement.executeQuery()) { + if(resultSet.next()) { + res = new LockRecord(resource); + res.setOwner(resultSet.getString(2)); + res.setUpdated(resultSet.getLong(3)); + res.setTimeout(resultSet.getLong(4)); + res.setVer(resultSet.getLong(5)); + } + } + } + return res; + } + + protected void addLockRecord(Connection connection, String resource, String owner, long timeout) throws SQLException { + if(sqlInsertLockRecord == null) { + sqlInsertLockRecord = String.format(SQL_INSERT_LOCK_RECORD, tableName); + } + try(PreparedStatement statement = connection.prepareStatement(sqlInsertLockRecord)) { + statement.setString(1, resource); + statement.setString(2, owner); + statement.setLong(3, getCurrentTime(connection)); + statement.setLong(4, timeout); + statement.setLong(5, 1); + statement.executeUpdate(); + } + } + + protected boolean updateLockRecord(Connection connection, String resource, String owner, long timeout, long ver) throws SQLException { + if(sqlUpdateLockRecord == null) { + sqlUpdateLockRecord = String.format(SQL_UPDATE_LOCK_RECORD, tableName); + } + try(PreparedStatement statement = connection.prepareStatement(sqlUpdateLockRecord)) { + long newVer = (ver >= Long.MAX_VALUE) ? 1 : (ver + 1); + statement.setString(1, owner); + statement.setLong(2, getCurrentTime(connection)); + statement.setLong(3, timeout); + statement.setLong(4, newVer); + statement.setString(5, resource); + statement.setLong(6, ver); + return (statement.executeUpdate() != 0); + } + } + +// protected void deleteLockRecord(Connection connection, String resource, long ver) throws SQLException { +// if(sqlDeleteLockRecord == null) { +// sqlDeleteLockRecord = String.format(SQL_DELETE_LOCK_RECORD, tableName); +// } +// try(PreparedStatement statement = connection.prepareStatement(sqlDeleteLockRecord)) { +// statement.setString(1, resource); +// statement.setLong(2, ver); +// statement.executeUpdate(); +// } +// } + + private boolean isLockExpired(LockRecord lockRecord, Connection connection) throws SQLException { + long timeout = lockRecord.getTimeout(); + if(timeout == 0) { + return false; + } + long updated = lockRecord.getUpdated(); + long now = getCurrentTime(connection); + long expiration = updated + timeout; + return (now > expiration); + } + + private long getCurrentTime(Connection connection) throws SQLException { + long res = -1; + if(connection != null) { + try(PreparedStatement statement = connection.prepareStatement(SQL_CURRENT_TIMESTAMP)) { + try(ResultSet resultSet = statement.executeQuery()) { + if(resultSet.next()) { + res = resultSet.getTimestamp(1).getTime(); + } + } + } + } + if(res == -1) { + res = System.currentTimeMillis(); + } + return res; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..6ec23eeb0 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + + <!--<bean id="lockManagerInMemoryBean" class="org.openecomp.appc.lockmanager.impl.inmemory.LockManagerInMemoryImpl" factory-method="getLockManager" scope="singleton"/>--> + <!--<service id="lockManagerInMemoryService" interface="org.openecomp.appc.lockmanager.api.LockManager" ref="lockManagerInMemoryBean"/>--> + + <service id="lockManagerMySqlOptimisticService" interface="org.openecomp.appc.lockmanager.api.LockManager"> + <bean class="org.openecomp.appc.lockmanager.impl.sql.optimistic.MySqlLockManager"> + <property name="connectionFactory"> + <bean class="org.openecomp.appc.dao.util.AppcJdbcConnectionFactory"> + <property name="schema" value="sdnctl"/> + </bean> + </property> + <property name="tableName" value="VNF_LOCK_MANAGEMENT"/> + </bean> + </service> +</blueprint> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/api/LockManagerBaseTests.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/api/LockManagerBaseTests.java new file mode 100644 index 000000000..47e27f79d --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/api/LockManagerBaseTests.java @@ -0,0 +1,167 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lockmanager.api; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openecomp.appc.lockmanager.api.LockException; +import org.openecomp.appc.lockmanager.api.LockManager; + +public abstract class LockManagerBaseTests { + + protected enum Resource {Resource1, Resource2}; + protected enum Owner {A, B}; + + protected LockManager lockManager; + + @Before + public void beforeTest() { + lockManager = createLockManager(); + } + + protected abstract LockManager createLockManager(); + + @Test + public void testAcquireLock() throws LockException { + boolean lockRes = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + try { + Assert.assertTrue(lockRes); + } finally { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + } + + @Test + public void testAcquireLock_AlreadyLockedBySameOwner() throws LockException { + boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + try { + Assert.assertTrue(lockRes1); + boolean lockRes2 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + Assert.assertFalse(lockRes2); + } finally { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + } + + @Test(expected = LockException.class) + public void testAcquireLock_AlreadyLockedByOtherOwner() throws LockException { + String owner2 = "B"; + boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + try { + Assert.assertTrue(lockRes1); + boolean lockRes2 = lockManager.acquireLock(Resource.Resource1.name(), owner2); + Assert.assertFalse(lockRes2); + } finally { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + } + + @Test + public void testAcquireLock_LockDifferentResources() throws LockException { + boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + try { + Assert.assertTrue(lockRes1); + boolean lockRes2 = lockManager.acquireLock(Resource.Resource2.name(), Owner.B.name()); + try { + Assert.assertTrue(lockRes2); + } finally { + lockManager.releaseLock(Resource.Resource2.name(), Owner.B.name()); + } + } finally { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + } + + @Test(expected = LockException.class) + public void testReleaseLock_NotLockedResource() throws LockException { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + + @Test(expected = LockException.class) + public void testReleaseLock_LockedByOtherOwnerResource() throws LockException { + boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + try { + Assert.assertTrue(lockRes1); + lockManager.releaseLock(Resource.Resource1.name(), Owner.B.name()); + } finally { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + } + + @Test(expected = LockException.class) + public void testAcquireLock_LockExpired() throws LockException, InterruptedException { + boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name(), 50); + Assert.assertTrue(lockRes1); + Thread.sleep(1000); + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + + @Test + public void testAcquireLock_OtherLockExpired() throws LockException, InterruptedException { + boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name(), 50); + Assert.assertTrue(lockRes1); + Thread.sleep(1000); + boolean lockRes2 = lockManager.acquireLock(Resource.Resource1.name(), Owner.B.name()); + try { + Assert.assertTrue(lockRes2); + }finally { + lockManager.releaseLock(Resource.Resource1.name(), Owner.B.name()); + } + } + + @Test + public void testIsLocked_WhenLocked() throws LockException, InterruptedException { + boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name(), 50); + try { + Assert.assertTrue(lockManager.isLocked(Resource.Resource1.name())); + }finally { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + } + + + @Test(expected = LockException.class) + public void testIsLocked_LockExpired() throws LockException, InterruptedException { + boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name(), 50); + Assert.assertTrue(lockRes1); + Assert.assertTrue(lockManager.isLocked(Resource.Resource1.name())); + Thread.sleep(1000); + try { + Assert.assertFalse(lockManager.isLocked(Resource.Resource1.name())); + }finally { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + } + + @Test + public void testIsLocked_LockReleased() throws LockException, InterruptedException { + boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name(), 50); + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + Assert.assertFalse(lockManager.isLocked(Resource.Resource1.name())); + } + + @Test + public void testIsLocked_NoLock() throws LockException, InterruptedException { + Assert.assertFalse(lockManager.isLocked(Resource.Resource1.name())); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImplTest.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImplTest.java new file mode 100644 index 000000000..99faec23d --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImplTest.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lockmanager.impl.inmemory; + +import org.openecomp.appc.lockmanager.api.LockManager; +import org.openecomp.appc.lockmanager.api.LockManagerBaseTests; +import org.openecomp.appc.lockmanager.impl.inmemory.LockManagerInMemoryImpl; + + +public class LockManagerInMemoryImplTest extends LockManagerBaseTests { + + @Override + protected LockManager createLockManager() { + return LockManagerInMemoryImpl.getLockManager(); + } + +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/MySqlLockManagerBaseTests.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/MySqlLockManagerBaseTests.java new file mode 100644 index 000000000..da5607819 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/MySqlLockManagerBaseTests.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lockmanager.impl.sql; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.appc.dao.util.DefaultJdbcConnectionFactory; +import org.openecomp.appc.lockmanager.api.LockManager; +import org.openecomp.appc.lockmanager.api.LockManagerBaseTests; +import org.openecomp.appc.lockmanager.impl.sql.JdbcLockManager; +import org.openecomp.appc.lockmanager.impl.sql.MySqlConnectionFactory; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +public abstract class MySqlLockManagerBaseTests extends LockManagerBaseTests { + + private static final boolean USE_REAL_DB = Boolean.getBoolean("lockmanager.tests.useRealDb"); + private static final String TABLE_LOCK_MANAGEMENT = "TEST_LOCK_MANAGEMENT"; + private static final String JDBC_URL = System.getProperty("lockmanager.tests.jdbcUrl", "jdbc:mysql://192.168.1.2/test"); + private static final String JDBC_USERNAME = System.getProperty("lockmanager.tests.jdbcUsername", "test"); + private static final String JDBC_PASSWORD = System.getProperty("lockmanager.tests.jdbcPassword", "123456"); + + protected static final int CONCURRENT_TEST_WAIT_TIME = 10; // secs + + @Rule + public TestName testName = new TestName(); + + @Override + protected LockManager createLockManager() { + JdbcLockManager jdbcLockManager = createJdbcLockManager(USE_REAL_DB); + DefaultJdbcConnectionFactory connectionFactory = new MySqlConnectionFactory(); + connectionFactory.setJdbcURL(JDBC_URL); + connectionFactory.setJdbcUserName(JDBC_USERNAME); + connectionFactory.setJdbcPassword(JDBC_PASSWORD); + jdbcLockManager.setConnectionFactory(connectionFactory); + jdbcLockManager.setTableName(TABLE_LOCK_MANAGEMENT); + System.out.println("=> Running LockManager test [" + jdbcLockManager.getClass().getName() + "." + testName.getMethodName() + "]" + (USE_REAL_DB ? ". JDBC URL is [" + JDBC_URL + "]" : "")); + clearTestLocks(jdbcLockManager); + return jdbcLockManager; + } + + protected abstract JdbcLockManager createJdbcLockManager(boolean useRealDb); + + protected boolean setSynchronizer(Synchronizer synchronizer) { + if(!(lockManager instanceof SynchronizerReceiver)) { + System.err.println("Skipping concurrency test [" + testName.getMethodName() + "] for LockManager of type " + lockManager.getClass()); + return false; + } + ((SynchronizerReceiver)lockManager).setSynchronizer(synchronizer); + return true; + } + + private static final String SQL_DELETE_LOCK_RECORD = String.format("DELETE FROM %s WHERE RESOURCE_ID=?", TABLE_LOCK_MANAGEMENT); + private void clearTestLocks(JdbcLockManager jdbcLockManager) { + Connection connection = jdbcLockManager.openDbConnection(); + if(connection == null) { + return; + } + try { + for(Resource resource: Resource.values()) { + try(PreparedStatement statement = connection.prepareStatement(SQL_DELETE_LOCK_RECORD)) { + statement.setString(1, resource.name()); + statement.executeUpdate(); + } + } + } catch(SQLException e) { + throw new RuntimeException("Cannot clear test resources in table", e); + } finally { + jdbcLockManager.closeDbConnection(connection); + } + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/Synchronizer.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/Synchronizer.java new file mode 100644 index 000000000..8d1f0bbfd --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/Synchronizer.java @@ -0,0 +1,80 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lockmanager.impl.sql; + +public class Synchronizer { + + private int participantNo; + private int participantCount; + + public Synchronizer(int participantNo) { + this.participantNo = participantNo; + } + + public int getParticipantCount() { + return participantCount; + } + + public void postLoadLockRecord(String resource, String owner) { + synchronized(this) { + waitForAllParticipants(this, participantNo, ++participantCount); + } + } + + public void preAddLockRecord(String resource, String owner) { + } + + public void postAddLockRecord(String resource, String owner) { + } + + public void preUpdateLockRecord(String resource, String owner) { + } + + public void postUpdateLockRecord(String resource, String owner) { + } + + public void releaseWait() { + synchronized(this) { + this.notifyAll(); + } + } + + protected void waitOn(Object obj, long timeout) { + try { + obj.wait(timeout); + } catch(InterruptedException e) { + throw new RuntimeException(e); + } + } + + protected void waitOn(Object obj) { + waitOn(obj, 0); + } + + protected void waitForAllParticipants(Object waitObj, int totalParticipantsNo, int currentParticipantsNo) { + if(totalParticipantsNo > currentParticipantsNo) { + waitOn(waitObj); + } else { + waitObj.notifyAll(); + } + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/SynchronizerReceiver.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/SynchronizerReceiver.java new file mode 100644 index 000000000..945fed10b --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/SynchronizerReceiver.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lockmanager.impl.sql; + +public interface SynchronizerReceiver { + + void setSynchronizer(Synchronizer synchronizer); +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManagerMock.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManagerMock.java new file mode 100644 index 000000000..3e6a236ba --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManagerMock.java @@ -0,0 +1,132 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lockmanager.impl.sql.optimistic; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.openecomp.appc.lockmanager.impl.sql.Synchronizer; +import org.openecomp.appc.lockmanager.impl.sql.SynchronizerReceiver; +import org.openecomp.appc.lockmanager.impl.sql.optimistic.LockRecord; +import org.openecomp.appc.lockmanager.impl.sql.optimistic.MySqlLockManager; + +class MySqlLockManagerMock extends MySqlLockManager implements SynchronizerReceiver { + + private final ConcurrentMap<String, LockRecord> locks = new ConcurrentHashMap<>(); + private boolean useReal; + private Synchronizer synchronizer; + + MySqlLockManagerMock(boolean useReal) { + this.useReal = useReal; + } + + @Override + public void setSynchronizer(Synchronizer synchronizer) { + this.synchronizer = synchronizer; + } + + @Override + protected Connection openDbConnection() { + if(useReal) { + return super.openDbConnection(); + } + return null; + } + + @Override + protected void closeDbConnection(Connection connection) { + if(useReal) { + super.closeDbConnection(connection); + } + } + + @Override + protected LockRecord loadLockRecord(Connection connection, String resource) throws SQLException { + LockRecord res; + if(useReal) { + res = super.loadLockRecord(connection, resource); + } else { + res = locks.get(resource); + } + if(synchronizer != null) { + synchronizer.postLoadLockRecord(resource, (res == null) ? null : res.getOwner()); + } + return res; + } + + @Override + protected void addLockRecord(Connection connection, String resource, String owner, long timeout) throws SQLException { + if(synchronizer != null) { + synchronizer.preAddLockRecord(resource, owner); + } + try { + if(useReal) { + super.addLockRecord(connection, resource, owner, timeout); + return; + } + LockRecord lockRecord = new LockRecord(resource); + lockRecord.setOwner(owner); + lockRecord.setUpdated(System.currentTimeMillis()); + lockRecord.setTimeout(timeout); + lockRecord.setVer(1); + LockRecord prevLockRecord = locks.putIfAbsent(resource, lockRecord); + if(prevLockRecord != null) { + // simulate unique constraint violation + throw new SQLException("Duplicate PK exception", "23000", 1062); + } + } finally { + if(synchronizer != null) { + synchronizer.postAddLockRecord(resource, owner); + } + } + } + + @Override + protected boolean updateLockRecord(Connection connection, String resource, String owner, long timeout, long ver) throws SQLException { + if(synchronizer != null) { + synchronizer.preUpdateLockRecord(resource, owner); + } + try { + if(useReal) { + return super.updateLockRecord(connection, resource, owner, timeout, ver); + } + LockRecord lockRecord = loadLockRecord(connection, resource); + synchronized(lockRecord) { + // should be atomic operation + if(ver != lockRecord.getVer()) { + return false; + } + lockRecord.setOwner(owner); + lockRecord.setUpdated(System.currentTimeMillis()); + lockRecord.setTimeout(timeout); + lockRecord.setVer(ver + 1); + } + return true; + } finally { + if(synchronizer != null) { + synchronizer.postUpdateLockRecord(resource, owner); + } + } + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/TestMySqlLockManager.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/TestMySqlLockManager.java new file mode 100644 index 000000000..6106dd84b --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/TestMySqlLockManager.java @@ -0,0 +1,227 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lockmanager.impl.sql.optimistic; + +import org.junit.Assert; +import org.junit.Test; +import org.openecomp.appc.lockmanager.api.LockException; +import org.openecomp.appc.lockmanager.impl.sql.JdbcLockManager; +import org.openecomp.appc.lockmanager.impl.sql.MySqlLockManagerBaseTests; +import org.openecomp.appc.lockmanager.impl.sql.Synchronizer; + +import java.util.concurrent.*; + +public class TestMySqlLockManager extends MySqlLockManagerBaseTests { + + @Override + protected JdbcLockManager createJdbcLockManager(boolean useReal) { + return new MySqlLockManagerMock(useReal); + } + + @Test + public void testConcurrentLockDifferentOwners() throws LockException, InterruptedException, ExecutionException, TimeoutException { + + final int participantsNo = 2; + Synchronizer synchronizer = new Synchronizer(participantsNo) { + + private boolean wait = true; + + @Override + public void preAddLockRecord(String resource, String owner) { + if(Owner.A.name().equals(owner)) { + synchronized(this) { + if(wait) { + waitOn(this); + } + } + } + } + + @Override + public void postAddLockRecord(String resource, String owner) { + if(!Owner.A.name().equals(owner)) { + synchronized(this) { + notifyAll(); + wait = false; + } + } + } + + @Override + public void preUpdateLockRecord(String resource, String owner) { + preAddLockRecord(resource, owner); + } + + @Override + public void postUpdateLockRecord(String resource, String owner) { + postAddLockRecord(resource, owner); + } + }; + if(!setSynchronizer(synchronizer)) { + return; + } + ExecutorService executor = Executors.newFixedThreadPool(participantsNo); + // acquireLock by owner A should fail as it will wait for acquireLock by owner B + Future<Boolean> future1 = executor.submit(new Callable<Boolean>() { + @Override + public Boolean call() throws Exception { + try { + lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + return false; + } catch(LockException e) { + // this call should fail as Synchronizer delays its lock to make sure the second call locks the resource first + Assert.assertEquals("Cannot lock resource [" + Resource.Resource1.name() + "] for [" + Owner.A.name() + "]: already locked by [" + Owner.B.name() + "]", e.getMessage()); + return true; + } + } + }); + try { + // acquireLock by owner B should success + Future<Boolean> future2 = executor.submit(new Callable<Boolean>() { + @Override + public Boolean call() throws Exception { + // this call should success as Synchronizer delays the above lock to make sure this call success to lock the resource + return lockManager.acquireLock(Resource.Resource1.name(), Owner.B.name()); + } + }); + try { + Assert.assertTrue(future2.get(CONCURRENT_TEST_WAIT_TIME, TimeUnit.SECONDS)); + Assert.assertTrue(future1.get(CONCURRENT_TEST_WAIT_TIME, TimeUnit.SECONDS)); + } finally { + future2.cancel(true); + } + } finally { + future1.cancel(true); + } + } + + @Test + public void testConcurrentLockSameOwner() throws LockException, InterruptedException, ExecutionException, TimeoutException { + final int participantsNo = 2; + Synchronizer synchronizer = new Synchronizer(participantsNo) { + + private boolean wait = true; + + @Override + public void preAddLockRecord(String resource, String owner) { + synchronized(this) { + if(wait) { + wait = false; + waitOn(this); + } + } + } + + @Override + public void postAddLockRecord(String resource, String owner) { + synchronized(this) { + notifyAll(); + } + } + }; + if(!setSynchronizer(synchronizer)) { + return; + } + ExecutorService executor = Executors.newFixedThreadPool(participantsNo); + // one acquireLock should return true and the other should return false + Callable<Boolean> callable = new Callable<Boolean>() { + @Override + public Boolean call() throws Exception { + return lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + } + }; + Future<Boolean> future1 = executor.submit(callable); + try { + Future<Boolean> future2 = executor.submit(callable); + try { + boolean future1Res = future1.get(CONCURRENT_TEST_WAIT_TIME, TimeUnit.SECONDS); + boolean future2Res = future2.get(CONCURRENT_TEST_WAIT_TIME, TimeUnit.SECONDS); + // one of the lock requests should return true, the other one false as lock is requested simultaneously from 2 threads by same owner + Assert.assertNotEquals(future1Res, future2Res); + } finally { + future2.cancel(true); + } + } finally { + future1.cancel(true); + } + } + + @Test + public void testConcurrentUnlockSameOwner() throws LockException, InterruptedException, ExecutionException, TimeoutException { + lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + final int participantsNo = 2; + Synchronizer synchronizer = new Synchronizer(participantsNo) { + + private boolean wait = true; + + @Override + public void preUpdateLockRecord(String resource, String owner) { + synchronized(this) { + // make sure second call updates the LockRecord first + if(wait) { + wait = false; + waitOn(this); + } + } + } + + @Override + public void postUpdateLockRecord(String resource, String owner) { + synchronized(this) { + notifyAll(); + } + } + }; + if(!setSynchronizer(synchronizer)) { + return; + } + ExecutorService executor = Executors.newFixedThreadPool(participantsNo); + Callable<Boolean> callable = new Callable<Boolean>() { + @Override + public Boolean call() throws Exception { + try { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + // one of the unlock calls should success + return true; + } catch(LockException e) { + // one of the unlock calls should throw the LockException as the resource should already be unlocked by other call + Assert.assertEquals("Error unlocking resource [" + Resource.Resource1.name() + "]: resource is not locked", e.getMessage()); + return false; + } + } + }; + Future<Boolean> future1 = executor.submit(callable); + try { + Future<Boolean> future2 = executor.submit(callable); + try { + boolean future1Res = future1.get(CONCURRENT_TEST_WAIT_TIME, TimeUnit.SECONDS); + boolean future2Res = future2.get(CONCURRENT_TEST_WAIT_TIME, TimeUnit.SECONDS); + // one of the unlock calls should return true, the other one false as unlock is requested simultaneously from 2 threads by same owner + Assert.assertNotEquals(future1Res, future2Res); + } finally { + future2.cancel(true); + } + } finally { + future1.cancel(true); + } + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/pom.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/pom.xml new file mode 100644 index 000000000..56440c4f0 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/pom.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-dispatcher-common</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>lock-manager-lib</artifactId> + <packaging>pom</packaging> + + <modules> + <module>lock-manager-api</module> + <module>lock-manager-impl</module> + <module>lock-manager-features</module> + </modules> +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/pom.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/pom.xml new file mode 100644 index 000000000..4054ff79e --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/pom.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-dispatcher-common</artifactId> + <packaging>pom</packaging> + <name>APPC Dispatcher Common</name> + <description>APPC Dispatcher Common</description> + + <!-- ================================================================================== --> + <!-- The modules we build --> + <!-- ================================================================================== --> + <modules> + <module>appc-data-access-lib</module> + <module>execution-queue-management-lib</module> + <module>state-machine-lib</module> + <module>ranking-framework-lib</module> + <module>lock-manager-lib</module> + <module>domain-model-lib</module> + <module>transaction-recorder</module> + </modules> + +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.gitignore b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/pom.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/pom.xml new file mode 100644 index 000000000..03562065d --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/pom.xml @@ -0,0 +1,37 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher-common</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-ranking-framework-lib</artifactId> + <packaging>bundle</packaging> + + + <dependencies> + <dependency> + <groupId>com.att.eelf</groupId> + <artifactId>eelf-core</artifactId> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Export-Package>org.openecomp.appc.rankingframework</Export-Package> + <Private-Package>org.openecomp.appc.rankingframework.impl</Private-Package> + <Embed-Dependency>eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Import-Package>!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.apache.log,*</Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/AbstractRankedAttributesResolverFactory.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/AbstractRankedAttributesResolverFactory.java new file mode 100644 index 000000000..75480b300 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/AbstractRankedAttributesResolverFactory.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.rankingframework; + +import org.openecomp.appc.rankingframework.impl.DefaultRankedAttributesTreeFactory; + +public abstract class AbstractRankedAttributesResolverFactory implements RankedAttributesResolverFactory { + + private static class ReferenceHolder { + private static final RankedAttributesResolverFactory INSTANCE = new DefaultRankedAttributesTreeFactory(); + } + + public static RankedAttributesResolverFactory getInstance() { + return ReferenceHolder.INSTANCE; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationEntry.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationEntry.java new file mode 100644 index 000000000..77fa8930d --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationEntry.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.rankingframework; + +public interface ConfigurationEntry<R> { + Object getAttributeValue(String name); + R getResult(); +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationSet.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationSet.java new file mode 100644 index 000000000..2e862d9fc --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationSet.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.rankingframework; + +import java.util.Collection; + +public interface ConfigurationSet<R> { + Collection<String> getRankedAttributeNames(); + + Iterable<ConfigurationEntry<R>> getEntries(); +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesContext.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesContext.java new file mode 100644 index 000000000..a8d9b71ec --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesContext.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.rankingframework; + +public interface RankedAttributesContext { + Object getAttributeValue(String name); +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolver.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolver.java new file mode 100644 index 000000000..1948ccc1f --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolver.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.rankingframework; + +public interface RankedAttributesResolver<R> { + R resolve(RankedAttributesContext context); +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolverFactory.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolverFactory.java new file mode 100644 index 000000000..7267c046c --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolverFactory.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.rankingframework; + +public interface RankedAttributesResolverFactory { + <R> RankedAttributesResolver<R> create(ConfigurationSet<R> config); +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/BacktraceStrategy.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/BacktraceStrategy.java new file mode 100644 index 000000000..1365ae834 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/BacktraceStrategy.java @@ -0,0 +1,119 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.rankingframework.impl; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.openecomp.appc.rankingframework.RankedAttributesContext; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +class BacktraceStrategy implements Strategy { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(BacktraceStrategy.class); + + @Override + public <R> R resolve(CompositeNode<R> rootNode, List<String> rankedNames, RankedAttributesContext context) { + + if (logger.isDebugEnabled()) { + StringBuilder buff = new StringBuilder(128); + for (String name : rankedNames) { + buff.append("/{").append(name).append(" = ").append(Utils.value(context.getAttributeValue(name))).append('}'); + } + logger.debug(String.format("Trying to resolve path: %s", buff)); + } + + Set<String> visited = new HashSet<>(); + + CompositeNode<R> parentNode = rootNode; + int depth = 0; + boolean stop = false; + R result = null; + + String attribute = null; + Object value = null; + + do { + if (value == null) { + attribute = rankedNames.get(depth); + value = Utils.value(context.getAttributeValue(attribute)); + } + + Node<R> childNode = parentNode.children().get(value); + + if (childNode != null) { + if (logger.isDebugEnabled()) { + logger.debug(String.format("Found matching node '%s' - checking it out", childNode)); + } + + if (!visited.add(childNode.id())) { + if (logger.isDebugEnabled()) { + logger.debug(String.format("The matching node '%s' was checked before - ignoring it", childNode)); + } + childNode = null; + } + } else { + if (logger.isDebugEnabled()) { + logger.debug(String.format("Node '%s/{%s = %s}' not found - falling back", parentNode, attribute, value != null ? value : "NULL")); + } + } + + if (childNode != null) { + switch (childNode.type()) { + case COMPOSITE: + depth++; + value = null; + parentNode = (CompositeNode<R>) childNode; + break; + case LEAF: + if (logger.isDebugEnabled()) { + logger.debug( String.format("Result node has been resolved succesfully - '%s'", childNode)); + } + result = ((LeafNode<R>) childNode).result(); + stop = true; + break; + default: + throw new IllegalStateException(childNode.type().name()); + } + } else { + if (!value.equals(Constants.DEFAULT_MATCH)) { + logger.debug("Exact match didn't work, trying the default option, if any"); + value = Constants.DEFAULT_MATCH; + } else if (depth > 0) { + if (logger.isDebugEnabled()) { + logger.debug(String.format("Exact match didn't work and no default option available beneath '%s' - moving out", parentNode)); + } + depth--; + value = null; + parentNode = parentNode.parent(); + } else { + logger.debug("Didn't success to resolve the path - stopping without result"); + stop = true; + } + } + } while (!stop); + + return result; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/CompositeNode.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/CompositeNode.java new file mode 100644 index 000000000..0b5e633f3 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/CompositeNode.java @@ -0,0 +1,38 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.rankingframework.impl; + +import java.util.Map; + +class CompositeNode<R> extends NodeBase<R> { + + private final Map<Object, Node<R>> children; + + CompositeNode(String name, Object value, CompositeNode<R> parent, Map<Object, Node<R>> children) { + super(name, value, parent, Type.COMPOSITE); + this.children = children; + } + + Map<Object, Node<R>> children() { + return children; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Constants.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Constants.java new file mode 100644 index 000000000..4111131e2 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Constants.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.rankingframework.impl; + +class Constants { + + private Constants() { + } + + static final String DEFAULT_MATCH = "*"; +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/DefaultRankedAttributesTreeFactory.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/DefaultRankedAttributesTreeFactory.java new file mode 100644 index 000000000..d7c48dae6 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/DefaultRankedAttributesTreeFactory.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.rankingframework.impl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.openecomp.appc.rankingframework.ConfigurationSet; +import org.openecomp.appc.rankingframework.RankedAttributesResolver; +import org.openecomp.appc.rankingframework.RankedAttributesResolverFactory; + +public final class DefaultRankedAttributesTreeFactory implements RankedAttributesResolverFactory { + + private final Strategy DEFAULT_STRATEGY = new BacktraceStrategy(); + + @Override + public <R> RankedAttributesResolver<R> create(ConfigurationSet<R> config) { + + CompositeNode<R> root = RankedAttributesTreeBuilder.build(config); + RankedAttributesResolver<R> tree = new RankedAttributesTree<R>(root, toList(config.getRankedAttributeNames()), + DEFAULT_STRATEGY); + return tree; + } + + private static List<String> toList(Collection<String> col) { + return Collections.unmodifiableList(new ArrayList<>(col)); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/LeafNode.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/LeafNode.java new file mode 100644 index 000000000..1b1dffdc8 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/LeafNode.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.rankingframework.impl; + +class LeafNode<R> extends NodeBase<R> { + + private final R result; + + LeafNode(String name, Object value, CompositeNode<R> parent, R result) { + super(name, value, parent, Type.LEAF); + this.result = result; + } + + R result() { + return result; + } + + @Override + public String toString() { + StringBuffer buff = new StringBuffer(128); + buff.append(super.toString()); + buff.append(" --> "); + buff.append(result.toString()); + return buff.toString(); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Node.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Node.java new file mode 100644 index 000000000..c33e4d875 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Node.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.rankingframework.impl; + +interface Node<R> { + enum Type { + LEAF, COMPOSITE + } + + String id(); + + String name(); + + Object value(); + + CompositeNode<R> parent(); + + Type type(); + + boolean isDefaultMatch(); +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/NodeBase.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/NodeBase.java new file mode 100644 index 000000000..747d9cfd2 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/NodeBase.java @@ -0,0 +1,87 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.rankingframework.impl; + +import java.util.UUID; + +abstract class NodeBase<R> implements Node<R> { + + private final String name; + private final Object value; + private final Type type; + private final CompositeNode<R> parent; + private final String id = UUID.randomUUID().toString(); + + NodeBase(String name, Object value, CompositeNode<R> parent, Type type) { + this.name = name; + this.value = value; + this.parent = parent; + this.type = type; + } + + @Override + public String id() { + return id; + } + + @Override + public Type type() { + return type; + } + + @Override + public String name() { + return name; + } + + @Override + public Object value() { + return value; + } + + @Override + public CompositeNode<R> parent() { + return parent; + } + + @Override + public boolean isDefaultMatch() { + return value.equals(Constants.DEFAULT_MATCH); + } + + @Override + public String toString() { + if (!name.equals("ROOT")) { + StringBuffer buff = new StringBuffer(128); + if (parent != null) { + buff.append(parent.toString()); + } + buff.append("/{"); + buff.append(name).append(" = ").append(value); + buff.append("}"); + + return buff.toString(); + } else { + return ""; + } + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTree.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTree.java new file mode 100644 index 000000000..305af85a6 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTree.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.rankingframework.impl; + +import java.util.List; + +import org.openecomp.appc.rankingframework.RankedAttributesContext; +import org.openecomp.appc.rankingframework.RankedAttributesResolver; + +class RankedAttributesTree<R> implements RankedAttributesResolver<R> { + + private final CompositeNode<R> root; + private final Strategy strategy; + private final List<String> rankedNames; + + RankedAttributesTree(CompositeNode<R> root, List<String> rankedNames, Strategy strategy) { + this.root = root; + this.rankedNames = rankedNames; + this.strategy = strategy; + } + + @Override + public R resolve(RankedAttributesContext context) { + return strategy.resolve(root, rankedNames, context); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTreeBuilder.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTreeBuilder.java new file mode 100644 index 000000000..16aee5607 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTreeBuilder.java @@ -0,0 +1,100 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.rankingframework.impl; + +import java.util.HashMap; + +import org.openecomp.appc.rankingframework.ConfigurationEntry; +import org.openecomp.appc.rankingframework.ConfigurationSet; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +class RankedAttributesTreeBuilder { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(RankedAttributesTreeBuilder.class); + + private RankedAttributesTreeBuilder() { + } + + static <R> CompositeNode<R> build(ConfigurationSet<R> config) { + + Object[] names = config.getRankedAttributeNames().toArray(); + + CompositeNode<R> root = new CompositeNode<>("ROOT", Constants.DEFAULT_MATCH, null, + new HashMap<Object, Node<R>>()); + + if (logger.isDebugEnabled()) { + logger.debug(String.format("Building decision tree for ranked attributes: %s", config.getRankedAttributeNames())); + } + + for (ConfigurationEntry<R> entry : config.getEntries()) { + process(entry, names, root); + } + + return root; + } + + private static <R> void process(ConfigurationEntry<R> entry, Object[] names, CompositeNode<R> root) { + CompositeNode<R> parentNode = null; + for (int i = 0; i < names.length; i++) { + + if (i == 0) { + parentNode = root; + } + + final String name = (String) names[i]; + + final Object value = value(entry, name); + + if (i < names.length - 1) { + CompositeNode<R> currentNode = (CompositeNode<R>) parentNode.children().get(value); + if (currentNode == null) { + currentNode = new CompositeNode<>(name, value, parentNode, new HashMap<Object, Node<R>>()); + parentNode.children().put(value, currentNode); + } + parentNode = currentNode; + } else { + LeafNode<R> currentNode = (LeafNode<R>) parentNode.children().get(value); + if (currentNode == null) { + currentNode = new LeafNode<R>(name, value, parentNode, entry.getResult()); + parentNode.children().put(value, currentNode); + + if (logger.isDebugEnabled()) { + logger.debug(String.format("Branch has been created: %s", currentNode)); + } + } else { + logger.error( + String.format("Duplicated configuration entry has been detected for attribute '%s' with value '%s' - the node '%s'exists already", + name, + value, + currentNode)); + throw new IllegalArgumentException("Duplicated configuration entry: " + currentNode); + } + } + } + } + + private static <R> Object value(ConfigurationEntry<R> entry, String name) { + Object value = entry.getAttributeValue(name); + return Utils.value(value); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Strategy.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Strategy.java new file mode 100644 index 000000000..121f1fb2d --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Strategy.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.rankingframework.impl; + +import java.util.List; + +import org.openecomp.appc.rankingframework.RankedAttributesContext; + +interface Strategy { + <R> R resolve(CompositeNode<R> root, List<String> rankedNames, RankedAttributesContext context); +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Utils.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Utils.java new file mode 100644 index 000000000..88ca6d5f5 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Utils.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.rankingframework.impl; + +class Utils { + + private Utils() { + } + + static <R> Object value(Object value) { + if (value == null || (value instanceof String && isEmpty((String) value))) { + value = Constants.DEFAULT_MATCH; + } + + return value; + } + + private static boolean isEmpty(String str) { + return str == null || str.length() == 0; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/java/org/openecomp/appc/rankingframework/TestRankingFramework.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/java/org/openecomp/appc/rankingframework/TestRankingFramework.java new file mode 100644 index 000000000..75301dc37 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/java/org/openecomp/appc/rankingframework/TestRankingFramework.java @@ -0,0 +1,225 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.rankingframework; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; +import org.openecomp.appc.rankingframework.AbstractRankedAttributesResolverFactory; +import org.openecomp.appc.rankingframework.ConfigurationEntry; +import org.openecomp.appc.rankingframework.ConfigurationSet; +import org.openecomp.appc.rankingframework.RankedAttributesContext; +import org.openecomp.appc.rankingframework.RankedAttributesResolver; + +public class TestRankingFramework { + + private static final String COUNTRY = "COUNTRY"; + private static final String STATE = "STATE"; + private static final String CITY = "CITY"; + + private static final List<String> NAMES = Arrays.asList(COUNTRY, STATE, CITY); + + private static final String PACIFIC = "Pacific"; + private static final String ATLANTIC = "Atlantic"; + private static final String ARCTIC = "Arctic"; + private static final String NA = "N/A"; + + private static ConfigurationEntry<String> entry(String [] attributes, String result) { + if (attributes == null || attributes.length != NAMES.size()) { + throw new IllegalArgumentException(); + } + + Map<String, String> map = new HashMap<>(attributes.length); + for (int i = 0; i < attributes.length; i++) { + map.put(NAMES.get(i), attributes[i]); + } + + return new ConfigurationEntryImpl(map, result); + } + + private static ConfigurationSet<String> config(ConfigurationEntry<String> ... entries) { + return new ConfigurationSetImpl(Arrays.asList(entries), NAMES); + } + + private static RankedAttributesContext context(String ... attributes) { + if (attributes == null || attributes.length != NAMES.size()) { + throw new IllegalArgumentException(); + } + + Map<String, String> map = new HashMap<>(attributes.length); + for (int i = 0; i < attributes.length; i++) { + map.put(NAMES.get(i), attributes[i]); + } + + return new Context(map); + } + + private static class ConfigurationSetImpl implements ConfigurationSet<String> { + + private final Collection<ConfigurationEntry<String>> entries; + private final Collection<String> names; + + ConfigurationSetImpl(Collection<ConfigurationEntry<String>> entries, Collection<String> names) { + this.entries = entries; + this.names = names; + } + + @Override + public Iterable<ConfigurationEntry<String>> getEntries() { + return entries; + } + + @Override + public Collection<String> getRankedAttributeNames() { + return names; + } + } + + private static class ConfigurationEntryImpl implements ConfigurationEntry<String> { + + private final Map<String, String> attributes; + private final String result; + + ConfigurationEntryImpl(Map<String, String> attributes, String result) { + this.attributes = attributes; + this.result = result; + } + + @Override + public Object getAttributeValue(String name) { + return attributes.get(name); + } + + @Override + public String getResult() { + return result; + } + } + + private static class Context implements RankedAttributesContext { + + private final Map<String, String> map; + + Context(Map<String, String> map) { + this.map = map; + } + + @Override + public Object getAttributeValue(String name) { + return map.get(name); + } + } + + private static ConfigurationSet<String> testData() { + @SuppressWarnings("unchecked") + ConfigurationSet<String> config = config( + entry(new String [] {"US", "CA", "SFO"}, PACIFIC), + entry(new String [] {"US", "CA", "LA"}, PACIFIC), + entry(new String [] {"US", "FL", "MIAMI"}, ATLANTIC), + entry(new String [] {"US", "AK", "Barrow"}, ARCTIC), + entry(new String [] {"US", "AK", "*"}, PACIFIC), + entry(new String [] {"US", "*", "Houston"}, ATLANTIC), + entry(new String [] {"US", "*", "*"}, NA) + ); + + return config; + } + + private static RankedAttributesResolver<String> resolver(ConfigurationSet<String> config) { + return AbstractRankedAttributesResolverFactory.getInstance().create(config); + } + + @Test + public void testExactMatch() { + + ConfigurationSet<String> config = testData(); + + RankedAttributesResolver<String> resolver = resolver(config) ; + + RankedAttributesContext context = context("US", "CA", "SFO"); + + String result = resolver.resolve(context); + + Assert.assertEquals(PACIFIC, result); + } + + @Test + public void testDefaultMatchPartial() { + + ConfigurationSet<String> config = testData(); + + RankedAttributesResolver<String> resolver = resolver(config) ; + + RankedAttributesContext context = context("US", "AK", "Anchorage"); + + String result = resolver.resolve(context); + + Assert.assertEquals(PACIFIC, result); + } + + @Test + public void testDefaultMatchFull() { + + ConfigurationSet<String> config = testData(); + + RankedAttributesResolver<String> resolver = resolver(config) ; + + RankedAttributesContext context = context("US", "IL", "Chicago"); + + String result = resolver.resolve(context); + + Assert.assertEquals(NA, result); + } + + @Test + public void testDefaultMatchInTheMiddle() { + + ConfigurationSet<String> config = testData(); + + RankedAttributesResolver<String> resolver = resolver(config) ; + + RankedAttributesContext context = context("US", "TX", "Houston"); + + String result = resolver.resolve(context); + + Assert.assertEquals(ATLANTIC, result); + } + + @Test + public void testBacktrace() { + + ConfigurationSet<String> config = testData(); + + RankedAttributesResolver<String> resolver = resolver(config) ; + + RankedAttributesContext context = context("US", "CA", "SJC"); + + String result = resolver.resolve(context); + + Assert.assertEquals(NA, result); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/com/att/eelf/logback.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/com/att/eelf/logback.xml new file mode 100644 index 000000000..2ac88adbc --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/com/att/eelf/logback.xml @@ -0,0 +1,27 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<configuration scan="true" scanPeriod="3 seconds" debug="false"> + +<!-- + Dummy file to suppress default EELF configuration + --> +</configuration> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/logback.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/logback.xml new file mode 100644 index 000000000..c93e4e4a9 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/logback.xml @@ -0,0 +1,46 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<configuration scan="true" scanPeriod="3 seconds" debug="false"> + + <property name="logDirectory" value="target" /> + + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern> %.-5level %-36.36logger - %msg%n</pattern> + </encoder> + </appender> + + <appender name="FILE" class="ch.qos.logback.core.FileAppender"> + <file>${logDirectory}/debug.log</file> + <encoder> + <pattern> %.-5level %-36.36logger - %msg%n</pattern> + </encoder> + </appender> + + <logger name="org.openecomp.appc" level="DEBUG" additivity="false"> + <appender-ref ref="FILE" /> + </logger> + + <root level="WARN"> + <appender-ref ref="STDOUT" /> + </root> +</configuration> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/.gitignore b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/pom.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/pom.xml new file mode 100644 index 000000000..10f74c6da --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/pom.xml @@ -0,0 +1,32 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher-common</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>state-machine-lib</artifactId> + <packaging>bundle</packaging> + + <name>state-machine-lib</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Export-Package>org.openecomp.appc.statemachine.*</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/StateMachine.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/StateMachine.java new file mode 100644 index 000000000..daa8a1ed3 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/StateMachine.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.statemachine; + +import org.openecomp.appc.statemachine.objects.*; + + +public interface StateMachine { + StateMachineResponse handleEvent(State currentState, Event event) throws InvalidInputException; +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineFactory.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineFactory.java new file mode 100644 index 000000000..d8a135be4 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineFactory.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.statemachine.impl; + +import java.util.HashSet; +import java.util.Set; + +import org.openecomp.appc.statemachine.StateMachine; +import org.openecomp.appc.statemachine.objects.Event; +import org.openecomp.appc.statemachine.objects.State; +import org.openecomp.appc.statemachine.objects.StateMachineMetadata; + + +public class StateMachineFactory { + + private StateMachineFactory(){ + + } + + public static StateMachine getStateMachine(StateMachineMetadata metadata){ + StateMachine machine = new StateMachineImpl(metadata); + return machine; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineImpl.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineImpl.java new file mode 100644 index 000000000..f4f6612f8 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineImpl.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.statemachine.impl; + +import java.util.HashSet; +import java.util.Set; + +import org.openecomp.appc.statemachine.StateMachine; +import org.openecomp.appc.statemachine.objects.*; + + +public class StateMachineImpl implements StateMachine { + + private final Set<State> states; + + private final Set<Event> events; + + StateMachineImpl(StateMachineMetadata metadata){ + this.states = new HashSet<State>(); + this.states.addAll(metadata.getStates()); + this.events = new HashSet<Event>(); + this.events.addAll(metadata.getEvents()); + } + + public StateMachineResponse handleEvent(State inputState, Event event) throws InvalidInputException{ + + if(!validateInputs(inputState,event)){ + throw new InvalidInputException("VNF State or incoming event is invalid. State = " +inputState + " event = " + event ); + } + + StateMachineResponse response = new StateMachineResponse(); + State currentState = null,nextState = null; + for(State stateInSet:states){ + if(stateInSet.equals(inputState)){ + currentState = stateInSet; + break; + } + } + for(Transition transition : currentState.getTransitions()){ + if(event.equals(transition.getEvent())){ + nextState = transition.getNextState(); + } + } + if(nextState == null){ + response.setResponse(Response.NO_TRANSITION_DEFINED); + } + else if(inputState.equals(nextState)){ + response.setResponse(Response.NO_STATE_CHANGE); + } + else{ + response.setResponse(Response.VALID_TRANSITION); + } + response.setNextState(nextState); + return response; + } + + private boolean validateInputs(State state,Event event){ + if(state ==null || event == null){ + return false; + } + if(!(this.states.contains(state) && this.events.contains(event))){ + return false; + } + return true; + } + + @Override + public String toString() { + return "StateMachineImpl{" + + "states=" + states + + ", events=" + events + + '}'; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Event.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Event.java new file mode 100644 index 000000000..377cd8138 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Event.java @@ -0,0 +1,59 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.statemachine.objects; + +public class Event{ + + private String eventName; + + private Event(){ + + } + @Override + public int hashCode(){ + return this.eventName.hashCode(); + } + @Override + public boolean equals(Object obj){ + if(obj == null){ + return false; + } + if(!(obj instanceof Event)){ + return false; + } + Event event = (Event)obj; + return this.eventName.equals(event.getEventName()); + } + + public Event(String eventName){ + this(); + this.eventName = eventName; + } + + public String getEventName() { + return eventName; + } + @Override + public String toString(){ + return this.eventName; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/InvalidInputException.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/InvalidInputException.java new file mode 100644 index 000000000..db6b6d3ce --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/InvalidInputException.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.statemachine.objects; + +public class InvalidInputException extends Exception{ + public InvalidInputException(String message){ + super(message); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Response.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Response.java new file mode 100644 index 000000000..8f24c46a0 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Response.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.statemachine.objects; + + +public enum Response { + NO_TRANSITION_DEFINED,NO_STATE_CHANGE,VALID_TRANSITION; + public String toString(){ + return this.name(); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/State.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/State.java new file mode 100644 index 000000000..18daef02e --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/State.java @@ -0,0 +1,79 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.statemachine.objects; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + + + +public class State{ + private String stateName; + private List<Transition> transitions; + + private State(){ + + } + + public State(String state){ + this(); + this.stateName = state; + this.transitions = new ArrayList<Transition>(); + } + + @Override + public int hashCode(){ + return this.stateName.hashCode(); + } + + @Override + public boolean equals(Object obj){ + if(obj == null){ + return false; + } + if(!(obj instanceof State)){ + return false; + } + State state = (State)obj; + return this.stateName.equals(state.getStateName()); + } + + + public String getStateName(){ + return stateName; + } + + void addTransition(Transition transition){ + this.transitions.add(transition); + } + + public List<Transition> getTransitions() { + return transitions; + } + + @Override + public String toString(){ + return this.stateName; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineMetadata.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineMetadata.java new file mode 100644 index 000000000..6625fef19 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineMetadata.java @@ -0,0 +1,79 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.statemachine.objects; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +public class StateMachineMetadata { + + Set<State> states; + Set<Event> events; + + private StateMachineMetadata(StateMachineMetadataBuilder builder){ + states = builder.states; + events = builder.events; + } + + public Set<State> getStates() { + return states; + } + + public Set<Event> getEvents() { + return events; + } + + public static class StateMachineMetadataBuilder{ + + private Set<State> states; + private Set<Event> events; + + public StateMachineMetadataBuilder(){ + states = new HashSet<State>(); + events = new HashSet<Event>(); + } + + public StateMachineMetadataBuilder addState(State state){ + this.states.add(state); + return this; + } + + public StateMachineMetadataBuilder addEvent(Event event){ + this.events.add(event); + return this; + } + + public StateMachineMetadataBuilder addTransition(State currentState,Event event,State nextState){ + Transition transition = new Transition(event,nextState); + currentState.addTransition(transition); + return this; + } + + public StateMachineMetadata build(){ + StateMachineMetadata machine = new StateMachineMetadata(this); + return machine; + } + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineResponse.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineResponse.java new file mode 100644 index 000000000..ce75693fc --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineResponse.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.statemachine.objects; + + +public class StateMachineResponse { + State nextState; + Response response; + + public StateMachineResponse(){ + + } + + public State getNextState() { + return nextState; + } + + public Response getResponse() { + return response; + } + + public void setNextState(State nextState) { + this.nextState = nextState; + } + + public void setResponse(Response response) { + this.response = response; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Transition.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Transition.java new file mode 100644 index 000000000..4a268f931 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Transition.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.statemachine.objects; + + +public class Transition { + private Event event; + private State nextState; + + private Transition(){ + + } + public Transition(Event event,State nextState){ + this(); + this.event = event; + this.nextState = nextState; + } + + public Event getEvent() { + return event; + } + + public State getNextState() { + return nextState; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/test/java/org/openecomp/appc/statemachine/TestStateMachine.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/test/java/org/openecomp/appc/statemachine/TestStateMachine.java new file mode 100644 index 000000000..735e8e13c --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/test/java/org/openecomp/appc/statemachine/TestStateMachine.java @@ -0,0 +1,98 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.statemachine; + + +import org.junit.Assert; +import org.junit.Test; +import org.openecomp.appc.statemachine.impl.StateMachineFactory; +import org.openecomp.appc.statemachine.objects.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + + +public class TestStateMachine { + + @Test + public void handleEvent() throws InvalidInputException { + +// MetadataReader metadataReader = new MetadataReader(); +// StateMachineMetadata metadata = metadataReader.readMetadata(null); +// +// StateMachine machine = StateMachineFactory.getStateMachine(metadata); +// +// /* +// Testing Positive Scenario passing the valid events and validating the StateMachineResponse +// */ +// for(State state:metadata.getStates()){ +// +// for(Transition transition:state.getTransitions()){ +// Event event = transition.getEvent(); +// State nextState = transition.getNextState(); +// +// StateMachineResponse response = machine.handleEvent(state,event); +// Assert.assertEquals(response.getNextState(),nextState); +// Assert.assertEquals(response.getResponse(),Response.VALID_TRANSITION); +// } +// } +// +// /* +// Testing Negative Scenarios, 1. Passing the valid Events for which Transition is not defined in +// Metadata and validating the StateMachineResponse 2. Passing the invalid events which are not +// registered as events in the StateMachineMetadata and validating StateMachineResponse +// */ +// for(State state:metadata.getStates()){ +// +// for(Transition transition:state.getTransitions()){ +// List<Event> negativeEvents = getNegativeEvents(state,metadata.getEvents()); +// +// for(Event negativeEvent:negativeEvents){ +// StateMachineResponse response = machine.handleEvent(state,negativeEvent); +// Assert.assertEquals(response.getNextState(),null); +// Assert.assertEquals(response.getResponse(),Response.NO_TRANSITION_DEFINED); +// +// boolean flag =false; +// try{ +// response = machine.handleEvent(state,new Event("PUT")); +// } +// catch(InvalidInputException e){ +// flag = true; +// } +// Assert.assertTrue(flag); +// +// } +// } +// } + } + +// private List<Event> getNegativeEvents(State state,Set<Event> events) { +// List<Event> negativeEventList = new ArrayList<>(); +// negativeEventList.addAll(events); +// +// for(Transition transition: state.getTransitions()){ +// negativeEventList.remove(transition.getEvent()); +// } +// return negativeEventList; +// } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/.gitignore b/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/pom.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/pom.xml new file mode 100644 index 000000000..af399eae2 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/pom.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <parent> + <artifactId>appc-dispatcher-common</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>transaction-recorder</artifactId> + <packaging>bundle</packaging> + + <name>transaction-recorder</name> + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-data-access-lib</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic,appc-data-access-lib;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Export-Service>org.openecomp.appc.transactionrecorder.TransactionRecorder</Export-Service> + <Import-Package>!javax.*,!groovy.lang,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.apache.commons.lang3,!org.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package> + <Export-Package>org.openecomp.appc.transactionrecorder,org.openecomp.appc.transactionrecorder.objects</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + + +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/TransactionRecorder.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/TransactionRecorder.java new file mode 100644 index 000000000..27fdc05b0 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/TransactionRecorder.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.transactionrecorder; + + +import org.openecomp.appc.transactionrecorder.objects.TransactionRecord; + + +public interface TransactionRecorder { + /** + * Stores transaction record to appc database by calling APPC Dao layer. + * @param record Transaction record data. + */ + void store(TransactionRecord record); +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/impl/TransactionRecorderImpl.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/impl/TransactionRecorderImpl.java new file mode 100644 index 000000000..74040d3e4 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/impl/TransactionRecorderImpl.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.transactionrecorder.impl; + +import org.openecomp.appc.dao.util.DBUtils; +import org.openecomp.appc.transactionrecorder.TransactionRecorder; +import org.openecomp.appc.transactionrecorder.objects.TransactionRecord; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + + + +public class TransactionRecorderImpl implements TransactionRecorder { + + private static String APPCCTL_SCHEMA = "appcctl"; + + private static final Logger logger = LoggerFactory.getLogger(TransactionRecorderImpl.class); + + /** + * Stores transaction record to appc database by calling APPC Dao layer. + * @param record Transaction record data. + */ + @Override + public void store(TransactionRecord record) { + Connection connection = null; + PreparedStatement stmt = null; + String queryString = "INSERT INTO transactions VALUES (?,?,?,?,?,?,?,?,?,?)"; + try { + if (logger.isDebugEnabled()) { + logger.debug("Transaction Data started Inserting Successfully into DB"); + } + connection = DBUtils.getConnection(APPCCTL_SCHEMA); + stmt = connection.prepareStatement(queryString); + stmt.setTimestamp(1, new java.sql.Timestamp(record.getTimeStamp().getTime())); + stmt.setString(2, record.getRequestID()); + stmt.setTimestamp(3, new java.sql.Timestamp(record.getStartTime().getTime())); + stmt.setTimestamp(4, new java.sql.Timestamp(record.getEndTime().getTime())); + stmt.setString(5, record.getTargetID()); + stmt.setString(6, record.getTargetType()); + stmt.setString(7, record.getSubComponent()); + stmt.setString(8, record.getOperation()); + stmt.setString(9, record.getResultCode()); + stmt.setString(10, record.getDescription()); + stmt.execute(); + if (logger.isDebugEnabled()) { + logger.debug("Transaction Data Inserted Successfully into DB"); + } + } catch (SQLException e) { + logger.error("Error Accessing Database " + e); + throw new RuntimeException(e); + } finally { + DBUtils.clearResources(null, stmt, connection); + } + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/objects/TransactionRecord.java b/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/objects/TransactionRecord.java new file mode 100644 index 000000000..4807aed0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/objects/TransactionRecord.java @@ -0,0 +1,147 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.transactionrecorder.objects; + +import java.util.Date; + + +public class TransactionRecord { + + /* +- Timestamp = RequestHandlerInput.RequestHeader.timeStamp +- Request ID = RequestHandlerInput.RequestHeader.requestID +- Start time = from flow +- End time = from flow +- VF_ID = RequestHandlerInput.targetID +- VF_type = genericVnf.getVnfType() +- Sub-component (optional) e.g. VFC_ID/VM UUID - ???? empty +- Operation e.g. Start, Configure etc. = CommandContext.Command +- Result - Success/Error code + description,as published to the initiator RequestHandlerResponse.ACCEPTED/RequestHandlerResponse.REJECTED + String (description) + */ + + private Date timeStamp; + private String requestID; + private Date startTime; + private Date endTime; + private String targetID; + private String targetType; + private String subComponent; + private String operation; + private String resultCode; + private String description; + + public Date getTimeStamp() { + return timeStamp; + } + + public void setTimeStamp(Date timeStamp) { + this.timeStamp = timeStamp; + } + + public String getRequestID() { + return requestID; + } + + public void setRequestID(String requestID) { + this.requestID = requestID; + } + + public Date getStartTime() { + return startTime; + } + + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + public Date getEndTime() { + return endTime; + } + + public void setEndTime(Date endTime) { + this.endTime = endTime; + } + + public String getTargetID() { + return targetID; + } + + public void setTargetID(String targetID) { + this.targetID = targetID; + } + + public String getTargetType() { + return targetType; + } + + public void setTargetType(String targetType) { + this.targetType = targetType; + } + + public String getSubComponent() { + return subComponent; + } + + public void setSubComponent(String subComponent) { + this.subComponent = subComponent; + } + + public String getOperation() { + return operation; + } + + public void setOperation(String operation) { + this.operation = operation; + } + + public String getResultCode() { + return resultCode; + } + + public void setResultCode(String resultCode) { + this.resultCode = resultCode; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @Override + public String toString() { + return "TransactionRecord{" + + "timeStamp=" + timeStamp + + ", requestID='" + requestID + '\'' + + ", startTime=" + startTime + + ", endTime=" + endTime + + ", targetID='" + targetID + '\'' + + ", targetType='" + targetType + '\'' + + ", subComponent='" + subComponent + '\'' + + ", operation='" + operation + '\'' + + ", resultCode='" + resultCode + '\'' + + ", description='" + description + '\'' + + '}'; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..2d2ef7a23 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- + Starter Blueprint Camel Definition appc-aai-adapter-blueprint +--> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + <bean id="transactionRecorderBean" class="org.openecomp.appc.transactionrecorder.impl.TransactionRecorderImpl" scope="singleton" ></bean> + <service id="transactionRecorderService" interface="org.openecomp.appc.transactionrecorder.TransactionRecorder" ref="transactionRecorderBean"/> +</blueprint> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-features/.gitignore b/app-c/appc/appc-dispatcher/appc-dispatcher-features/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-features/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-features/pom.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-features/pom.xml new file mode 100644 index 000000000..b26d324d2 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-features/pom.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-dispatcher</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <name>appc-dispatcher-features</name> + <artifactId>appc-dispatcher-features</artifactId> + + <packaging>jar</packaging> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-features/src/main/resources/features.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-features/src/main/resources/features.xml new file mode 100644 index 000000000..3d0859340 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-features/src/main/resources/features.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="appc-dispatcher-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + + <feature name='appc-dispatcher' description="appc-dispatcher" version='${project.version}'> + <feature version='${project.version}'>appc-request-handler</feature> + <feature version='${project.version}'>appc-command-executor</feature> + <feature version='${project.version}'>appc-lifecycle-management</feature> + <feature version='${project.version}'>appc-license-manager</feature> + <feature version='${project.version}'>appc-workflow-management</feature> + <feature version='${project.version}'>lock-manager</feature> + </feature> + +</features> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-installer/.gitignore b/app-c/appc/appc-dispatcher/appc-dispatcher-installer/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-installer/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-installer/pom.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-installer/pom.xml new file mode 100644 index 000000000..27a4061ce --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-installer/pom.xml @@ -0,0 +1,223 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-dispatcher</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + + <artifactId>appc-dispatcher-installer</artifactId> + <name>APPC Dispatcher - Karaf Installer</name> + <packaging>pom</packaging> + + <properties> + <application.name>appc-dispatcher</application.name> + <features.boot>appc-dispatcher</features.boot> + <features.boot.licenseManager>appc-license-manager</features.boot.licenseManager> + <!--<features.repositories>mvn:org.openecomp.appc/appc-dispatcher-features/${project.version}/xml/features,mvn:org.openecomp.appc/appc-request-handler-features/${project.version}/xml/features,mvn:org.openecomp.appc/appc-command-executor-features/${project.version}/xml/features,mvn:org.openecomp.appc/appc-lifecycle-management-features/${project.version}/xml/features,mvn:org.openecomp.appc/appc-license-manager-features/${project.version}/xml/features,mvn:org.openecomp.appc/appc-workflow-management-features/${project.version}/xml/features,mvn:org.openecomp.appc/lock-manager-features/${project.version}/xml/features</features.repositories>--> + + <!-- SEPARATING FEATURE INSTALLS --> + <features.repo.dispatcher>mvn:org.openecomp.appc/appc-dispatcher-features/${project.version}/xml/features</features.repo.dispatcher> + <features.repo.requestHandler>mvn:org.openecomp.appc/appc-request-handler-features/${project.version}/xml/features</features.repo.requestHandler> + <features.repo.commandExecutor>mvn:org.openecomp.appc/appc-command-executor-features/${project.version}/xml/features</features.repo.commandExecutor> + <features.repo.lifecycleManagement>mvn:org.openecomp.appc/appc-lifecycle-management-features/${project.version}/xml/features</features.repo.lifecycleManagement> + <features.repo.licenseManager>mvn:org.openecomp.appc/appc-license-manager-features/${project.version}/xml/features</features.repo.licenseManager> + <features.repo.workflowManagement>mvn:org.openecomp.appc/appc-workflow-management-features/${project.version}/xml/features</features.repo.workflowManagement> + <features.repo.lockManager>mvn:org.openecomp.appc/lock-manager-features/${project.version}/xml/features</features.repo.lockManager> + + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher-features</artifactId> + <version>${project.version}</version> + <classifier>features</classifier> + <type>xml</type> +<!-- <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> --> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-request-handler-features</artifactId> + <version>${project.version}</version> + <classifier>features</classifier> + <type>xml</type> +<!-- <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> --> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-command-executor-features</artifactId> + <version>${project.version}</version> + <classifier>features</classifier> + <type>xml</type> +<!-- <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> --> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-lifecycle-management-features</artifactId> + <version>${project.version}</version> + <classifier>features</classifier> + <type>xml</type> +<!-- <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> --> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-workflow-management-features</artifactId> + <version>${project.version}</version> + <classifier>features</classifier> + <type>xml</type> +<!-- <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> --> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-license-manager-features</artifactId> + <version>${project.version}</version> + <classifier>features</classifier> + <type>xml</type> + <!-- <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> --> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>lock-manager-features</artifactId> + <version>${project.version}</version> + <classifier>features</classifier> + <type>xml</type> + <!-- <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> --> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>false</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>true</attach> + <finalName>${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <excludeGroupIds>org.opendaylight</excludeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals> + <!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-installer/src/assembly/assemble_installer_zip.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..8948a3302 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>controller</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-installer/src/assembly/assemble_mvnrepo_zip.xml b/app-c/appc/appc-dispatcher/appc-dispatcher-installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..a18efd00b --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,47 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>controller</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + +</assembly> diff --git a/app-c/appc/appc-dispatcher/appc-dispatcher-installer/src/main/resources/scripts/install-feature.sh b/app-c/appc/appc-dispatcher/appc-dispatcher-installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..c73d14abd --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-dispatcher-installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,54 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +#!/bin/bash + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -n -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +# ${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories} + +# INSTALLING ODL FEATURES SEPARATELY--> +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repo.dispatcher} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repo.requestHandler} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repo.commandExecutor} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repo.lifecycleManagement} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repo.licenseManager} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repo.workflowManagement} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repo.lockManager} + +# INSTALLING appc-license-manager first since it's a dependency on other features +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot.licenseManager} + +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot} + diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/.gitignore b/app-c/appc/appc-dispatcher/appc-license-manager/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-license-manager/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/.gitignore b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/pom.xml b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/pom.xml new file mode 100644 index 000000000..5bf4457a6 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/pom.xml @@ -0,0 +1,47 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-license-manager</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-license-manager-api</artifactId> + <packaging>bundle</packaging> + + <name>appc-license-manager-api</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Export-Package>org.openecomp.appc.licmgr,org.openecomp.appc.licmgr.exception,org.openecomp.appc.licmgr.objects</Export-Package> + <Embed-Dependency>!dblib-provider,appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Import-Package>!groovy.lang,!javax.*,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/Constants.java b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/Constants.java new file mode 100644 index 000000000..81ce0e713 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/Constants.java @@ -0,0 +1,109 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.licmgr; + +public class Constants { + + private Constants(){} + + public static final String CONFIGURE_PATH = "/restconf/config/opendaylight-inventory:nodes/node/"; + public static final String CONNECT_PATH = "/restconf/config/opendaylight-inventory:nodes/node/controller-config/yang-ext:mount/config:modules"; + public static final String CHECK_CONNECTION_PATH = "/restconf/operational/opendaylight-inventory:nodes/node/"; + public static final String DISCONNECT_PATH = "/restconf/config/opendaylight-inventory:nodes/node/controller-config/yang-ext:mount/config:modules/module/odl-sal-netconf-connector-cfg:sal-netconf-connector/"; + + public static final String CONTROLLER_IP = "127.0.0.1"; + public static final int CONTROLLER_PORT = 8181; + public static final String PROTOCOL = "http"; + + public static final String VF_LICENSE = "VF_LICENSE"; + + // tables and fields + public static final String NETCONF_SCHEMA = "sdnctl"; + public static final String SDNCTL_SCHEMA = "sdnctl"; + public static final String DEVICE_AUTHENTICATION_TABLE_NAME = "DEVICE_AUTHENTICATION"; + public static final String CONFIGFILES_TABLE_NAME = "CONFIGFILES"; + public static final String DEVICE_INTERFACE_LOG_TABLE_NAME = "DEVICE_INTERFACE_LOG"; + public static final String FILE_CONTENT_TABLE_FIELD_NAME = "FILE_CONTENT"; + public static final String FILE_NAME_TABLE_FIELD_NAME = "FILE_NAME"; + public static final String USER_NAME_TABLE_FIELD_NAME = "USER_NAME"; + public static final String PASSWORD_TABLE_FIELD_NAME = "PASSWORD"; + public static final String PORT_NUMBER_TABLE_FIELD_NAME = "PORT_NUMBER"; + public static final String VNF_TYPE_TABLE_FIELD_NAME = "VNF_TYPE"; + public static final String SERVICE_INSTANCE_ID_FIELD_NAME = "SERVICE_INSTANCE_ID"; + public static final String REQUEST_ID_FIELD_NAME = "REQUEST_ID"; + public static final String CREATION_DATE_FIELD_NAME = "CREATION_DATE"; + public static final String LOG_FIELD_NAME = "LOG"; + public static final String ASDC_ARTIFACTS_TABLE_NAME = "ASDC_ARTIFACTS"; + + // input fields names + public static final String PAYLOAD = "payload"; + + // constants fo DG + public static final String VNF_TYPE_FIELD_NAME = "org.openecomp.appc.vftype"; + public static final String VNF_VERSION_FIELD_NAME = "org.openecomp.appc.vfversion"; + public static final String VNF_RESOURCE_VERSION_FIELD_NAME = "org.openecomp.appc.resource-version"; + public static final String TARGET_VNF_TYPE = "target-vnf-type"; + public static final String FILE_CONTENT_FIELD_NAME = "file-content"; + public static final String CONNECTION_DETAILS_FIELD_NAME = "connection-details"; + public static final String CONFIGURATION_FILE_FIELD_NAME = "configuration-file-name"; + public static final String VNF_HOST_IP_ADDRESS_FIELD_NAME = "vnf-host-ip-address"; + public static final String UPGRADE_VERSION = "upgrade-version"; + public static final String DG_ERROR_FIELD_NAME = "org.openecomp.appc.dg.error"; + public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; + public static final String RESOURCEKEY = "resourceKey"; + public static final String REQ_ID_FIELD_NAME = "org.openecomp.appc.reqid"; + public static final String API_VERSION_FIELD_NAME = "org.openecomp.appc.apiversion"; + public static final String MODEL_ENTITLMENT_POOL_UUID_NAME = "model.entitlement.pool.uuid"; + public static final String MODEL_LICENSE_KEY_UUID_NAME = "model.license.key.uuid"; + public static final String ENTITLMENT_POOL_UUID_NAME = "entitlement.pool.uuid"; + public static final String LICENSE_KEY_UUID_NAME = "license.key.uuid"; + public static final String IS_ACQUIRE_LICENSE_REQUIRE ="is.acquire-license.require"; + public static final String IS_RELEASE_LICENSE_REQUIRE ="is.release-license.require"; + + public static final String AAI_ENTITLMENT_POOL_UUID_NAME = "aai.input.data.entitlement-assignment-group-uuid"; + public static final String AAI_LICENSE_KEY_UUID_NAME = "aai.input.data.license-assignment-group-uuid"; + public static final String AAI_LICENSE_KEY_VALUE = "aai.input.data.license-key"; + public static final String IS_AAI_ENTITLEMENT_UPDATE_REQUIRE = "is.aai-entitlement-update.require"; + public static final String IS_AAI_LICENSE_UPDATE_REQUIRE = "is.aai-license-update.require"; + public static final String IS_ACQUIRE_ENTITLEMENT_REQUIRE ="is.acquire-entitlement.require"; + public static final String IS_RELEASE_ENTITLEMENT_REQUIRE ="is.release-entitlement.require"; + + public enum ASDC_ARTIFACTS_FIELDS { + SERVICE_UUID, + DISTRIBUTION_ID, + SERVICE_NAME, + SERVICE_DESCRIPTION, + RESOURCE_UUID, + RESOURCE_INSTANCE_NAME, + RESOURCE_NAME, + RESOURCE_VERSION, + RESOURCE_TYPE, + ARTIFACT_UUID, + ARTIFACT_TYPE, + ARTIFACT_VERSION, + ARTIFACT_DESCRIPTION, + INTERNAL_VERSION, + CREATION_DATE, + ARTIFACT_NAME, + ARTIFACT_CONTENT + } +} diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/LicenseDataAccessService.java b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/LicenseDataAccessService.java new file mode 100644 index 000000000..34936f859 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/LicenseDataAccessService.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.licmgr; + +import java.util.Map; + +import org.openecomp.appc.licmgr.exception.DataAccessException; +import org.openecomp.sdnc.sli.resource.dblib.DbLibService; + + +@SuppressWarnings("JavaDoc") +public interface LicenseDataAccessService { + + /** + * + * @param schema + */ + void setSchema(String schema); + + /** + * + * @param vnfType resource name + * @param vnfVersion resource version + * @return map contains requested fields as Strings + * @throws RuntimeException + */ + Map<String,String> retrieveLicenseModelData(String vnfType, String vnfVersion, String... fields) throws DataAccessException; + + /** + * + * @param parameters parameters to store in artifacts table + * @throws RuntimeException + */ + void storeArtifactPayload(Map<String, String> parameters) throws RuntimeException; +} diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/LicenseManager.java b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/LicenseManager.java new file mode 100644 index 000000000..40c7d8bb6 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/LicenseManager.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.licmgr; + +import java.util.Map; + +import org.openecomp.appc.licmgr.exception.DataAccessException; +import org.openecomp.appc.licmgr.objects.LicenseModel; + + +public interface LicenseManager { + + /** + * + * @param vnfType + * @param vnfVersion + * @return pojo object represented license model + * @throws DataAccessException + */ + LicenseModel retrieveLicenseModel(String vnfType, String vnfVersion) throws DataAccessException; + + /** + * + * @param vnfType resource name + * @param vnfVersion resource version + * @return map contains requested fields as Strings + * @throws RuntimeException + */ + Map<String,String> retrieveLicenseModelData(String vnfType, String vnfVersion, String... fields) throws + DataAccessException; + + /** + * + * @param parameters parameters to store in artifacts table + * @throws RuntimeException + */ + void storeArtifactPayload(Map<String, String> parameters) throws RuntimeException; + +} diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/exception/DataAccessException.java b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/exception/DataAccessException.java new file mode 100644 index 000000000..a7e3a084a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/exception/DataAccessException.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.licmgr.exception; + + + +public class DataAccessException extends RuntimeException { + + private static final long serialVersionUID = -155423437162622414L; + + public DataAccessException(){ + } + + public DataAccessException(String message){ + super(message); + } + + public DataAccessException(Throwable cause){ + super(cause); + } + + public DataAccessException(String message , Throwable cause){ + super(message , cause); + } + +} diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/objects/LicenseModel.java b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/objects/LicenseModel.java new file mode 100644 index 000000000..c3c886d77 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/objects/LicenseModel.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.licmgr.objects; + +public class LicenseModel { + + private String entitlementPoolUuid; + + private String licenseKeyGroupUuid; + + public String getEntitlementPoolUuid() { + return entitlementPoolUuid; + } + + public void setEntitlementPoolUuid(String entitlementPoolUuid) { + this.entitlementPoolUuid = entitlementPoolUuid; + } + + public String getLicenseKeyGroupUuid() { + return licenseKeyGroupUuid; + } + + public void setLicenseKeyGroupUuid(String licenseKeyGroupUuid) { + this.licenseKeyGroupUuid = licenseKeyGroupUuid; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/.gitignore b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/pom.xml b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/pom.xml new file mode 100644 index 000000000..1b209f1e0 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/pom.xml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-license-manager</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-license-manager-core</artifactId> + <packaging>bundle</packaging> + + <name>APPC License Manager Bundle</name> + <description>appc-license-manager-core OSGi bundle project.</description> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-license-manager-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.sun.mail</groupId> + <artifactId>javax.mail</artifactId> + <version>1.5.0</version> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Embed-Dependency>!dblib-provider,appc-common,eelf-core,logback-core,logback-classic,javax.mail;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Export-Service>org.openecomp.appc.licmgr.LicenseManager</Export-Service> + <Import-Package>org.openecomp.appc.licmgr,org.openecomp.appc.licmgr.exception,org.openecomp.appc.licmgr.objects,javax.mail.internet,!javax.mail,!groovy.lang,!javax.jms,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseDataAccessServiceImpl.java b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseDataAccessServiceImpl.java new file mode 100644 index 000000000..2aff1ffb9 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseDataAccessServiceImpl.java @@ -0,0 +1,177 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.licmgr.impl; + +import org.openecomp.appc.licmgr.Constants; +import org.openecomp.appc.licmgr.LicenseDataAccessService; +import org.openecomp.appc.licmgr.exception.DataAccessException; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.resource.dblib.DbLibService; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +import javax.sql.rowset.CachedRowSet; + +import static org.openecomp.appc.licmgr.Constants.ASDC_ARTIFACTS_FIELDS; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + + +@SuppressWarnings("JavaDoc") +class LicenseDataAccessServiceImpl implements LicenseDataAccessService { + + private static EELFLogger logger = EELFManager.getInstance().getLogger(LicenseDataAccessServiceImpl.class); + + public void setSchema(String schema) { + this.schema = schema; + } + + private String schema; + + private DbLibService dbLibService; + + private void checkDbLibService() throws DataAccessException { + if (null != dbLibService) {return;} + + //get dblib service and send it to DAService + BundleContext bctx = FrameworkUtil.getBundle(LicenseManagerImpl.class).getBundleContext(); + ServiceReference sref = bctx.getServiceReference(DbLibService.class.getName()); + dbLibService = (DbLibService)bctx.getService(sref); + + } + + /** + * empty constructor + */ + public LicenseDataAccessServiceImpl(){} + + @Override + public Map<String,String> retrieveLicenseModelData(String vnfType, String vnfVersion, String... fields) throws + DataAccessException { + + checkDbLibService(); + + Map<String,String> result = new HashMap<>(); + if (null == fields || 0 == fields.length) fields = new String[]{ASDC_ARTIFACTS_FIELDS.ARTIFACT_CONTENT.name()}; + + String queryString = buildQueryStatement(); + + ArrayList<String> argList = new ArrayList<>(); + argList.add(vnfType); + argList.add(vnfVersion); + argList.add(Constants.VF_LICENSE); + + try { + + final CachedRowSet data = dbLibService.getData(queryString, argList, Constants.NETCONF_SCHEMA); + + if (data.first()) { + for (String field : fields) { + result.put(field, data.getString(field)); + } + } else { + String msg = "Missing license model for VNF_TYPE: " + vnfType + " and VNF_VERSION: " + vnfVersion + " in table " + Constants.ASDC_ARTIFACTS_TABLE_NAME; + logger.info(msg); + } + } catch (SQLException e) { + logger.error("Error Accessing Database " + e); + throw new DataAccessException(e); + } + + return result; + } + + private String buildQueryStatement() { + return "select * " + "from " + Constants.ASDC_ARTIFACTS_TABLE_NAME + " " + + "where " + ASDC_ARTIFACTS_FIELDS.RESOURCE_NAME.name() + " = ?" + + " AND " + ASDC_ARTIFACTS_FIELDS.RESOURCE_VERSION.name() + " = ?" + + " AND " + ASDC_ARTIFACTS_FIELDS.ARTIFACT_TYPE.name() + " = ?"; + } + + /** + * Implementation of storeArtifactPayload() + * @see LicenseDataAccessService + */ + @Override + public void storeArtifactPayload(Map<String, String> parameters) throws RuntimeException { + + checkDbLibService(); + + if(parameters == null || parameters.isEmpty()) { + throw new RuntimeException("No parameters for insert are provided"); + } + + String insertStr = "INSERT INTO " + Constants.ASDC_ARTIFACTS_TABLE_NAME + "("; + String valuesStr = "VALUES("; + String insertStatementStr; + + ArrayList<String> params = new ArrayList<>(); + boolean firstTime = true; + for(Map.Entry<String, String> entry : parameters.entrySet()) { + if(!firstTime) { + insertStr += ","; + valuesStr += ","; + } + else { + firstTime = false; + } + insertStr += entry.getKey(); + valuesStr += "?"; + + params.add(entry.getValue()); + } + + insertStr += ")"; + valuesStr += ")"; + insertStatementStr = insertStr + " " + valuesStr; + + executeStoreArtifactPayload(insertStatementStr, params); + } + + /** + * Exexutes insert statement for artifact payload + * @param insertStatementStr + * @param params + * @throws RuntimeException + */ + private void executeStoreArtifactPayload(String insertStatementStr, ArrayList<String> params) throws RuntimeException { + + try { + logger.info("used schema=" + this.schema); + logger.info("insert statement=" + insertStatementStr); + + dbLibService.writeData(insertStatementStr, params, this.schema); + + logger.info("finished to execute insert"); + + } catch (SQLException e) { + logger.error("Storing Artifact payload failed - " + insertStatementStr); + throw new RuntimeException("Storing Artifact payload failed - " + insertStatementStr); + } + } + +} diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseManagerImpl.java b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseManagerImpl.java new file mode 100644 index 000000000..815bb02ab --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseManagerImpl.java @@ -0,0 +1,100 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.licmgr.impl; + +import static org.openecomp.appc.licmgr.Constants.ASDC_ARTIFACTS_FIELDS.ARTIFACT_CONTENT; + +import java.util.Map; + +import org.openecomp.appc.licmgr.Constants; +import org.openecomp.appc.licmgr.LicenseDataAccessService; +import org.openecomp.appc.licmgr.LicenseManager; +import org.openecomp.appc.licmgr.exception.DataAccessException; +import org.openecomp.appc.licmgr.objects.LicenseModel; + + +@SuppressWarnings("all") +public class LicenseManagerImpl implements LicenseManager { + + private LicenseDataAccessService DAService; + + public void setDAService(LicenseDataAccessService daSrv){ + DAService = daSrv; + } + + public LicenseManagerImpl() { + DAService = new LicenseDataAccessServiceImpl(); + DAService.setSchema(Constants.SDNCTL_SCHEMA); + } + + @Override + public LicenseModel retrieveLicenseModel(String vnfType, String vnfVersion) throws DataAccessException { + + LicenseModel licenseModel; + try { + Map<String,String> resultMap = DAService.retrieveLicenseModelData(vnfType, vnfVersion); + if (resultMap.isEmpty()) { + throw new DataAccessException(String.format("License model not found for vnfType='%s' and vnfVersion='%s'", vnfType, vnfVersion)); + } + String licenseModelXML = resultMap.get(ARTIFACT_CONTENT.name()); + licenseModel = convert(licenseModelXML); // JAXBUtil.<VfLicenseModel>toObject(licenseModelXML, VfLicenseModel.class); + } catch (DataAccessException le) { + throw le; + } catch (Exception e) { + throw new DataAccessException(e); + } + return licenseModel; + } + + @Override + public Map<String, String> retrieveLicenseModelData(String vnfType, String vnfVersion, String... fields) throws DataAccessException { + + Map<String,String> resultMap = DAService.retrieveLicenseModelData(vnfType, vnfVersion, fields); + return resultMap; + } + + @Override + public void storeArtifactPayload(Map<String, String> parameters) throws RuntimeException { + + DAService.storeArtifactPayload(parameters); + } + + private static LicenseModel convert(String xml) { + + LicenseModel licenseModel = new LicenseModel(); + + int posEntitlementStart = xml.indexOf("<entitlement-pool-uuid>"); + int posEntitlementEnd = xml.indexOf("</entitlement-pool-uuid>", posEntitlementStart); + if (-1 != posEntitlementStart) { + licenseModel.setEntitlementPoolUuid(xml.substring(posEntitlementStart + "<entitlement-pool-uuid>".length(), posEntitlementEnd)); + } + + int posLicenseStart = xml.indexOf("<license-key-group-uuid>"); + int posLicenseEnd = xml.indexOf("</license-key-group-uuid>", posEntitlementStart); + if (-1 != posLicenseStart) { + licenseModel.setLicenseKeyGroupUuid(xml.substring(posLicenseStart + "<license-key-group-uuid>".length(), posLicenseEnd)); + } + + return licenseModel; + } + +} diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..c8efb8390 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- + Starter Blueprint Camel Definition appc-command-executor-blueprint +--> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + + <bean id="licenseServiceBean" class="org.openecomp.appc.licmgr.impl.LicenseManagerImpl" scope="singleton" activation="lazy"/> + <service id="licenseService" interface="org.openecomp.appc.licmgr.LicenseManager" ref="licenseServiceBean"/> + +</blueprint> diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..9d9e1d787 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,49 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + + +#Property below provided by appc.properties +#dmaap.poolMembers=<DMAAP_IP>:3904 + +dmaap.topic.read=APPC-TEST2 +dmaap.topic.write=APPC-TEST2 +#dmaap.topic.read.filter={"class":"Assigned","field":"request"} +dmaap.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]} +dmaap.client.name=APPC-TEST-CLIENT-LIC-MGR-MAIN +dmaap.client.name.id=0 +#dmaap.client.key=random +#dmaap.client.secret=random + +dmaap.threads.queuesize.min=1 +dmaap.threads.queuesize.max=1000 +dmaap.threads.poolsize.min=2 +dmaap.threads.poolsize.max=2 + +# +# This needs to be changed so that the action can be appended to the end of the URL path +# +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:topology-service +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider: diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerImplTest.java b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerImplTest.java new file mode 100644 index 000000000..41bc7cadf --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerImplTest.java @@ -0,0 +1,22 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.licmgr; diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerMock.java b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerMock.java new file mode 100644 index 000000000..ca7c1f2e9 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerMock.java @@ -0,0 +1,57 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.licmgr; + +import java.util.Map; + +import org.openecomp.appc.licmgr.LicenseManager; +import org.openecomp.appc.licmgr.exception.DataAccessException; +import org.openecomp.appc.licmgr.objects.LicenseModel; + + +public class LicenseManagerMock implements LicenseManager { + + LicenseModel licenseModel; + @Override + public LicenseModel retrieveLicenseModel(String vnfType, String vnfVersion) throws DataAccessException { + if (vnfType == "VSCP" && vnfVersion == "123"){ + return licenseModel; + } + else { + return null; + } + } + + @Override public Map<String, String> retrieveLicenseModelData(String vnfType, String vnfVersion, String... fields) + throws DataAccessException { + return null; + } + + @Override public void storeArtifactPayload(Map<String, String> parameters) throws RuntimeException { + + } + + public void storeLicenseModel(LicenseModel licenseModel){ + this.licenseModel = licenseModel; + + } +} diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerPluginImplTest.java b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerPluginImplTest.java new file mode 100644 index 000000000..41bc7cadf --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerPluginImplTest.java @@ -0,0 +1,22 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.licmgr; diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseServiceMock.java b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseServiceMock.java new file mode 100644 index 000000000..e496da7b5 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseServiceMock.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.licmgr; + +import java.util.HashMap; +import java.util.Map; + +import org.openecomp.appc.licmgr.LicenseDataAccessService; +import org.openecomp.appc.licmgr.exception.DataAccessException; +import org.openecomp.sdnc.sli.resource.dblib.DbLibService; + +class LicenseServiceMock implements LicenseDataAccessService { + + private String configFile; + private HashMap<String, String> backupConf; + + @Override + public void setSchema(String schema) { + } + + void setConfigFile(String configFile) { + this.configFile = configFile; + } + + public HashMap<String, String> getBackupConf() { + return backupConf; + } + + @Override + public Map<String, String> retrieveLicenseModelData(String vnfType, String vnfVersion, String... fields) throws DataAccessException { + return null; + } + + @Override + public void storeArtifactPayload(Map<String, String> parameters) throws DataAccessException { + } +} diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/TestVfLicenseModelConvert.java b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/TestVfLicenseModelConvert.java new file mode 100644 index 000000000..26482a1dc --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/TestVfLicenseModelConvert.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.licmgr; + +/* +import org.openecomp.appc.licmgr.objects.VfLicenseModel; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Unmarshaller; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +*/ + +public class TestVfLicenseModelConvert { +/* + public static void main(String args[]) { + + try { + + //create JAXB context + JAXBContext context = JAXBContext.newInstance(VfLicenseModel.class); + + //Create Unmarshaller using JAXB context + Unmarshaller unmarshaller = context.createUnmarshaller(); + + Path xmlPath = Paths.get("src/test/resources/xml/vf-license-model.xml"); + InputStream xmlInputStream = Files.newInputStream(xmlPath); + + VfLicenseModel licenseModel = (VfLicenseModel) unmarshaller.unmarshal(xmlInputStream); + + String vnfId = licenseModel.getVnfId(); + String vendorName = licenseModel.getVendorName(); + + } catch (Exception e) { + e.printStackTrace(); + } + } +*/ +} diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-features/.gitignore b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-features/.gitignore new file mode 100644 index 000000000..2992ae832 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-features/.gitignore @@ -0,0 +1,3 @@ +/target/ +/bin/ +/.settings/ diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-features/pom.xml b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-features/pom.xml new file mode 100644 index 000000000..3adbcf5e2 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-features/pom.xml @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-license-manager</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <name>appc-license-manager-features</name> + <artifactId>appc-license-manager-features</artifactId> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-license-manager-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-license-manager-core</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> +<!-- <plugin> --> + <!-- launches the feature test, which validates that your karaf feature + can be installed inside of a karaf container. It doesn't validate that your + functionality works correctly, just that you have all of the dependent bundles + defined correctly. --> +<!-- <groupId>org.apache.maven.plugins</groupId> --> +<!-- <artifactId>maven-surefire-plugin</artifactId> --> +<!-- <version>2.16</version> --> +<!-- <configuration> --> +<!-- <systemPropertyVariables> --> +<!-- <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId> --> +<!-- <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId> --> +<!-- <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version> --> +<!-- </systemPropertyVariables> --> +<!-- <dependenciesToScan> --> +<!-- <dependency>org.opendaylight.yangtools:features-test</dependency> --> +<!-- </dependenciesToScan> --> +<!-- <classpathDependencyExcludes> --> + <!-- The dependencies which bring in AbstractDataBrokerTest class brings + in a second PaxExam container which results in the feature tests failing + with a message similar to: "ERROR o.ops4j.pax.exam.spi.PaxExamRuntime - Ambiguous + TestContainer ..." This excludes the container we don't want to use. --> +<!-- <classpathDependencyExcludes>org.ops4j.pax.exam:pax-exam-container-native</classpathDependencyExcludes> --> +<!-- </classpathDependencyExcludes> --> +<!-- </configuration> --> +<!-- </plugin> --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + + <!-- Skipping ODL feature test --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <skipTests>true</skipTests> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-features/src/main/resources/features.xml b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-features/src/main/resources/features.xml new file mode 100644 index 000000000..34635b839 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/appc-license-manager-features/src/main/resources/features.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="appc-license-manager-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + + <feature name='appc-license-manager' description="application license manager" version='${project.version}'> + <bundle>mvn:com.sun.mail/javax.mail/1.5.0</bundle> + <bundle>mvn:org.openecomp.appc/appc-license-manager-api/${project.version}</bundle> + <bundle>mvn:org.openecomp.appc/appc-license-manager-core/${project.version}</bundle> + </feature> + +</features> diff --git a/app-c/appc/appc-dispatcher/appc-license-manager/pom.xml b/app-c/appc/appc-dispatcher/appc-license-manager/pom.xml new file mode 100644 index 000000000..f590f42b5 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-license-manager/pom.xml @@ -0,0 +1,22 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-license-manager</artifactId> + <packaging>pom</packaging> + <name>APPC License Manager</name> + <description>APPC License Manager</description> + + <!-- ================================================================================== --> + <!-- The modules we build --> + <!-- ================================================================================== --> + <modules> + <module>appc-license-manager-api</module> + <module>appc-license-manager-core</module> + <module>appc-license-manager-features</module> + </modules> + +</project> diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/.gitignore b/app-c/appc/appc-dispatcher/appc-lifecycle-management/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-lifecycle-management/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/.gitignore b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/pom.xml b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/pom.xml new file mode 100644 index 000000000..67e52a2a6 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/pom.xml @@ -0,0 +1,36 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-lifecycle-management</artifactId> + <version>1.0.0</version> + </parent> + + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-lifecycle-management-api</artifactId> + <version>1.0.0</version> + <packaging>bundle</packaging> + + <name>appc-lifecycle-management-api</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Export-Package>org.openecomp.appc.lifecyclemanager.*</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/LifecycleManager.java b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/LifecycleManager.java new file mode 100644 index 000000000..795e340e0 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/LifecycleManager.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lifecyclemanager; + + +import org.openecomp.appc.lifecyclemanager.objects.LifecycleException; +import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException; + +public interface LifecycleManager { + String getNextState(String vnfType, String currentState, String event) throws NoTransitionDefinedException,LifecycleException; +} diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/LCMResponse.java b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/LCMResponse.java new file mode 100644 index 000000000..70aefee26 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/LCMResponse.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lifecyclemanager.objects; + +public enum LCMResponse { + INVALID_INPUT_PARAMETERS, + NO_STATE_CHANGE, + NO_TRANSITION_DEFINED, + VALID_TRANSITION; + + public String toString(){ + return this.name(); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/LifecycleException.java b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/LifecycleException.java new file mode 100644 index 000000000..d729ca161 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/LifecycleException.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lifecyclemanager.objects; + + +public class LifecycleException extends Exception { + public final String currentState; + public final String event; + public LifecycleException(Exception e,String currentState,String event){ + super(e); + this.currentState = currentState; + this.event = event; + + } +} diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/NoTransitionDefinedException.java b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/NoTransitionDefinedException.java new file mode 100644 index 000000000..688be531d --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/NoTransitionDefinedException.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lifecyclemanager.objects; + + +public class NoTransitionDefinedException extends Exception { + public final String currentState; + public final String event; + public NoTransitionDefinedException(String message,String currentState,String event){ + super(message); + this.currentState = currentState; + this.event = event; + + } +} diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/VNFOperationOutcome.java b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/VNFOperationOutcome.java new file mode 100644 index 000000000..9ad1cc701 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/VNFOperationOutcome.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lifecyclemanager.objects; + +public enum VNFOperationOutcome { + SUCCESS,FAILURE,EXPIRE; + public String toString(){ + return this.name(); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/.gitignore b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/pom.xml b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/pom.xml new file mode 100644 index 000000000..b8535cb62 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/pom.xml @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + + <!-- + + 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. + --> + + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-lifecycle-management</artifactId> + <version>1.0.0</version> + </parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-lifecycle-management-core</artifactId> + <packaging>bundle</packaging> + + <name>appc-lifecycle-management-core Bundle</name> + <description>appc-lifecycle-management-core OSGi bundle project.</description> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-lifecycle-management-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>state-machine-lib</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.att.eelf</groupId> + <artifactId>eelf-core</artifactId> + <version>${eelf.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>domain-model-lib</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Export-Service>org.openecomp.appc.lifecyclemanager.LifecycleManager</Export-Service> + <Import-Package>org.openecomp.appc.lifecyclemanager.*,!groovy.lang,!javax.*,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.apache.commons.lang3,!org.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/java/org/openecomp/appc/lifecyclemanager/helper/MetadataReader.java b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/java/org/openecomp/appc/lifecyclemanager/helper/MetadataReader.java new file mode 100644 index 000000000..516bb7e4b --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/java/org/openecomp/appc/lifecyclemanager/helper/MetadataReader.java @@ -0,0 +1,337 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lifecyclemanager.helper; + + +import org.openecomp.appc.domainmodel.lcm.VNFOperation; +import org.openecomp.appc.lifecyclemanager.objects.VNFOperationOutcome; +import org.openecomp.appc.statemachine.objects.Event; +import org.openecomp.appc.statemachine.objects.State; +import org.openecomp.appc.statemachine.objects.StateMachineMetadata; + + +public class MetadataReader { + + private enum VNFStates { + Not_Instantiated, Instantiated, Configuring, Configured, Testing, Tested, Rebuilding, Restarting, Error, Running, Unknown, Terminating, Stopping, Stopped, + Backing_Up, Snapshotting, Software_Uploading, Upgrading, Rollbacking, Licensing, Migrating, Evacuating; + } + + @SuppressWarnings("unused") + public StateMachineMetadata readMetadata(String vnfType){ + State NOT_INSTANTIATED = new State(VNFStates.Not_Instantiated.toString()); + State INSTANTIATED = new State(VNFStates.Instantiated.toString()); + State CONFIGURING = new State(VNFStates.Configuring.toString()); + State CONFIGURED = new State(VNFStates.Configured.toString()); + State TESTING = new State(VNFStates.Testing.toString()); + State TESTED = new State(VNFStates.Tested.toString()); + State REBUILDING = new State(VNFStates.Rebuilding.toString()); + State RESTARTING = new State(VNFStates.Restarting.toString()); + State ERROR = new State(VNFStates.Error.toString()); + State RUNNING = new State(VNFStates.Running.toString()); + State UNKNOWN = new State(VNFStates.Unknown.toString()); + State TERMINATING = new State(VNFStates.Terminating.toString()); + State STOPPING = new State(VNFStates.Stopping.toString()); + State STOPPED = new State(VNFStates.Stopped.toString()); + +// State PRE_UPGRADE_TESTING = new State(VNFStates.Pre_Upgrade_Testing.toString()); + State BACKING_UP = new State(VNFStates.Backing_Up.toString()); + State SNAPSHOTTING = new State(VNFStates.Snapshotting.toString()); + State SOFTWARE_UPLOADING = new State(VNFStates.Software_Uploading.toString()); + State UPGRADING = new State(VNFStates.Upgrading.toString()); + State ROLLBACKING = new State(VNFStates.Rollbacking.toString()); + + State MIGRATING = new State(VNFStates.Migrating.toString()); + State EVACUATING = new State(VNFStates.Evacuating.toString()); + + Event CONFIGURE = new Event(VNFOperation.Configure.toString()); + Event HEALTHCHECK = new Event(VNFOperation.HealthCheck.toString()); + Event TEST = new Event(VNFOperation.Test.toString()); + Event START = new Event(VNFOperation.Start.toString()); + Event TERMINATE = new Event(VNFOperation.Terminate.toString()); + Event RESTART = new Event(VNFOperation.Restart.toString()); + Event REBUILD = new Event(VNFOperation.Rebuild.toString()); + Event STOP = new Event(VNFOperation.Stop.toString()); + Event MODIFY_CONFIG = new Event(VNFOperation.ModifyConfig.toString()); + Event BACKUP = new Event(VNFOperation.Backup.toString()); + Event SNAPSHOT = new Event(VNFOperation.Snapshot.toString()); + Event SOFTWARE_UPLOAD = new Event(VNFOperation.SoftwareUpload.toString()); + Event LIVE_UPGRADE = new Event(VNFOperation.LiveUpgrade.toString()); + Event ROLLBACK = new Event(VNFOperation.Rollback.toString()); + Event SYNC = new Event(VNFOperation.Sync.toString()); + Event AUDIT = new Event(VNFOperation.Audit.toString()); + Event MIGRATE = new Event(VNFOperation.Migrate.toString()); + Event EVACUATE = new Event(VNFOperation.Evacuate.toString()); + + Event LOCK = new Event(VNFOperation.Lock.toString()); + Event UNLOCK = new Event(VNFOperation.Unlock.toString()); + Event CHECKLOCK = new Event(VNFOperation.CheckLock.toString()); + + Event SUCCESS = new Event(VNFOperationOutcome.SUCCESS.toString()); + Event FAILURE = new Event(VNFOperationOutcome.FAILURE.toString()); + + + StateMachineMetadata.StateMachineMetadataBuilder builder = new StateMachineMetadata.StateMachineMetadataBuilder(); + + builder = builder.addState(NOT_INSTANTIATED); + builder = builder.addState(INSTANTIATED); + builder = builder.addState(CONFIGURING); + builder = builder.addState(CONFIGURED); + builder = builder.addState(TESTING); + builder = builder.addState(TESTED); + builder = builder.addState(REBUILDING); + builder = builder.addState(RESTARTING); + builder = builder.addState(ERROR); + builder = builder.addState(RUNNING); + builder = builder.addState(UNKNOWN); + builder = builder.addState(TERMINATING); + builder = builder.addState(STOPPING); + builder = builder.addState(STOPPED); +// builder = builder.addState(PRE_UPGRADE_TESTING); + builder = builder.addState(BACKING_UP); + builder = builder.addState(SNAPSHOTTING); + builder = builder.addState(SOFTWARE_UPLOADING); + builder = builder.addState(UPGRADING); + builder = builder.addState(ROLLBACKING); + builder = builder.addState(MIGRATING); + builder = builder.addState(EVACUATING); + + builder = builder.addEvent(CONFIGURE); + builder = builder.addEvent(TEST); + builder = builder.addEvent(START); + builder = builder.addEvent(TERMINATE); + builder = builder.addEvent(RESTART); + builder = builder.addEvent(REBUILD); + builder = builder.addEvent(SUCCESS); + builder = builder.addEvent(FAILURE); + builder = builder.addEvent(STOP); + builder = builder.addEvent(MODIFY_CONFIG); + builder = builder.addEvent(HEALTHCHECK); + builder = builder.addEvent(BACKUP); + builder = builder.addEvent(SNAPSHOT); + builder = builder.addEvent(SOFTWARE_UPLOAD); + builder = builder.addEvent(LIVE_UPGRADE); + builder = builder.addEvent(ROLLBACK); + builder = builder.addEvent(SYNC); + builder = builder.addEvent(AUDIT); + builder = builder.addEvent(MIGRATE); + builder = builder.addEvent(EVACUATE); + builder = builder.addEvent(LOCK); + builder = builder.addEvent(UNLOCK); + builder = builder.addEvent(CHECKLOCK); + + builder = builder.addTransition(INSTANTIATED,CONFIGURE,CONFIGURING); + builder = builder.addTransition(INSTANTIATED,TEST,TESTING); + builder = builder.addTransition(INSTANTIATED,START,RESTARTING); + builder = builder.addTransition(INSTANTIATED,TERMINATE,TERMINATING); + builder = builder.addTransition(INSTANTIATED,RESTART,RESTARTING); + builder = builder.addTransition(INSTANTIATED,REBUILD,REBUILDING); + builder = builder.addTransition(INSTANTIATED,STOP,STOPPING); + builder = builder.addTransition(INSTANTIATED,MODIFY_CONFIG,CONFIGURING); + builder = builder.addTransition(INSTANTIATED,HEALTHCHECK,TESTING); + builder = builder.addTransition(INSTANTIATED,BACKUP,BACKING_UP); + builder = builder.addTransition(INSTANTIATED,SNAPSHOT,SNAPSHOTTING); + builder = builder.addTransition(INSTANTIATED,SOFTWARE_UPLOAD,SOFTWARE_UPLOADING); + builder = builder.addTransition(INSTANTIATED,LIVE_UPGRADE,UPGRADING); + builder = builder.addTransition(INSTANTIATED,ROLLBACK,ROLLBACKING); + builder = builder.addTransition(INSTANTIATED,MIGRATE,MIGRATING); + builder = builder.addTransition(INSTANTIATED,EVACUATE,EVACUATING); + builder = builder.addTransition(INSTANTIATED,LOCK,INSTANTIATED); + builder = builder.addTransition(INSTANTIATED,UNLOCK,INSTANTIATED); + builder = builder.addTransition(INSTANTIATED,CHECKLOCK,INSTANTIATED); + + builder = builder.addTransition(CONFIGURED,CONFIGURE,CONFIGURING); + builder = builder.addTransition(CONFIGURED,TEST,TESTING); + builder = builder.addTransition(CONFIGURED,START,RESTARTING); + builder = builder.addTransition(CONFIGURED,TERMINATE,TERMINATING); + builder = builder.addTransition(CONFIGURED,RESTART,RESTARTING); + builder = builder.addTransition(CONFIGURED,REBUILD,REBUILDING); + builder = builder.addTransition(CONFIGURED,STOP,STOPPING); + builder = builder.addTransition(CONFIGURED,MODIFY_CONFIG,CONFIGURING); + builder = builder.addTransition(CONFIGURED,HEALTHCHECK,TESTING); + builder = builder.addTransition(CONFIGURED,BACKUP,BACKING_UP); + builder = builder.addTransition(CONFIGURED,SNAPSHOT,SNAPSHOTTING); + builder = builder.addTransition(CONFIGURED,SOFTWARE_UPLOAD,SOFTWARE_UPLOADING); + builder = builder.addTransition(CONFIGURED,LIVE_UPGRADE,UPGRADING); + builder = builder.addTransition(CONFIGURED,ROLLBACK,ROLLBACKING); + builder = builder.addTransition(CONFIGURED,SYNC,CONFIGURED); + builder = builder.addTransition(CONFIGURED,AUDIT,CONFIGURED); + builder = builder.addTransition(CONFIGURED,MIGRATE,MIGRATING); + builder = builder.addTransition(CONFIGURED,EVACUATE,EVACUATING); + builder = builder.addTransition(CONFIGURED,LOCK,CONFIGURED); + builder = builder.addTransition(CONFIGURED,UNLOCK,CONFIGURED); + builder = builder.addTransition(CONFIGURED,CHECKLOCK,CONFIGURED); + + builder = builder.addTransition(TESTED,CONFIGURE,CONFIGURING); + builder = builder.addTransition(TESTED,TEST,TESTING); + builder = builder.addTransition(TESTED,START,RESTARTING); + builder = builder.addTransition(TESTED,TERMINATE,TERMINATING); + builder = builder.addTransition(TESTED,RESTART,RESTARTING); + builder = builder.addTransition(TESTED,REBUILD,REBUILDING); + builder = builder.addTransition(TESTED,STOP,STOPPING); + builder = builder.addTransition(TESTED,MODIFY_CONFIG,CONFIGURING); + builder = builder.addTransition(TESTED,HEALTHCHECK,TESTING); + builder = builder.addTransition(TESTED,BACKUP,BACKING_UP); + builder = builder.addTransition(TESTED,SNAPSHOT,SNAPSHOTTING); + builder = builder.addTransition(TESTED,SOFTWARE_UPLOAD,SOFTWARE_UPLOADING); + builder = builder.addTransition(TESTED,LIVE_UPGRADE,UPGRADING); + builder = builder.addTransition(TESTED,ROLLBACK,ROLLBACKING); + builder = builder.addTransition(TESTED,SYNC,TESTED); + builder = builder.addTransition(TESTED,AUDIT,TESTED); + builder = builder.addTransition(TESTED,MIGRATE,MIGRATING); + builder = builder.addTransition(TESTED,EVACUATE,EVACUATING); + builder = builder.addTransition(TESTED,LOCK,TESTED); + builder = builder.addTransition(TESTED,UNLOCK,TESTED); + builder = builder.addTransition(TESTED,CHECKLOCK,TESTED); + + builder = builder.addTransition(RUNNING,CONFIGURE,CONFIGURING); + builder = builder.addTransition(RUNNING,TEST,TESTING); + builder = builder.addTransition(RUNNING,START,RESTARTING); + builder = builder.addTransition(RUNNING,TERMINATE,TERMINATING); + builder = builder.addTransition(RUNNING,RESTART,RESTARTING); + builder = builder.addTransition(RUNNING,REBUILD,REBUILDING); + builder = builder.addTransition(RUNNING,STOP,STOPPING); + builder = builder.addTransition(RUNNING,MODIFY_CONFIG,CONFIGURING); + builder = builder.addTransition(RUNNING,HEALTHCHECK,TESTING); + builder = builder.addTransition(RUNNING,BACKUP,BACKING_UP); + builder = builder.addTransition(RUNNING,SNAPSHOT,SNAPSHOTTING); + builder = builder.addTransition(RUNNING,SOFTWARE_UPLOAD,SOFTWARE_UPLOADING); + builder = builder.addTransition(RUNNING,LIVE_UPGRADE,UPGRADING); + builder = builder.addTransition(RUNNING,ROLLBACK,ROLLBACKING); + builder = builder.addTransition(RUNNING,SYNC,RUNNING); + builder = builder.addTransition(RUNNING,AUDIT,RUNNING); + builder = builder.addTransition(RUNNING,MIGRATE,MIGRATING); + builder = builder.addTransition(RUNNING,EVACUATE,EVACUATING); + builder = builder.addTransition(RUNNING,LOCK,RUNNING); + builder = builder.addTransition(RUNNING,UNLOCK,RUNNING); + builder = builder.addTransition(RUNNING,CHECKLOCK,RUNNING); + + builder = builder.addTransition(ERROR,CONFIGURE,CONFIGURING); + builder = builder.addTransition(ERROR,TEST,TESTING); + builder = builder.addTransition(ERROR,START,RESTARTING); + builder = builder.addTransition(ERROR,TERMINATE,TERMINATING); + builder = builder.addTransition(ERROR,RESTART,RESTARTING); + builder = builder.addTransition(ERROR,REBUILD,REBUILDING); + builder = builder.addTransition(ERROR,STOP,STOPPING); + builder = builder.addTransition(ERROR,MODIFY_CONFIG,CONFIGURING); + builder = builder.addTransition(ERROR,HEALTHCHECK,TESTING); + builder = builder.addTransition(ERROR,BACKUP,BACKING_UP); + builder = builder.addTransition(ERROR,SNAPSHOT,SNAPSHOTTING); + builder = builder.addTransition(ERROR,SOFTWARE_UPLOAD,SOFTWARE_UPLOADING); + builder = builder.addTransition(ERROR,LIVE_UPGRADE,UPGRADING); + builder = builder.addTransition(ERROR,ROLLBACK,ROLLBACKING); + builder = builder.addTransition(ERROR,SYNC,ERROR); + builder = builder.addTransition(ERROR,AUDIT,ERROR); + builder = builder.addTransition(ERROR,MIGRATE,MIGRATING); + builder = builder.addTransition(ERROR,EVACUATE,EVACUATING); + builder = builder.addTransition(ERROR,LOCK,ERROR); + builder = builder.addTransition(ERROR,UNLOCK,ERROR); + builder = builder.addTransition(ERROR,CHECKLOCK,ERROR); + + builder = builder.addTransition(UNKNOWN,CONFIGURE,CONFIGURING); + builder = builder.addTransition(UNKNOWN,TEST,TESTING); + builder = builder.addTransition(UNKNOWN,START,RESTARTING); + builder = builder.addTransition(UNKNOWN,TERMINATE,TERMINATING); + builder = builder.addTransition(UNKNOWN,RESTART,RESTARTING); + builder = builder.addTransition(UNKNOWN,REBUILD,REBUILDING); + builder = builder.addTransition(UNKNOWN,STOP,STOPPING); + builder = builder.addTransition(UNKNOWN,MODIFY_CONFIG,CONFIGURING); + builder = builder.addTransition(UNKNOWN,HEALTHCHECK,TESTING); + builder = builder.addTransition(UNKNOWN,BACKUP,BACKING_UP); + builder = builder.addTransition(UNKNOWN,SNAPSHOT,SNAPSHOTTING); + builder = builder.addTransition(UNKNOWN,SOFTWARE_UPLOAD,SOFTWARE_UPLOADING); + builder = builder.addTransition(UNKNOWN,LIVE_UPGRADE,UPGRADING); + builder = builder.addTransition(UNKNOWN,ROLLBACK,ROLLBACKING); + builder = builder.addTransition(UNKNOWN,SYNC,UNKNOWN); + builder = builder.addTransition(UNKNOWN,AUDIT,UNKNOWN); + builder = builder.addTransition(UNKNOWN,MIGRATE,MIGRATING); + builder = builder.addTransition(UNKNOWN,EVACUATE,EVACUATING); + builder = builder.addTransition(UNKNOWN,LOCK,UNKNOWN); + builder = builder.addTransition(UNKNOWN,UNLOCK,UNKNOWN); + builder = builder.addTransition(UNKNOWN,CHECKLOCK,UNKNOWN); + + builder = builder.addTransition(STOPPED,CONFIGURE,CONFIGURING); + builder = builder.addTransition(STOPPED,TEST,TESTING); + builder = builder.addTransition(STOPPED,START,RESTARTING); + builder = builder.addTransition(STOPPED,TERMINATE,TERMINATING); + builder = builder.addTransition(STOPPED,RESTART,RESTARTING); + builder = builder.addTransition(STOPPED,REBUILD,REBUILDING); + builder = builder.addTransition(STOPPED,MODIFY_CONFIG,CONFIGURING); + builder = builder.addTransition(STOPPED,HEALTHCHECK,TESTING); + builder = builder.addTransition(STOPPED,BACKUP,BACKING_UP); + builder = builder.addTransition(STOPPED,SNAPSHOT,SNAPSHOTTING); + builder = builder.addTransition(STOPPED,SOFTWARE_UPLOAD,SOFTWARE_UPLOADING); + builder = builder.addTransition(STOPPED,LIVE_UPGRADE,UPGRADING); + builder = builder.addTransition(STOPPED,ROLLBACK,ROLLBACKING); + builder = builder.addTransition(STOPPED,MIGRATE,MIGRATING); + builder = builder.addTransition(STOPPED,EVACUATE,EVACUATING); + builder = builder.addTransition(STOPPED,LOCK,STOPPED); + builder = builder.addTransition(STOPPED,UNLOCK,STOPPED); + builder = builder.addTransition(STOPPED,CHECKLOCK,STOPPED); + + builder = builder.addTransition(CONFIGURING,SUCCESS,CONFIGURED); + builder = builder.addTransition(CONFIGURING,FAILURE,ERROR); + + builder = builder.addTransition(TESTING,SUCCESS,TESTED); + builder = builder.addTransition(TESTING,FAILURE,ERROR); + + builder = builder.addTransition(RESTARTING,SUCCESS,RUNNING); + builder = builder.addTransition(RESTARTING,FAILURE,ERROR); + + builder = builder.addTransition(TERMINATING,SUCCESS,NOT_INSTANTIATED); + builder = builder.addTransition(TERMINATING,FAILURE,ERROR); + + builder = builder.addTransition(REBUILDING,SUCCESS,RUNNING); + builder = builder.addTransition(REBUILDING,FAILURE,ERROR); + + builder = builder.addTransition(STOPPING,SUCCESS,STOPPED); + builder = builder.addTransition(STOPPING,FAILURE,ERROR); + +// builder = builder.addTransition(PRE_UPGRADE_TESTING,SUCCESS,TESTED); +// builder = builder.addTransition(PRE_UPGRADE_TESTING,FAILURE,ERROR); + + builder = builder.addTransition(BACKING_UP,SUCCESS,RUNNING); + builder = builder.addTransition(BACKING_UP,FAILURE,ERROR); + + builder = builder.addTransition(SNAPSHOTTING,SUCCESS,RUNNING); + builder = builder.addTransition(SNAPSHOTTING,FAILURE,ERROR); + + builder = builder.addTransition(SOFTWARE_UPLOADING,SUCCESS,RUNNING); + builder = builder.addTransition(SOFTWARE_UPLOADING,FAILURE,ERROR); + + builder = builder.addTransition(UPGRADING,SUCCESS,RUNNING); + builder = builder.addTransition(UPGRADING,FAILURE,ERROR); + + builder = builder.addTransition(ROLLBACKING,SUCCESS,RUNNING); + builder = builder.addTransition(ROLLBACKING,FAILURE,ERROR); + + builder = builder.addTransition(MIGRATING,SUCCESS,RUNNING); + builder = builder.addTransition(MIGRATING,FAILURE,ERROR); + + builder = builder.addTransition(EVACUATING,SUCCESS,RUNNING); + builder = builder.addTransition(EVACUATING,FAILURE,ERROR); + + return builder.build(); + + } + +} diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/java/org/openecomp/appc/lifecyclemanager/impl/LifecycleManagerImpl.java b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/java/org/openecomp/appc/lifecyclemanager/impl/LifecycleManagerImpl.java new file mode 100644 index 000000000..ffaab140a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/java/org/openecomp/appc/lifecyclemanager/impl/LifecycleManagerImpl.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.lifecyclemanager.impl; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.openecomp.appc.i18n.Msg; +import org.openecomp.appc.lifecyclemanager.LifecycleManager; +import org.openecomp.appc.lifecyclemanager.helper.MetadataReader; +import org.openecomp.appc.lifecyclemanager.objects.*; +import org.openecomp.appc.statemachine.*; +import org.openecomp.appc.statemachine.impl.StateMachineFactory; +import org.openecomp.appc.statemachine.objects.*; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; + + +public class LifecycleManagerImpl implements LifecycleManager{ + + private MetadataReader metadataReader; + private static Map<String,StateMachine> stateMachineMap = new ConcurrentHashMap<String,StateMachine>(); + private static final EELFLogger logger = EELFManager.getInstance().getLogger(LifecycleManagerImpl.class); + private static EELFLogger errorLogger = EELFManager.getInstance().getErrorLogger(); + public LifecycleManagerImpl(){ + this.metadataReader = new MetadataReader(); + } + + @Override + public String getNextState(String vnfType, String currentState, String event) throws NoTransitionDefinedException,LifecycleException{ + if (logger.isTraceEnabled()) { + logger.trace("Entering to getNextState with vnfType = "+ vnfType + ", currentState = " + currentState + ", event = " + event); + } + + State nextState = null; + StateMachine machine = null; + StateMachineResponse response; + try { + machine = this.getStateMachine(vnfType); + response = machine.handleEvent(new State(currentState),new Event(event)); + if(Response.NO_TRANSITION_DEFINED.equals(response.getResponse())){ + errorLogger.error(EELFResourceManager.format(Msg.VF_ILLEGAL_COMMAND, vnfType,event,currentState)); + throw new NoTransitionDefinedException("No Transition Defined for currentState = " + currentState + ", event = " + event,currentState,event); + } + nextState = response.getNextState(); + } catch (InvalidInputException e) { + logger.error(e.getMessage()); + throw new LifecycleException(e,currentState,event); + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting from getNextState with (nextState = "+nextState.getStateName()!=null?nextState.getStateName():"null"+")"); + } + return nextState.getStateName(); + } + + private StateMachine getStateMachine(String vnfType){ + if (logger.isTraceEnabled()) { + logger.trace("Entering to getNextState with vnfType = "+ vnfType); + } + if(vnfType == null){ + vnfType = "DEFAULT"; + } + StateMachine machine = stateMachineMap.get(vnfType); + if(machine == null){ + StateMachineMetadata metadata = metadataReader.readMetadata(vnfType); + machine = StateMachineFactory.getStateMachine(metadata); + stateMachineMap.put(vnfType,machine); + } + + logger.trace("Exiting getStateMachine with (StateMachine = "+stateMachineMap.get(vnfType)!=null?stateMachineMap.get(vnfType).toString():"null"+")"); + return stateMachineMap.get(vnfType); + } + +} diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..a7d0b83ea --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- + Starter Blueprint Camel Definition appc-aai-adapter-blueprint +--> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + <bean id="lifecycleManagerBean" class="org.openecomp.appc.lifecyclemanager.impl.LifecycleManagerImpl" scope="singleton" > +</bean> + + <service id="lcmService" interface="org.openecomp.appc.lifecyclemanager.LifecycleManager" ref="lifecycleManagerBean"/> + +</blueprint> diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..63711c27f --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,48 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + +#Property below provided by appc.properties +#dmaap.poolMembers=<DMAAP_IP>:3904 + +dmaap.topic.read=APPC-TEST2 +dmaap.topic.write=APPC-TEST2 +#dmaap.topic.read.filter={"class":"Assigned","field":"request"} +dmaap.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]} +dmaap.client.name=APPC-TEST-CLIENT-LC-MGMT-MAIN +dmaap.client.name.id=0 +#dmaap.client.key=random +#dmaap.client.secret=random + +dmaap.threads.queuesize.min=1 +dmaap.threads.queuesize.max=1000 +dmaap.threads.poolsize.min=1 +dmaap.threads.poolsize.max=2 + +# +# This needs to be changed so that the action can be appended to the end of the URL path +# +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:topology-service +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider: diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/test/java/org/openecomp/appc/TestLifecycleManager.java b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/test/java/org/openecomp/appc/TestLifecycleManager.java new file mode 100644 index 000000000..4c14e90bd --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/test/java/org/openecomp/appc/TestLifecycleManager.java @@ -0,0 +1,155 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc; + +import org.junit.Assert; +import org.junit.Test; +import org.openecomp.appc.domainmodel.lcm.VNFOperation; +import org.openecomp.appc.lifecyclemanager.LifecycleManager; +import org.openecomp.appc.lifecyclemanager.helper.MetadataReader; +import org.openecomp.appc.lifecyclemanager.impl.LifecycleManagerImpl; +import org.openecomp.appc.lifecyclemanager.objects.LifecycleException; +import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException; +import org.openecomp.appc.statemachine.objects.*; + +import java.util.*; + + +public class TestLifecycleManager { + + private static final State[] VALID_LOCK_STATES = new State[] { + new State("Instantiated"), + new State("Configured"), + new State("Tested"), + new State("Running"), + new State("Error"), + new State("Unknown"), + new State("Stopped"), + }; + + @Test + public void handleEvent() throws InvalidInputException, LifecycleException, NoTransitionDefinedException { + + MetadataReader metadataReader = new MetadataReader(); + StateMachineMetadata metadata = metadataReader.readMetadata(null); + + LifecycleManagerImpl lifecycleManager = new LifecycleManagerImpl(); + + /* + Testing Positive Scenario passing the valid events and validating the StateMachineResponse + */ + for(State state:metadata.getStates()){ + + for(Transition transition:state.getTransitions()){ + Event event = transition.getEvent(); + State nextStateFromMetadata = transition.getNextState(); + + String expectedNextState = lifecycleManager.getNextState(null,state.toString(),event.toString()); + Assert.assertEquals(expectedNextState,nextStateFromMetadata.toString()); + } + } + + /* + Testing Negative Scenarios, 1. Passing the valid Events for which Transition is not defined in + Metadata and validating the StateMachineResponse 2. Passing the invalid events which are not + registered as events in the StateMachineMetadata and validating StateMachineResponse + */ + for(State state:metadata.getStates()){ + + for(Transition transition:state.getTransitions()){ + List<Event> negativeEvents = getNegativeEvents(state,metadata.getEvents()); + + for(Event negativeEvent:negativeEvents){ + boolean flag =false; + try{ + String response = lifecycleManager.getNextState(null,state.toString(),negativeEvent.toString()); + + } + catch (NoTransitionDefinedException e){ + flag =true; + } + Assert.assertEquals(flag,true); + + flag =false; + try{ + String response = lifecycleManager.getNextState(null,state.toString(),"PUT"); + } + catch(LifecycleException e){ + flag = true; + } + Assert.assertTrue(flag); + + } + } + } + } + + private List<Event> getNegativeEvents(State state,Set<Event> events) { + List<Event> negativeEventList = new ArrayList<>(); + negativeEventList.addAll(events); + + for(Transition transition: state.getTransitions()){ + negativeEventList.remove(transition.getEvent()); + } + return negativeEventList; + } + + @Test + public void testLockStates() throws LifecycleException, NoTransitionDefinedException { + MetadataReader metadataReader = new MetadataReader(); + StateMachineMetadata metadata = metadataReader.readMetadata(null); + LifecycleManager lifecycleManager = new LifecycleManagerImpl(); + for(State state: metadata.getStates()) { + if(isValidState(state, VALID_LOCK_STATES)) { + assertSameNextState(lifecycleManager, state, VNFOperation.Lock); + assertSameNextState(lifecycleManager, state, VNFOperation.Unlock); + assertSameNextState(lifecycleManager, state, VNFOperation.CheckLock); + } else { + assertNoNextState(lifecycleManager, state, VNFOperation.Lock); + assertNoNextState(lifecycleManager, state, VNFOperation.Unlock); + assertNoNextState(lifecycleManager, state, VNFOperation.CheckLock); + } + } + } + + private boolean isValidState(State state, State[] validStates) { + for(State validState: validStates) { + if(validState.equals(state)) { + return true; + } + } + return false; + } + + private void assertSameNextState(LifecycleManager lifecycleManager, State state, VNFOperation operation) throws LifecycleException, NoTransitionDefinedException { + Assert.assertEquals(state.getStateName(), lifecycleManager.getNextState("no-matter", state.getStateName(), operation.toString())); + } + + private void assertNoNextState(LifecycleManager lifecycleManager, State state, VNFOperation operation) throws LifecycleException { + try { + lifecycleManager.getNextState("no-matter", state.getStateName(), operation.toString()); + Assert.fail("lifecycleManager.getNextState() should fail for state [" + state + "], operation [" + operation + "]"); + } catch(NoTransitionDefinedException e) { + // this exception is excepted + } + } +} diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/.gitignore b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/pom.xml b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/pom.xml new file mode 100644 index 000000000..00886e75f --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/pom.xml @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-lifecycle-management</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <name>appc-lifecycle-management-features</name> + <artifactId>appc-lifecycle-management-features</artifactId> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-lifecycle-management-api</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-lifecycle-management-core</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <!--<plugin> + <!– launches the feature test, which validates that your karaf feature + can be installed inside of a karaf container. It doesn't validate that your + functionality works correctly, just that you have all of the dependent bundles + defined correctly. –> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.16</version> + <configuration> + <systemPropertyVariables> + <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId> + <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId> + <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version> + </systemPropertyVariables> + <dependenciesToScan> + <dependency>org.opendaylight.yangtools:features-test</dependency> + </dependenciesToScan> + <classpathDependencyExcludes> + <!– The dependencies which bring in AbstractDataBrokerTest class + brings in a second PaxExam container which results in the feature tests failing + with a message similar to: "ERROR o.ops4j.pax.exam.spi.PaxExamRuntime - Ambiguous + TestContainer ..." This excludes the container we don't want to use. –> + <classpathDependencyExcludes>org.ops4j.pax.exam:pax-exam-container-native</classpathDependencyExcludes> + </classpathDependencyExcludes> + </configuration> + </plugin>--> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + + <!-- Skipping ODL feature test --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <skipTests>true</skipTests> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/src/main/resources/features.xml b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/src/main/resources/features.xml new file mode 100644 index 000000000..b74afa93f --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/src/main/resources/features.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="appc-lifecycle-management-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + + <feature name='appc-lifecycle-management' description="application executor" version='${project.version}'> + <bundle dependency="true">mvn:org.openecomp.appc/domain-model-lib/${project.version}</bundle> + <bundle>mvn:org.openecomp.appc/state-machine-lib/${project.version}</bundle> + <bundle>mvn:org.openecomp.appc/appc-lifecycle-management-api/${project.version}</bundle> + <bundle>mvn:org.openecomp.appc/appc-lifecycle-management-core/${project.version}</bundle> + </feature> + +</features> diff --git a/app-c/appc/appc-dispatcher/appc-lifecycle-management/pom.xml b/app-c/appc/appc-dispatcher/appc-lifecycle-management/pom.xml new file mode 100644 index 000000000..7d75c0fd4 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-lifecycle-management/pom.xml @@ -0,0 +1,22 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-lifecycle-management</artifactId> + <packaging>pom</packaging> + <name>APPC Lifecycle Management</name> + <description>APPC Lifecycle Management</description> + + <!-- ================================================================================== --> + <!-- The modules we build --> + <!-- ================================================================================== --> + <modules> + <module>appc-lifecycle-management-api</module> + <module>appc-lifecycle-management-core</module> + <module>appc-lifecycle-management-features</module> + </modules> + +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/.gitignore b/app-c/appc/appc-dispatcher/appc-request-handler/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-request-handler/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/.gitignore b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/pom.xml b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/pom.xml new file mode 100644 index 000000000..b24c10797 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/pom.xml @@ -0,0 +1,59 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-request-handler</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-request-handler-api</artifactId> + <packaging>bundle</packaging> + + <name>appc-request-handler-api</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-annotations</artifactId> +<!-- <version>${jackson.version}</version> --> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-data-access-lib</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-command-executor-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Export-Package>org.openecomp.appc.requesthandler,org.openecomp.appc.requesthandler.objects,org.openecomp.appc.transactionrecorder,org.openecomp.appc.message</Export-Package> + <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic,appc-data-access-lib,javax.json;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Import-Package>com.fasterxml.jackson.annotation,org.apache.commons.lang3,!groovy.lang,!javax.*,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/message/RequestHandlerMessages.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/message/RequestHandlerMessages.java new file mode 100644 index 000000000..c397f09cd --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/message/RequestHandlerMessages.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.message; + + +public class RequestHandlerMessages { + public final static String VNF_WORKING_STATE_UPDATED = "VNF WorkingState for vnfId ${vnfId} was updated to ${workingState} at attempt ${attempt} out of ${maxAttempts} with ownerId = ${ownerId} and forceFlag = ${forceFlag}"; + public final static String VNF_WORKING_STATE_WAS_NOT_UPDATED = "VNF WorkingState for vnfId ${vnfId} was not updated to ${workingState} attempt ${attempt} out of ${maxAttempts} with ownerId = ${ownerId} and forceFlag = ${forceFlag}"; +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/RequestHandler.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/RequestHandler.java new file mode 100644 index 000000000..d0d54c9db --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/RequestHandler.java @@ -0,0 +1,77 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.requesthandler; + +import org.openecomp.appc.domainmodel.lcm.RuntimeContext; +import org.openecomp.appc.executor.UnstableVNFException; +import org.openecomp.appc.requesthandler.objects.RequestHandlerInput; +import org.openecomp.appc.requesthandler.objects.RequestHandlerOutput; + +/** + * This class provides application logic for the Request/Response Handler Component. + * + */ +public interface RequestHandler { + /** + * It receives requests from the north-bound REST API (Communication) Layer and + * performs following validations. + * 1. VNF exists in A&AI for the given targetID (VnfID) + * 2. For the current VNF Orchestration Status, the command can be executed + * 3. For the given VNF type and Operation, there exists work-flow definition in the APPC database + * If any of the validation fails, it returns appropriate response + * + * @param input RequestHandlerInput object which contains request header and other request parameters like command , target Id , payload etc. + * @return response for request as enum with Return code and message. + */ + RequestHandlerOutput handleRequest(RequestHandlerInput input); + + /** + * This method perform operations required before execution of workflow starts. It retrieves next state for current operation from Lifecycle manager and update it in AAI. + * @param vnf_id vnf id or target Id on which updates required + * @param requestIdentifierString - string contains id uniquely represents the request + * @param forceFlag + * @return true in case AAI updates are successful. false for any error or exception. + */ + void onRequestExecutionStart(String vnf_id, boolean readOnlyActivity, String requestIdentifierString, boolean forceFlag) throws UnstableVNFException; + + /** + * This method perform following operations required after execution of workflow. + * It posts asynchronous response to message bus (DMaaP). + * Unlock VNF Id + * Removes request from request registry. + * Generate audit logs. + * Adds transaction record to database id if transaction logging is enabled. + * @param runtimeContext RuntimeContext object which contains all parameters from request, response and few parameters from AA&I + * @param isAAIUpdated boolean flag which indicate AAI upodate status after request completion. + */ + void onRequestExecutionEnd(RuntimeContext runtimeContext, boolean isAAIUpdated); + + /** + * This method perform following operations required if TTL ends when request still waiting in execution queue . + * It posts asynchronous response to message bus (DMaaP). + * Unlock VNF Id + * Removes request from request registry. + * @param runtimeContext RuntimeContext object which contains all parameters from request, response and few parameters from AA&I; + * @param updateAAI boolean flag which indicate AAI upodate status after request completion. + */ + void onRequestTTLEnd(RuntimeContext runtimeContext, boolean updateAAI); +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerInput.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerInput.java new file mode 100644 index 000000000..70d9b84e8 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerInput.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.requesthandler.objects; + +import org.openecomp.appc.domainmodel.lcm.RequestContext; + +public class RequestHandlerInput { + + + private RequestContext requestContext; + private String rpcName; + + public String getRpcName() { + return rpcName; + } + + public void setRpcName(String rpcName) { + this.rpcName = rpcName; + } + + public RequestContext getRequestContext() { + return requestContext; + } + + public RequestHandlerInput(){ + } + + + public void setRequestContext(RequestContext requestContext) { + this.requestContext = requestContext; + } + + @Override + public String toString() { + return "RequestHandlerInput{" + + "requestContext=" + requestContext + + '}'; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerOutput.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerOutput.java new file mode 100644 index 000000000..051c02708 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerOutput.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.requesthandler.objects; + +import org.openecomp.appc.domainmodel.lcm.ResponseContext; + +public class RequestHandlerOutput { + + private ResponseContext responseContext; + + public RequestHandlerOutput(){ + + } + + public ResponseContext getResponseContext() { + return responseContext; + } + + public void setResponseContext(ResponseContext responseContext) { + this.responseContext = responseContext; + } + + @Override + public String toString() { + return "RequestHandlerOutput{" + + "responseContext=" + responseContext + + '}'; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/.gitignore b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/pom.xml b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/pom.xml new file mode 100644 index 000000000..d2f469bbc --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/pom.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + + <!-- 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. --> + + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-request-handler</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-request-handler-core</artifactId> + <packaging>bundle</packaging> + + <name>appc-request-handler-core Bundle</name> + <description>appc-request-handler-core OSGi bundle project.</description> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-metric-bundle</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dmaap-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-command-executor-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-workflow-management-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-request-handler-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>execution-queue-management-lib</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-lifecycle-management-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-data-access-lib</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>lock-manager-api</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.adaptors</groupId> + <artifactId>aai-service-provider</artifactId> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>domain-model-lib</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-provider-model</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>transaction-recorder</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Embed-Dependency>appc-provider-model,appc-dmaap-adapter-bundle,appc-metric-bundle,appc-common,eelf-core,logback-core,logback-classic,appc-data-access-lib;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Export-Service>org.openecomp.appc.requesthandler.RequestHandler</Export-Service> + <Import-Package>org.openecomp.appc.lockmanager.api.*,org.openecomp.appc.requesthandler,org.openecomp.appc.requesthandler.objects,org.openecomp.appc.transactionrecorder,org.openecomp.appc.transactionrecorder.objects,!groovy.lang,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.apache.commons.lang3,!org.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/common/constant/Constants.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/common/constant/Constants.java new file mode 100644 index 000000000..e516f4991 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/common/constant/Constants.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.common.constant; + +import java.util.concurrent.TimeUnit; + +public class Constants { + + public static final int DEFAULT_TTL = 30; + public static final String SUCCESS_MSG="SUCCESS"; + public static final String FAILURE_MSG="FAILURE"; + public static final String DEFAULT_LOGGING_FLAG="true"; + public static final long DEFAULT_IDLE_TIMEOUT = TimeUnit.MILLISECONDS.convert(15, TimeUnit.MINUTES); +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/MessageAdapter.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/MessageAdapter.java new file mode 100644 index 000000000..e24237fcb --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/MessageAdapter.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.messageadapter; + +import org.openecomp.appc.domainmodel.lcm.ResponseContext; +import org.openecomp.appc.domainmodel.lcm.VNFOperation; + +public interface MessageAdapter { + /** + * Initialize dmaapProducer client to post messages using configuration properties + */ + void init(); + + /** + * Posts message to DMaaP. As DMaaP accepts only json messages this method first convert dmaapMessage to json format and post it to DMaaP. + * @param asyncResponse response data that based on it a message will be send to DMaaP (the format of the message that will be sent to DMaaP based on the action and its YANG domainmodel). + * @return True if message is postes successfully else False + */ + boolean post(VNFOperation operation, String rpcName, ResponseContext asyncResponse); + +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/impl/MessageAdapterDmaapImpl.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/impl/MessageAdapterDmaapImpl.java new file mode 100644 index 000000000..9f74ad438 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/impl/MessageAdapterDmaapImpl.java @@ -0,0 +1,127 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.messageadapter.impl; + +import java.util.HashSet; +import java.util.Properties; + +import org.apache.commons.lang.ObjectUtils; +import org.openecomp.appc.adapter.dmaap.Producer; +import org.openecomp.appc.adapter.dmaap.DmaapProducer; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.domainmodel.lcm.ResponseContext; +import org.openecomp.appc.domainmodel.lcm.VNFOperation; +import org.openecomp.appc.messageadapter.MessageAdapter; +import org.openecomp.appc.requesthandler.conv.Converter; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import com.fasterxml.jackson.core.JsonProcessingException; + +public class MessageAdapterDmaapImpl implements MessageAdapter{ + + private Producer dmaapProducer; + private String partition ; + private Configuration configuration; + private HashSet<String> pool; + private String writeTopic; + private String apiKey; + private String apiSecret; + + private Integer READ_TIMEOUT; + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(MessageAdapterDmaapImpl.class); + + /** + * Initialize dmaapProducer client to post messages using configuration properties + */ + @Override + public void init(){ + this.dmaapProducer = getDmaapProducer(); + } + private Producer getDmaapProducer() { + configuration = ConfigurationFactory.getConfiguration(); + Properties properties=configuration.getProperties(); + updateProperties(properties); + Producer producer=new DmaapProducer(pool,writeTopic); + producer.updateCredentials(apiKey, apiSecret); + return producer; + } + + + private void updateProperties(Properties props) { + if (logger.isTraceEnabled()) { + logger.trace("Entering to updateProperties with Properties = "+ ObjectUtils.toString(props)); + } + pool = new HashSet<>(); + if (props != null) { + // readTopic = props.getProperty("dmaap.topic.read"); + writeTopic = props.getProperty("dmaap.topic.write"); + apiKey = props.getProperty("dmaap.client.key"); + apiSecret = props.getProperty("dmaap.client.secret"); + /* clientName = props.getProperty("dmaap.client.name", "APP-C"); + clientId = props.getProperty("dmaap.client.name.id", "0"); + filter_json = props.getProperty("dmaap.topic.read.filter"); + */ + // READ_TIMEOUT = Integer.valueOf(props.getProperty("dmaap.topic.read.timeout", String.valueOf(READ_TIMEOUT))); + String hostnames = props.getProperty("dmaap.poolMembers"); + if (hostnames != null && !hostnames.isEmpty()) { + for (String name : hostnames.split(",")) { + pool.add(name); + } + } + } + } + + /** + * Posts message to DMaaP. As DMaaP accepts only json messages this method first convert dmaapMessage to json format and post it to DMaaP. + * @param asyncResponse response data that based on it a message will be send to DMaaP (the format of the message that will be sent to DMaaP based on the action and its YANG domainmodel). + * @return True if message is postes successfully else False + */ + @Override + public boolean post(VNFOperation operation, String rpcName, ResponseContext asyncResponse){ + boolean success; + if (logger.isTraceEnabled()) { + logger.trace("Entering to post with AsyncResponse = " + ObjectUtils.toString(asyncResponse)); + } + + String jsonMessage; + try { + jsonMessage = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(operation, rpcName, asyncResponse); + if (logger.isDebugEnabled()) { + logger.debug("DMaaP Response = " + jsonMessage); + } + success = dmaapProducer.post(this.partition, jsonMessage); + } catch (JsonProcessingException e1) { + logger.error("Error generating Jason from DMaaP message "+ e1.getMessage()); + success= false; + }catch (Exception e){ + logger.error("Error sending message to DMaaP "+e.getMessage()); + success= false; + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting from post with (success = "+ ObjectUtils.toString(success)+")"); + } + return success; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/conv/Converter.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/conv/Converter.java new file mode 100644 index 000000000..50c18d661 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/conv/Converter.java @@ -0,0 +1,341 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.requesthandler.conv; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.Action; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.AuditOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.HealthCheckOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.LiveUpgradeOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.LockOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.ModifyConfigOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.Payload; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RollbackOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SnapshotOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SoftwareUploadOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.StopOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SyncOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.TerminateOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.TestOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.UnlockOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.ZULU; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.CommonHeader; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.CommonHeaderBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.FlagsBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.status.Status; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.status.StatusBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataContainer; +import org.openecomp.appc.domainmodel.lcm.ResponseContext; +import org.openecomp.appc.domainmodel.lcm.VNFOperation; +import org.openecomp.appc.requesthandler.impl.DmaapOutgoingMessage; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.fasterxml.jackson.databind.SerializationFeature; + + +public class Converter { + public static final String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; + public static final String MODE_FLAG = "MODE"; + public static final String FORCE_FLAG = "FORCE"; + public static final String TTL_FLAG = "TTL"; + public final static String DMaaP_ROOT_VALUE = "output"; + private static final SimpleDateFormat isoFormatter = new SimpleDateFormat(ISO_FORMAT); + private static final EELFLogger logger = EELFManager.getInstance().getLogger(Converter.class); + static { + isoFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); + } + + public static Builder<?> convAsyncResponseToBuilder(VNFOperation vnfOperation, String rpcName, ResponseContext response) { + Builder<?> outObj = null; + if(response == null){ + throw new IllegalArgumentException("empty asyncResponse"); + } + if(vnfOperation == null){ + throw new IllegalArgumentException("empty asyncResponse.action"); + } + Action action = Action.valueOf(vnfOperation.name()); + CommonHeader commonHeader = convAsyncResponseTorev160108CommonHeader(response); + Status status = convAsyncResponseTorev160108Status(response); +// Payload payload = convAsyncResponseTorev160108Payload(inObj); + switch (action){ + case Rollback: + outObj = new RollbackOutputBuilder(); + ((RollbackOutputBuilder)outObj).setCommonHeader(commonHeader); + ((RollbackOutputBuilder)outObj).setStatus(status); + return outObj; + case Snapshot: + outObj = new SnapshotOutputBuilder(); + ((SnapshotOutputBuilder)outObj).setCommonHeader(commonHeader); + ((SnapshotOutputBuilder)outObj).setStatus(status); + try { + ((SnapshotOutputBuilder) outObj).setSnapshotId(response.getAdditionalContext().get("output.snapshot-id")); + } catch (NullPointerException ignored) { + // in case of negative response, snapshotID does not populated, so just ignore NPL + } + return outObj; + case Audit: + outObj = new AuditOutputBuilder(); + ((AuditOutputBuilder)outObj).setCommonHeader(commonHeader); + ((AuditOutputBuilder)outObj).setStatus(status); + return outObj; + case HealthCheck: + outObj = new HealthCheckOutputBuilder(); + ((HealthCheckOutputBuilder)outObj).setCommonHeader(commonHeader); + ((HealthCheckOutputBuilder)outObj).setStatus(status); + return outObj; + case LiveUpgrade: + outObj = new LiveUpgradeOutputBuilder(); + ((LiveUpgradeOutputBuilder)outObj).setCommonHeader(commonHeader); + ((LiveUpgradeOutputBuilder)outObj).setStatus(status); + return outObj; + case Lock: + outObj = new LockOutputBuilder(); + ((LockOutputBuilder)outObj).setCommonHeader(commonHeader); + ((LockOutputBuilder)outObj).setStatus(status); + return outObj; + case ModifyConfig: + outObj = new ModifyConfigOutputBuilder(); + ((ModifyConfigOutputBuilder)outObj).setCommonHeader(commonHeader); + ((ModifyConfigOutputBuilder)outObj).setStatus(status); + return outObj; + case SoftwareUpload: + outObj = new SoftwareUploadOutputBuilder(); + ((SoftwareUploadOutputBuilder)outObj).setCommonHeader(commonHeader); + ((SoftwareUploadOutputBuilder)outObj).setStatus(status); + return outObj; + case Stop: + outObj = new StopOutputBuilder(); + ((StopOutputBuilder)outObj).setCommonHeader(commonHeader); + ((StopOutputBuilder)outObj).setStatus(status); + return outObj; + case Sync: + outObj = new SyncOutputBuilder(); + ((SyncOutputBuilder)outObj).setCommonHeader(commonHeader); + ((SyncOutputBuilder)outObj).setStatus(status); + return outObj; + case Terminate: + outObj = new TerminateOutputBuilder(); + ((TerminateOutputBuilder)outObj).setCommonHeader(commonHeader); + ((TerminateOutputBuilder)outObj).setStatus(status); + return outObj; + case Test: + outObj = new TestOutputBuilder(); + ((TestOutputBuilder)outObj).setCommonHeader(commonHeader); + ((TestOutputBuilder)outObj).setStatus(status); + return outObj; + case Unlock: + outObj = new UnlockOutputBuilder(); + ((UnlockOutputBuilder)outObj).setCommonHeader(commonHeader); + ((UnlockOutputBuilder)outObj).setStatus(status); + return outObj; + default: + throw new IllegalArgumentException(action+" action is not supported"); + } + } + + public static Payload convAsyncResponseTorev160108Payload(ResponseContext inObj) throws ParseException { + Payload payload = null; + if(inObj.getPayload() != null) { + payload = new Payload(inObj.getPayload()); + } + return payload; + } + + public static String convPayloadObjectToJsonString(Object inObj) throws ParseException { + String payloadAsString = null; + if(inObj != null) { + + if(inObj instanceof String){ + payloadAsString = (String)inObj; + }else { + try { + ObjectMapper objectMapper = new ObjectMapper(); + payloadAsString = objectMapper.writeValueAsString(inObj); +// payloadAsString = objectMapper.writeValueAsString(payloadAsString); + } catch (JsonProcessingException e) { + String errMsg = "Error serialize payload json to string"; + throw new ParseException(errMsg + "-" + e.toString(), 0); + } + } + } + return payloadAsString; + } + + public static Status convAsyncResponseTorev160108Status(ResponseContext inObj) { + StatusBuilder statusBuilder = new StatusBuilder(); + statusBuilder.setCode(inObj.getStatus().getCode()); + statusBuilder.setMessage(inObj.getStatus().getMessage()); + return statusBuilder.build(); + } + + public static CommonHeader convAsyncResponseTorev160108CommonHeader(ResponseContext inObj) { + CommonHeader outObj = null; + if(inObj == null){ + throw new IllegalArgumentException("empty asyncResponse"); + } + + CommonHeaderBuilder commonHeaderBuilder = new CommonHeaderBuilder(); + org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags commonHeaderFlags = null; + if(inObj.getCommonHeader().getFlags() != null){ + commonHeaderFlags = Converter.convFlagsMapTorev160108Flags(inObj.getCommonHeader().getFlags()); + commonHeaderBuilder.setFlags(commonHeaderFlags); + } + + + commonHeaderBuilder.setApiVer(inObj.getCommonHeader().getApiVer()); + commonHeaderBuilder.setRequestId(inObj.getCommonHeader().getRequestId()); + if(inObj.getCommonHeader().getSubRequestId() != null){ + commonHeaderBuilder.setSubRequestId(inObj.getCommonHeader().getSubRequestId()); + } + + if(inObj.getCommonHeader().getOriginatorId() != null){ + commonHeaderBuilder.setOriginatorId(inObj.getCommonHeader().getOriginatorId()); + } + + if(inObj.getCommonHeader().getTimeStamp() != null){ + String zuluTimestampStr = Converter.convDateToZuluString(inObj.getCommonHeader().getTimeStamp()); + ZULU zuluTimestamp = new ZULU(zuluTimestampStr); + commonHeaderBuilder.setTimestamp(zuluTimestamp); + } + outObj = commonHeaderBuilder.build(); + return outObj; + + } + + public static String convDateToZuluString(Date timeStamp) { + return isoFormatter.format(timeStamp); + } + + public static org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags + convFlagsMapTorev160108Flags(org.openecomp.appc.domainmodel.lcm.Flags flags) { + Flags rev160108flags = null; + boolean anyFlag = false; + FlagsBuilder flagsBuilder = new FlagsBuilder(); + /* + * TODO: The below flags are related to APP-C request and should not be sent back - uncomment when response flags are introduced. + */ + /* + if(flags.containsKey(FORCE_FLAG)){ + org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags.Force force = + org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags.Force.valueOf(flags.get(FORCE_FLAG).toString()); + flagsBuilder.setForce(force); + anyFlag = true; + } + if(flags.containsKey(MODE_FLAG)){ + org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags.Mode mode = + org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags.Mode.valueOf(flags.get(MODE_FLAG).toString()); + flagsBuilder.setMode(mode); + anyFlag = true; + } + if(flags.containsKey(TTL_FLAG)){ + flagsBuilder.setTtl(Integer.valueOf(flags.get(TTL_FLAG).toString())); + anyFlag = true; + } + if(anyFlag){ + rev160108flags = flagsBuilder.build(); + } + */ + + rev160108flags = flagsBuilder.build(); + return rev160108flags; + } + + public static String convAsyncResponseToJsonStringBody(VNFOperation vnfOperation, String rpcName, ResponseContext asyncResponse) throws JsonProcessingException { + Builder<?> builder = Converter.convAsyncResponseToBuilder(vnfOperation, rpcName, asyncResponse); + Object message = builder.build(); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.addMixInAnnotations(message.getClass(), MixInFlagsMessage.class); + objectMapper.addMixInAnnotations(CommonHeader.class, MixInCommonHeader.class); + objectMapper.addMixInAnnotations(Flags.class, MixIn.class); + objectMapper.addMixInAnnotations(Status.class, MixIn.class); + objectMapper.addMixInAnnotations(Payload.class, MixIn.class); + objectMapper.addMixInAnnotations(ZULU.class, MixIn.class); + +// .configure(SerializationConfig.Feature.SORT_PROPERTIES_ALPHABETICALLY,true) + ObjectWriter writer = objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL).configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY,true) + .writer(SerializationFeature.WRAP_ROOT_VALUE).withRootName(DMaaP_ROOT_VALUE).withoutFeatures(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS); + return writer.writeValueAsString(message); + } + + public static String convAsyncResponseToDmaapOutgoingMessageJsonString(VNFOperation vnfOperation, String rpcName, ResponseContext asyncResponse) throws JsonProcessingException { + DmaapOutgoingMessage dmaapOutgoingMessage = convAsyncResponseToDmaapOutgoingMessage(vnfOperation, rpcName, asyncResponse); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.addMixInAnnotations(dmaapOutgoingMessage.getBody().getOutput().getClass(), MixInFlagsMessage.class); + objectMapper.addMixInAnnotations(CommonHeader.class, MixInCommonHeader.class); + objectMapper.addMixInAnnotations(Flags.class, MixIn.class); + objectMapper.addMixInAnnotations(Status.class, MixIn.class); + objectMapper.addMixInAnnotations(Payload.class, MixIn.class); + objectMapper.addMixInAnnotations(ZULU.class, MixIn.class); + +// .configure(SerializationConfig.Feature.SORT_PROPERTIES_ALPHABETICALLY,true) + ObjectWriter writer = objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL).configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY,true).writer(); + return writer.writeValueAsString(dmaapOutgoingMessage); + } + + public static DmaapOutgoingMessage convAsyncResponseToDmaapOutgoingMessage(VNFOperation vnfOperation, String rpcName, ResponseContext asyncResponse) throws JsonProcessingException { + DmaapOutgoingMessage outObj = new DmaapOutgoingMessage(); + outObj.setRpcName(rpcName); + Builder<?> builder = Converter.convAsyncResponseToBuilder(vnfOperation, rpcName, asyncResponse); + Object messageBody = builder.build(); + DmaapOutgoingMessage.Body body = new DmaapOutgoingMessage.Body(messageBody); + outObj.setBody(body); + return outObj; + } + + abstract class MixIn { + @JsonIgnore + abstract Class<? extends DataContainer> getImplementedInterface(); // to be removed during serialization + + @JsonValue + abstract java.lang.String getValue(); + } + abstract class MixInCommonHeader extends MixIn { + @JsonProperty("api-ver") + abstract java.lang.String getApiVer(); + @JsonProperty("originator-id") + abstract java.lang.String getOriginatorId(); + @JsonProperty("request-id") + abstract java.lang.String getRequestId(); + @JsonProperty("sub-request-id") + abstract java.lang.String getSubRequestId(); + + } + abstract class MixInFlagsMessage extends MixIn { + @JsonProperty("common-header") + abstract CommonHeader getCommonHeader(); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DGWorkflowNotFoundException.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DGWorkflowNotFoundException.java new file mode 100644 index 000000000..c41f42ed6 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DGWorkflowNotFoundException.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.requesthandler.exceptions; + + +public class DGWorkflowNotFoundException extends Exception { + public final String workflowModule; + public final String workflowName; + public final String workflowVersion; + public DGWorkflowNotFoundException(String message,String workflowModule,String workflowName,String workflowVersion){ + super(message); + this.workflowModule = workflowModule; + this.workflowName = workflowName; + this.workflowVersion = workflowVersion; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DuplicateRequestException.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DuplicateRequestException.java new file mode 100644 index 000000000..a9c1c0000 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DuplicateRequestException.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.requesthandler.exceptions; + + +public class DuplicateRequestException extends Exception { + public DuplicateRequestException(String message){ + super(message); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/InvalidInputException.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/InvalidInputException.java new file mode 100644 index 000000000..a70b6f14a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/InvalidInputException.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.requesthandler.exceptions; + + +public class InvalidInputException extends Exception { + public InvalidInputException(String message){ + super(message); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/RequestExpiredException.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/RequestExpiredException.java new file mode 100644 index 000000000..44b0869a9 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/RequestExpiredException.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.requesthandler.exceptions; + + +public class RequestExpiredException extends Exception { + public RequestExpiredException(String message){ + super(message); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/VNFNotFoundException.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/VNFNotFoundException.java new file mode 100644 index 000000000..16a9e5e6e --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/VNFNotFoundException.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.requesthandler.exceptions; + + +public class VNFNotFoundException extends Exception { + public VNFNotFoundException(String message){ + super(message); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/WorkflowNotFoundException.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/WorkflowNotFoundException.java new file mode 100644 index 000000000..97dabe869 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/WorkflowNotFoundException.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.requesthandler.exceptions; + + +public class WorkflowNotFoundException extends Exception { + public final String vnfTypeVersion; + public final String command; + public WorkflowNotFoundException(String message,String vnfTypeVersion,String command){ + super(message); + this.vnfTypeVersion = vnfTypeVersion; + this.command = command; + } + +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestRegistry.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestRegistry.java new file mode 100644 index 000000000..874626c78 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestRegistry.java @@ -0,0 +1,79 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.requesthandler.helper; + +import org.apache.commons.lang.ObjectUtils; +import org.openecomp.appc.executor.objects.UniqueRequestIdentifier; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import java.util.Collections; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * + * This class serves as Request Registry, which holds the + * request unique parameters (originatorId,requestId,subRequestId) + * in memory. + */ +public class RequestRegistry { + + static Set<UniqueRequestIdentifier> set = Collections.newSetFromMap(new ConcurrentHashMap<UniqueRequestIdentifier, Boolean>()); + private static final EELFLogger logger = EELFManager.getInstance().getLogger(RequestRegistry.class); + public RequestRegistry(){ + + } + + /** + * This method accepts unique request parameters and adds it to Request Registry + * if Registry already contains same parameters it returns false, + * else returns true. + * @param requestIdentifier + * @return + */ + public boolean registerRequest(UniqueRequestIdentifier requestIdentifier){ + + if (logger.isTraceEnabled()) { + logger.trace("Entering to registerRequest with UniqueRequestIdentifier = "+ ObjectUtils.toString(requestIdentifier)); + } + boolean output = set.add(requestIdentifier); + logger.debug(" Output = " + output); + if (logger.isTraceEnabled()) { + logger.trace("Exiting from registerRequest with (output = "+ ObjectUtils.toString(output)+")"); + } + return output; + } + + /** + * This method accepts unique request parameters and removes request + * from the Request Registry + * @param requestIdentifier + */ + public void removeRequest(UniqueRequestIdentifier requestIdentifier){ + if (logger.isTraceEnabled()) { + logger.trace("Entering to removeRequest with UniqueRequestIdentifier = "+ ObjectUtils.toString(requestIdentifier)); + } + set.remove(requestIdentifier); + } + +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestValidator.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestValidator.java new file mode 100644 index 000000000..4f2986d74 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestValidator.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.requesthandler.helper; + +import org.openecomp.appc.domainmodel.lcm.RuntimeContext; +import org.openecomp.appc.executor.UnstableVNFException; +import org.openecomp.appc.lifecyclemanager.objects.LifecycleException; +import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException; +import org.openecomp.appc.requesthandler.exceptions.DGWorkflowNotFoundException; +import org.openecomp.appc.requesthandler.exceptions.DuplicateRequestException; +import org.openecomp.appc.requesthandler.exceptions.InvalidInputException; +import org.openecomp.appc.requesthandler.exceptions.RequestExpiredException; +import org.openecomp.appc.requesthandler.exceptions.VNFNotFoundException; +import org.openecomp.appc.requesthandler.exceptions.WorkflowNotFoundException; + +public interface RequestValidator { + public void validateRequest(RuntimeContext runtimeContext) throws VNFNotFoundException, RequestExpiredException, UnstableVNFException, InvalidInputException, DuplicateRequestException, NoTransitionDefinedException, LifecycleException, WorkflowNotFoundException,DGWorkflowNotFoundException; +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/DmaapOutgoingMessage.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/DmaapOutgoingMessage.java new file mode 100644 index 000000000..4546726e9 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/DmaapOutgoingMessage.java @@ -0,0 +1,114 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.requesthandler.impl; + + + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +/** + * This class represents a message being sent out to DMaaP by APPC as async response. + * note the structure of this class must be adapted to the sync message sent to DMaaP represened in org.openecomp.appc.listener.LCM.domainmodel.DmaapOutgoingMessage + * + */ +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class DmaapOutgoingMessage { + + private final static String defaultCambriaPartition = "MSO"; + @JsonProperty("cambria.partition") + private String cambriaPartition = defaultCambriaPartition; + + @JsonProperty("rpc-name") + private String rpcName; + + @JsonProperty("body") + private Body body; + + public DmaapOutgoingMessage() { + } + + public String getCambriaPartition() { + return cambriaPartition; + } + + public void setCambriaPartition(String cambriaPartition) { + this.cambriaPartition = cambriaPartition; + } + + public String getRpcName() { + return rpcName; + } + + public void setRpcName(String rpcName) { + this.rpcName = rpcName; + } + + public Body getBody() { + return body; + } + + public void setBody(Body body) { + this.body = body; + } + + @Override + public String toString() { + return "DmaapOutgoingMessage{" + + "cambriaPartition='" + cambriaPartition + '\'' + + ", rpcName='" + rpcName + '\'' + + ", body=" + body + + '}'; + } + + @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Body { + public Body() { + } + + public Body(Object output) { + this.output = output; + } + + @JsonProperty("output") + private Object output; + + public Object getOutput() { + return output; + } + + public void setOutput(Object body) { + this.output = body; + } + + @Override + public String toString() { + return "Body{" + + "output=" + output + + '}'; + } + } +} + diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestHandlerImpl.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestHandlerImpl.java new file mode 100644 index 000000000..d1303605d --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestHandlerImpl.java @@ -0,0 +1,839 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.requesthandler.impl; + +import org.apache.commons.lang.ObjectUtils; +import org.openecomp.appc.common.constant.Constants; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.domainmodel.lcm.*; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.executor.CommandExecutor; +import org.openecomp.appc.executor.UnstableVNFException; +import org.openecomp.appc.executor.objects.CommandExecutorInput; +import org.openecomp.appc.executor.objects.LCMCommandStatus; +import org.openecomp.appc.executor.objects.Params; +import org.openecomp.appc.executor.objects.UniqueRequestIdentifier; +import org.openecomp.appc.i18n.Msg; +import org.openecomp.appc.lifecyclemanager.objects.LifecycleException; +import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException; +import org.openecomp.appc.lockmanager.api.LockException; +import org.openecomp.appc.lockmanager.api.LockManager; +import org.openecomp.appc.logging.LoggingConstants; +import org.openecomp.appc.logging.LoggingUtils; +import org.openecomp.appc.messageadapter.MessageAdapter; +import org.openecomp.appc.messageadapter.impl.MessageAdapterDmaapImpl; +import org.openecomp.appc.metricservice.MetricRegistry; +import org.openecomp.appc.metricservice.MetricService; +import org.openecomp.appc.metricservice.metric.DispatchingFuntionMetric; +import org.openecomp.appc.metricservice.metric.Metric; +import org.openecomp.appc.metricservice.metric.MetricType; +import org.openecomp.appc.metricservice.policy.PublishingPolicy; +import org.openecomp.appc.metricservice.publisher.LogPublisher; +import org.openecomp.appc.requesthandler.RequestHandler; +import org.openecomp.appc.requesthandler.exceptions.*; +import org.openecomp.appc.requesthandler.helper.RequestRegistry; +import org.openecomp.appc.requesthandler.helper.RequestValidator; +import org.openecomp.appc.requesthandler.objects.RequestHandlerInput; +import org.openecomp.appc.requesthandler.objects.RequestHandlerOutput; +import org.openecomp.appc.transactionrecorder.TransactionRecorder; +import org.openecomp.appc.transactionrecorder.objects.TransactionRecord; +import org.openecomp.appc.workingstatemanager.WorkingStateManager; +import org.openecomp.appc.workingstatemanager.objects.VNFWorkingState; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicException; +import org.openecomp.sdnc.sli.SvcLogicResource.QueryStatus; +import org.openecomp.sdnc.sli.aai.AAIService; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.slf4j.MDC; + +import static com.att.eelf.configuration.Configuration.*; + +import java.net.InetAddress; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * This class provides application logic for the Request/Response Handler Component. + * + */ +public class RequestHandlerImpl implements RequestHandler { + + /** + * APP-C VNF lock idle timeout in milliseconds. Applied only when locking VNF using northbound API "lock" + */ + private static final String PROP_IDLE_TIMEOUT = "org.openecomp.appc.lock.idleTimeout"; + + private CommandExecutor commandExecutor; + + private TransactionRecorder transactionRecorder; + private MessageAdapter messageAdapter; + private RequestValidator requestValidator; + private static MetricRegistry metricRegistry; + private boolean isMetricEnabled = false; + private RequestRegistry requestRegistry; + private LockManager lockManager; + private WorkingStateManager workingStateManager; + private AAIService aaiService; + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(RequestHandlerImpl.class); + + public void setAaiService(AAIService aaiService) { + this.aaiService = aaiService; + } + + public void setTransactionRecorder(TransactionRecorder transactionRecorder) { + this.transactionRecorder = transactionRecorder; + } + + public void setLockManager(LockManager lockManager) { + this.lockManager = lockManager; + } + + public void setRequestValidator(RequestValidator requestValidator) { + this.requestValidator = requestValidator; + } + + public void setMessageAdapter(MessageAdapter messageAdapter) { + this.messageAdapter = messageAdapter; + } + + private static final Configuration configuration = ConfigurationFactory.getConfiguration(); + + public void setWorkingStateManager(WorkingStateManager workingStateManager) { + this.workingStateManager = workingStateManager; + } + + public RequestHandlerImpl() { + requestRegistry = new RequestRegistry(); + messageAdapter = new MessageAdapterDmaapImpl(); + messageAdapter.init(); + Properties properties = configuration.getProperties(); + if (properties != null && properties.getProperty("metric.enabled") != null) { + isMetricEnabled = Boolean.valueOf(properties.getProperty("metric.enabled")); + } + if (isMetricEnabled) { + initMetric(); + } + } + + public void setCommandExecutor(CommandExecutor commandExecutor) { + this.commandExecutor = commandExecutor; + } + + + /** + * It receives requests from the north-bound REST API (Communication) Layer and + * performs following validations. + * 1. VNF exists in A&AI for the given targetID (VnfID) + * 2. For the current VNF Orchestration Status, the command can be executed + * 3. For the given VNF type and Operation, there exists work-flow definition in the APPC database + * If any of the validation fails, it returns appropriate response + * + * @param input RequestHandlerInput object which contains request header and other request parameters like command , target Id , payload etc. + * @return response for request as enum with Return code and message. + */ + @Override + public RequestHandlerOutput handleRequest(RequestHandlerInput input) { + if (logger.isTraceEnabled()) + logger.trace("Entering to handleRequest with RequestHandlerInput = " + ObjectUtils.toString(input) + ")"); + Params params = null; + String vnfId = null, vnfType = null, errorMessage = null; + Date startTime = new Date(System.currentTimeMillis()); + RequestHandlerOutput output = null; + setInitialLogProperties(input.getRequestContext()); + + RuntimeContext runtimeContext = new RuntimeContext(); + runtimeContext.setRequestContext(input.getRequestContext()); + runtimeContext.setTimeStart(startTime); + runtimeContext.setRpcName(input.getRpcName()); + + final ResponseContext responseContext = new ResponseContext(); + responseContext.setStatus(new Status()); + responseContext.setAdditionalContext(new HashMap<String, String>(4)); + responseContext.setCommonHeader(input.getRequestContext().getCommonHeader()); + runtimeContext.setResponseContext(responseContext); + runtimeContext.getResponseContext().setStatus(new Status()); + + vnfId = runtimeContext.getRequestContext().getActionIdentifiers().getVnfId(); + + try { + + requestValidator.validateRequest(runtimeContext); + + handleRequest(runtimeContext); + + final int statusCode = runtimeContext.getResponseContext().getStatus().getCode(); + if (statusCode % 100 == 2 || statusCode % 100 == 3) { + createTransactionRecord(runtimeContext); + } + output = new RequestHandlerOutput(); + output.setResponseContext(runtimeContext.getResponseContext()); + + } catch (VNFNotFoundException e) { + errorMessage = e.getMessage(); + String logMessage = EELFResourceManager.format(Msg.APPC_NO_RESOURCE_FOUND, vnfId); + storeErrorMessageToLog(runtimeContext, LoggingConstants.TargetNames.AAI, "", logMessage); + params = new Params().addParam("vnfId", vnfId); + output = buildRequestHandlerOutput(LCMCommandStatus.VNF_NOT_FOUND, params); + } catch (NoTransitionDefinedException e) { + errorMessage = e.getMessage(); + String logMessage = EELFResourceManager.format(Msg.VF_UNDEFINED_STATE, input.getRequestContext().getCommonHeader().getOriginatorId(), input.getRequestContext().getAction().name()); + params = new Params().addParam("actionName", input.getRequestContext().getAction()).addParam("currentState", e.currentState); + output = buildRequestHandlerOutput(LCMCommandStatus.NO_TRANSITION_DEFINE, params); + storeErrorMessageToLog(runtimeContext, + LoggingConstants.TargetNames.APPC, + LoggingConstants.TargetNames.STATE_MACHINE, + logMessage); + } catch (LifecycleException e) { + errorMessage = e.getMessage(); + params = new Params().addParam("actionName", input.getRequestContext().getAction()).addParam("currentState", e.currentState); + output = buildRequestHandlerOutput(LCMCommandStatus.ACTION_NOT_SUPPORTED, params); + } catch (UnstableVNFException e) { + errorMessage = e.getMessage(); + params = new Params().addParam("vnfId", vnfId); + output = buildRequestHandlerOutput(LCMCommandStatus.UNSTABLE_VNF, params); + } catch (WorkflowNotFoundException e) { + errorMessage = e.getMessage(); + String vnfTypeVersion = e.vnfTypeVersion; + params = new Params().addParam("actionName", input.getRequestContext().getAction()).addParam("vnfTypeVersion", vnfTypeVersion); + output = buildRequestHandlerOutput(LCMCommandStatus.WORKFLOW_NOT_FOUND, params); + } catch (DGWorkflowNotFoundException e) { + errorMessage = e.getMessage(); + String logMessage = EELFResourceManager.format(Msg.APPC_WORKFLOW_NOT_FOUND, vnfType, input.getRequestContext().getAction().name()); + storeErrorMessageToLog(runtimeContext, + LoggingConstants.TargetNames.APPC, + LoggingConstants.TargetNames.WORKFLOW_MANAGER, + logMessage); + params = new Params().addParam("actionName", input.getRequestContext().getAction().name()) + .addParam("dgModule", e.workflowModule).addParam("dgName", e.workflowName).addParam("dgVersion", e.workflowVersion); + output = buildRequestHandlerOutput(LCMCommandStatus.DG_WORKFLOW_NOT_FOUND, params); + } catch (RequestExpiredException e) { + errorMessage = e.getMessage(); + params = new Params().addParam("actionName", input.getRequestContext().getAction().name()); + output = buildRequestHandlerOutput(LCMCommandStatus.EXPIRED_REQUEST, params); + } catch (InvalidInputException e) { + errorMessage = e.getMessage() != null ? e.getMessage() : e.toString(); + params = new Params().addParam("errorMsg", errorMessage); + output = buildRequestHandlerOutput(LCMCommandStatus.INVALID_INPUT_PARAMETER, params); + } catch (DuplicateRequestException e) { + errorMessage = e.getMessage(); + output = buildRequestHandlerOutput(LCMCommandStatus.DUPLICATE_REQUEST, null); + } catch (Exception e) { + storeErrorMessageToLog(runtimeContext, "", "", "Exception = " + e.getMessage()); + errorMessage = e.getMessage() != null ? e.getMessage() : e.toString(); + params = new Params().addParam("errorMsg", errorMessage); + output = buildRequestHandlerOutput(LCMCommandStatus.UNEXPECTED_ERROR, params); + } finally { + try { + if (logger.isDebugEnabled() && errorMessage != null) + logger.debug("error occurred in handleRequest " + errorMessage); + logger.debug("output.getResponse().getResponseCode().equals(LCMCommandStatus.ACCEPTED.getResponseCode(): " + (output.getResponseContext().getStatus().getCode() == LCMCommandStatus.ACCEPTED.getResponseCode())); + logger.debug("output.getResponse().getResponseCode().equals(LCMCommandStatus.SUCCESS.getResponseCode(): " + (output.getResponseContext().getStatus().getCode() == LCMCommandStatus.SUCCESS.getResponseCode())); + + runtimeContext.setResponseContext(output.getResponseContext()); + if ((null == output) || !(output.getResponseContext().getStatus().getCode() == LCMCommandStatus.ACCEPTED.getResponseCode())) { + if (isMetricEnabled) { + ((DispatchingFuntionMetric) metricRegistry.metric("DISPATCH_FUNCTION")).incrementRejectedRequest(); + } + removeRequestFromRegistry(input.getRequestContext().getCommonHeader()); + } + } finally { + storeAuditLogRecord(runtimeContext); + storeMetricLogRecord(runtimeContext); + clearRequestLogProperties(); + } + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting from handleRequest with (RequestHandlerOutput = " + ObjectUtils.toString(output.getResponseContext()) + ")"); + } + return output; + } + + private void storeErrorMessageToLog(RuntimeContext runtimeContext, String targetEntity, String targetServiceName, String additionalMessage) { + LoggingUtils.logErrorMessage(runtimeContext.getResponseContext().getStatus() != null ? + String.valueOf(runtimeContext.getResponseContext().getStatus().getCode()) : "", + runtimeContext.getResponseContext().getStatus() != null ? + String.valueOf(runtimeContext.getResponseContext().getStatus().getMessage()) : "", + targetEntity, + targetServiceName, + additionalMessage, + this.getClass().getCanonicalName()); + } + + private void createTransactionRecord(RuntimeContext runtimeContext) { + TransactionRecord transactionRecord = new TransactionRecord(); + transactionRecord.setTimeStamp(runtimeContext.getResponseContext().getCommonHeader().getTimeStamp()); + transactionRecord.setRequestID(runtimeContext.getResponseContext().getCommonHeader().getRequestId()); + transactionRecord.setStartTime(runtimeContext.getTimeStart()); + transactionRecord.setEndTime(new Date(System.currentTimeMillis())); + transactionRecord.setTargetID(runtimeContext.getVnfContext().getId()); + transactionRecord.setTargetType(runtimeContext.getVnfContext().getType()); + transactionRecord.setOperation(runtimeContext.getRequestContext().getAction().name()); + transactionRecord.setResultCode(String.valueOf(runtimeContext.getResponseContext().getStatus().getCode())); + transactionRecord.setDescription(runtimeContext.getResponseContext().getStatus().getMessage()); + transactionRecorder.store(transactionRecord); + } + + private void handleRequest(RuntimeContext runtimeContext) { + + switch (runtimeContext.getRequestContext().getAction()) { + case Lock: + try { + lockWithTimeout(runtimeContext.getVnfContext().getId(), runtimeContext.getRequestContext().getCommonHeader().getRequestId()); + fillStatus(runtimeContext,LCMCommandStatus.SUCCESS, null); + } catch (LockException e) { + Params params = new Params().addParam("errorMsg", e.getMessage()); + fillStatus(runtimeContext, LCMCommandStatus.LOCKING_FAILURE, params); + storeErrorMessageToLog(runtimeContext, + LoggingConstants.TargetNames.APPC, + LoggingConstants.TargetNames.LOCK_MANAGER, + EELFResourceManager.format(Msg.VF_SERVER_BUSY, runtimeContext.getVnfContext().getId())); + } + + break; + + case Unlock: + try { + releaseVNFLock(runtimeContext.getVnfContext().getId(), runtimeContext.getRequestContext().getCommonHeader().getRequestId()); + fillStatus(runtimeContext,LCMCommandStatus.SUCCESS, null); + } catch (LockException e) { + //TODO add proper error code and message + // logger.error(EELFResourceManager.format(Msg.VF_SERVER_BUSY, runtimeContext.getVnfContext().getId())); + Params params = new Params().addParam("errorMsg", e.getMessage()); + fillStatus(runtimeContext, LCMCommandStatus.LOCKING_FAILURE, params); + } + break; + + case CheckLock: + boolean isLocked = lockManager.isLocked(runtimeContext.getVnfContext().getId()); + fillStatus(runtimeContext,LCMCommandStatus.SUCCESS, null); + runtimeContext.getResponseContext().addKeyValueToAdditionalContext("locked", String.valueOf(isLocked).toUpperCase()); + break; + default: + try { + boolean lockAcquired = acquireVNFLock(runtimeContext.getVnfContext().getId(), runtimeContext.getRequestContext().getCommonHeader().getRequestId(), 0); + runtimeContext.setIsLockAcquired(lockAcquired); + callWfOperation(runtimeContext); + } catch (LockException e) { + Params params = new Params().addParam("errorMsg", e.getMessage()); + fillStatus(runtimeContext, LCMCommandStatus.LOCKING_FAILURE, params); + } finally { + if (runtimeContext.isLockAcquired()) { + final int statusCode = runtimeContext.getResponseContext().getStatus().getCode(); + if (statusCode % 100 == 2 || statusCode % 100 == 3) { + try { + releaseVNFLock(runtimeContext.getVnfContext().getId(), runtimeContext.getRequestContext().getCommonHeader().getRequestId()); + //TODO add logger call + } catch (LockException e) { + //ignore + } + } + } + } + } + + } + + private void callWfOperation(RuntimeContext runtimeContext) { + int remainingTTL = calculateRemainingTTL(runtimeContext.getRequestContext().getCommonHeader()); + if (remainingTTL > 0) { + if (logger.isDebugEnabled()) { + logger.debug("Calling command Executor with remaining TTL value: " + remainingTTL); + } + + RuntimeContext clonedContext = cloneContext(runtimeContext); + + CommandExecutorInput commandExecutorInput = new CommandExecutorInput(); + commandExecutorInput.setRuntimeContext(clonedContext); + commandExecutorInput.setTtl(remainingTTL); + + try { + commandExecutor.executeCommand(commandExecutorInput); + if(logger.isTraceEnabled()) { + logger.trace("Command was added to queue successfully for vnfID = " + ObjectUtils.toString(runtimeContext.getRequestContext().getActionIdentifiers().getVnfId())); + } + fillStatus(runtimeContext, LCMCommandStatus.ACCEPTED, null); + if (isMetricEnabled) { + ((DispatchingFuntionMetric) metricRegistry.metric("DISPATCH_FUNCTION")).incrementAcceptedRequest(); + } + } catch (APPCException e) { + String errorMessage = e.getMessage() != null ? e.getMessage() : e.toString(); + Params params = new Params().addParam("errorMsg", errorMessage); + fillStatus(runtimeContext, LCMCommandStatus.UNEXPECTED_ERROR, params); + } + + } else { + fillStatus(runtimeContext, LCMCommandStatus.EXPIRED_REQUEST, null); + storeErrorMessageToLog(runtimeContext, + LoggingConstants.TargetNames.APPC, + LoggingConstants.TargetNames.REQUEST_HANDLER, + EELFResourceManager.format(Msg.APPC_EXPIRED_REQUEST, + runtimeContext.getRequestContext().getCommonHeader().getOriginatorId(), + runtimeContext.getRequestContext().getActionIdentifiers().getVnfId(), + String.valueOf(runtimeContext.getRequestContext().getCommonHeader().getFlags().getTtl()))); + } + } + + private void fillStatus(RuntimeContext runtimeContext, LCMCommandStatus lcmCommandStatus, Params params) { + runtimeContext.getResponseContext().getStatus().setCode(lcmCommandStatus.getResponseCode()); + runtimeContext.getResponseContext().getStatus().setMessage(lcmCommandStatus.getFormattedMessage(params)); + } + + /* + * Workaround to clone context in order to prevent sharing of ResponseContext by two threads (one to set Accepted + * status code and other - depending on DG status). Other properties should not be a problem + */ + private RuntimeContext cloneContext(RuntimeContext runtimeContext) { + RuntimeContext other = new RuntimeContext(); + other.setRequestContext(runtimeContext.getRequestContext()); + other.setResponseContext(new ResponseContext()); + other.getResponseContext().setStatus(new Status()); + other.getResponseContext().setCommonHeader(runtimeContext.getRequestContext().getCommonHeader()); + other.setVnfContext(runtimeContext.getVnfContext()); + other.setRpcName(runtimeContext.getRpcName()); + other.setTimeStart(runtimeContext.getTimeStart()); + other.setIsLockAcquired(runtimeContext.isLockAcquired()); + return other; + } + + + private void clearRequestLogProperties() { + try { + MDC.remove(MDC_KEY_REQUEST_ID); + MDC.remove(MDC_SERVICE_INSTANCE_ID); + MDC.remove(MDC_SERVICE_NAME); + MDC.remove(LoggingConstants.MDCKeys.PARTNER_NAME); + MDC.remove(LoggingConstants.MDCKeys.TARGET_VIRTUAL_ENTITY); + } catch (Exception e) { + + } + } + + private void removeRequestFromRegistry(CommonHeader commonHeader) { + if (logger.isTraceEnabled()) + logger.trace("Entering to removeRequestFromRegistry with RequestHeader = " + ObjectUtils.toString(commonHeader)); + requestRegistry.removeRequest( + new UniqueRequestIdentifier(commonHeader.getOriginatorId(), + commonHeader.getRequestId(), + commonHeader.getSubRequestId())); + } + + private boolean acquireVNFLock(String vnfID, String requestId, long timeout) throws LockException { + if (logger.isTraceEnabled()) + logger.trace("Entering to acquireVNFLock with vnfID = " + vnfID); + boolean lockAcquired = lockManager.acquireLock(vnfID, requestId, timeout); + if (lockAcquired) { + logger.info("Lock acquired for vnfID = " + vnfID); + } else { + logger.info("vnfID = " + vnfID + " was already locked"); + } + return lockAcquired; + } + + private void lockWithTimeout(String vnfId, String requestId) throws LockException { + long timeout = configuration.getLongProperty(PROP_IDLE_TIMEOUT, Constants.DEFAULT_IDLE_TIMEOUT); + acquireVNFLock(vnfId, requestId, timeout); + } + + private void resetLock(String vnfId, String requestId, boolean lockAcquired, boolean resetLockTimeout) { + if (lockAcquired) { + try { + releaseVNFLock(vnfId, requestId); + } catch (LockException e) { + logger.error("Unlock VNF [" + vnfId + "] failed. Request id: [" + requestId + "]", e); + + + } + } else if (resetLockTimeout) { + try { + // reset timeout to previous value + lockWithTimeout(vnfId, requestId); + } catch (LockException e) { + logger.error("Reset lock idle timeout for VNF [" + vnfId + "] failed. Request id: [" + requestId + "]", e); + } + } + } + + private void releaseVNFLock(String vnfId, String transactionId) throws LockException { + lockManager.releaseLock(vnfId, transactionId); + logger.info("Lock released for vnfID = " + vnfId); + } + + private void setInitialLogProperties(RequestContext requestContext) { + + try { + MDC.put(MDC_KEY_REQUEST_ID, requestContext.getCommonHeader().getRequestId()); + if (requestContext.getActionIdentifiers().getServiceInstanceId() != null) { + MDC.put(MDC_SERVICE_INSTANCE_ID, requestContext.getActionIdentifiers().getServiceInstanceId()); + } + MDC.put(LoggingConstants.MDCKeys.PARTNER_NAME, requestContext.getCommonHeader().getOriginatorId()); + MDC.put(MDC_INSTANCE_UUID, ""); // value should be created in the future + try { + MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getCanonicalHostName()); //Don't change it to a .getHostName() again please. It's wrong! + MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress()); + MDC.put(LoggingConstants.MDCKeys.SERVER_NAME, InetAddress.getLocalHost().getHostName()); + MDC.put(MDC_SERVICE_NAME, requestContext.getAction().name()); + MDC.put(LoggingConstants.MDCKeys.TARGET_VIRTUAL_ENTITY, requestContext.getActionIdentifiers().getVnfId()); + + } catch (Exception e) { + logger.debug(e.getMessage()); + } + } catch (RuntimeException e) { + //ignore + } + } + + + private int calculateRemainingTTL(CommonHeader commonHeader) { + if (logger.isTraceEnabled()) { + logger.trace("Entering to calculateRemainingTTL with RequestHeader = " + ObjectUtils.toString(commonHeader)); + } + long usedTimeInMillis = (System.currentTimeMillis() - commonHeader.getTimeStamp().getTime()); + logger.debug("usedTimeInMillis = " + usedTimeInMillis); + int usedTimeInSeconds = Math.round(usedTimeInMillis / 1000); + logger.debug("usedTimeInSeconds = " + usedTimeInSeconds); + Integer inputTTL = this.getInputTTL(commonHeader); + logger.debug("inputTTL = " + inputTTL); + Integer remainingTTL = inputTTL - usedTimeInSeconds; + logger.debug("Remaining TTL = " + remainingTTL); + if (logger.isTraceEnabled()) + logger.trace("Exiting from calculateRemainingTTL with (remainingTTL = " + ObjectUtils.toString(remainingTTL) + ")"); + return remainingTTL; + } + + private Integer getInputTTL(CommonHeader header) { + if (logger.isTraceEnabled()) + logger.trace("Entering in getInputTTL with RequestHeader = " + ObjectUtils.toString(header)); + if (!isValidTTL(String.valueOf(header.getFlags().getTtl()))) { + String defaultTTLStr = configuration.getProperty("org.openecomp.appc.workflow.default.ttl", String.valueOf(Constants.DEFAULT_TTL)); + Integer defaultTTL = Integer.parseInt(defaultTTLStr); + if (logger.isTraceEnabled()) + logger.trace("Exiting from getInputTTL with (defaultTTL = " + ObjectUtils.toString(defaultTTL) + ")"); + return defaultTTL; + } + if (logger.isTraceEnabled()) + logger.trace("Exiting from getInputTTL with (inputTTL = " + ObjectUtils.toString(header.getFlags().getTtl()) + ")"); + + return header.getFlags().getTtl(); + } + + private boolean isValidTTL(String ttl) { + if (ttl == null || ttl.length() == 0) { + if (logger.isTraceEnabled()) + logger.trace("Exiting from getInputTTL with (result = false)"); + return false; + } + try { + Integer i = Integer.parseInt(ttl); + return (i > 0); + } catch (NumberFormatException e) { + if (logger.isTraceEnabled()) + logger.trace("Exiting from getInputTTL with (result = false)"); + return false; + } + } + + private Boolean isLoggingEnabled() { + String defaultFlagStr = configuration.getProperty("org.openecomp.appc.localTransactionRecorder.enable", String.valueOf(Constants.DEFAULT_LOGGING_FLAG)); + Boolean defaultFlag = Boolean.parseBoolean(defaultFlagStr); + return defaultFlag; + } + + private static RequestHandlerOutput buildRequestHandlerOutput(LCMCommandStatus response, Params params) { + RequestHandlerOutput output = new RequestHandlerOutput(); + ResponseContext responseContext = new ResponseContext(); + org.openecomp.appc.domainmodel.lcm.Status status = new org.openecomp.appc.domainmodel.lcm.Status(); + status.setCode(response.getResponseCode()); + status.setMessage(response.getFormattedMessage(params)); + responseContext.setStatus(status); + output.setResponseContext(responseContext); + return output; + } + + /** + * This method perform operations required before execution of workflow starts. It retrieves next state for current operation from Lifecycle manager and update it in AAI. + * + * @return true in case AAI updates are successful. false for any error or exception. + */ + @Override + public void onRequestExecutionStart(String vnfId, boolean readOnlyActivity, String requestIdentifierString, boolean forceFlag) throws UnstableVNFException { + if (logger.isTraceEnabled()) { + logger.trace("Entering to onRequestExecutionStart with vnfId = " + vnfId + "and requestIdentifierString = " + requestIdentifierString); + } + try { + boolean updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, requestIdentifierString, forceFlag); + if (!updated) { + throw new UnstableVNFException("VNF is not stable for vnfID = " + vnfId); + } + } catch (Exception e) { + logger.error("Error updating working state for vnf " + vnfId + e); + throw new RuntimeException(e); + } + + if (logger.isTraceEnabled()) + logger.trace("Exiting from onRequestExecutionStart "); + } + + /** + * This method perform following operations required after execution of workflow. + * It posts asynchronous response to message bus (DMaaP). + * Unlock VNF Id + * Removes request from request registry. + * Generate audit logs. + * Adds transaction record to database id if transaction logging is enabled. + * + * @param isAAIUpdated boolean flag which indicate AAI upodate status after request completion. + */ + @Override + public void onRequestExecutionEnd(RuntimeContext runtimeContext, boolean isAAIUpdated) { + if (logger.isTraceEnabled()) { + logger.trace("Entering to onRequestExecutionEnd with runtimeContext = " + ObjectUtils.toString(runtimeContext)); + } + + postMessageToDMaaP(runtimeContext.getRequestContext().getAction(), runtimeContext.getRpcName(), runtimeContext.getResponseContext()); + requestRegistry.removeRequest( + new UniqueRequestIdentifier(runtimeContext.getResponseContext().getCommonHeader().getOriginatorId(), + runtimeContext.getResponseContext().getCommonHeader().getRequestId(), + runtimeContext.getResponseContext().getCommonHeader().getSubRequestId())); + resetLock(runtimeContext.getVnfContext().getId(), runtimeContext.getResponseContext().getCommonHeader().getRequestId(), runtimeContext.isLockAcquired(), true); + Status status = runtimeContext.getResponseContext().getStatus(); + + VNFWorkingState workingState; + if (status.getCode() == LCMCommandStatus.SUCCESS.getResponseCode() || isReadOnlyAction(runtimeContext.getRequestContext().getAction())) { + workingState = VNFWorkingState.STABLE; + } else { + workingState = VNFWorkingState.UNKNOWN; + } + + UniqueRequestIdentifier requestIdentifier = new UniqueRequestIdentifier(runtimeContext.getResponseContext().getCommonHeader().getOriginatorId(), + runtimeContext.getResponseContext().getCommonHeader().getRequestId(), + runtimeContext.getResponseContext().getCommonHeader().getSubRequestId()); + + String requestIdentifierString = requestIdentifier.toIdentifierString(); + workingStateManager.setWorkingState(runtimeContext.getVnfContext().getId(), workingState, requestIdentifierString, false); + + + storeAuditLogRecord(runtimeContext); + + if (isLoggingEnabled()) { + createTransactionRecord(runtimeContext); + } + } + + private void storeAuditLogRecord(RuntimeContext runtimeContext) { + LoggingUtils.logAuditMessage(runtimeContext.getTimeStart(), + new Date(System.currentTimeMillis()), + String.valueOf(runtimeContext.getResponseContext().getStatus().getCode()), + runtimeContext.getResponseContext().getStatus().getMessage(), + this.getClass().getCanonicalName()); + } + + private void storeMetricLogRecord(RuntimeContext runtimeContext) { + LoggingUtils.logMetricsMessage(runtimeContext.getTimeStart(), + new Date(System.currentTimeMillis()), + LoggingConstants.TargetNames.APPC, + runtimeContext.getRequestContext().getAction().name(), + runtimeContext.getResponseContext().getStatus().getCode() == LCMCommandStatus.ACCEPTED.getResponseCode() ? LoggingConstants.StatusCodes.COMPLETE : LoggingConstants.StatusCodes.ERROR, + String.valueOf(runtimeContext.getResponseContext().getStatus().getCode()), + runtimeContext.getResponseContext().getStatus().getMessage(), + this.getClass().getCanonicalName()); + } + + private boolean isReadOnlyAction(VNFOperation action) { + return VNFOperation.Sync == action + || VNFOperation.Audit == action; + } + + + //returns null if asyncResponse was not modified otherwise reutrns the updated asyncResponse + private void postMessageToDMaaP(VNFOperation operation, String rpcName, ResponseContext responseContext/*, boolean isTTLEnd, boolean aaiUpdateSuccess*/) { + if (logger.isTraceEnabled()) { + logger.trace("Entering to postMessageToDMaaP with AsyncResponse = " + ObjectUtils.toString(responseContext)); + } + /*boolean updated = updateAsyncResponseStatus(responseContext, isTTLEnd, aaiUpdateSuccess); + */ + boolean callbackResponse = messageAdapter.post(operation, rpcName, responseContext); + if (!callbackResponse) { + logger.error("DMaaP posting status: " + callbackResponse, "dmaapMessage: " + responseContext); + } + if (logger.isTraceEnabled()) + logger.trace("Exiting from postMessageToDMaaP with (callbackResponse = " + ObjectUtils.toString(callbackResponse) + ")"); + } + + //returns true if asyncResponse was modified + /* private boolean updateAsyncResponseStatus(ResponseContext asyncResponse, boolean isTTLEnd, boolean aaiUpdateSuccess) { + boolean updated = false; + if (logger.isTraceEnabled()) + logger.trace("Entering to updateAsyncResponseStatus with AsyncResponse = "+ObjectUtils.toString(asyncResponse)+ ", isTTLEnd = "+ ObjectUtils.toString(isTTLEnd)+ ", aaiUpdateSuccess = "+ ObjectUtils.toString(aaiUpdateSuccess)); + if(!aaiUpdateSuccess){ + if (asyncResponse.getStatus().getCode() == 0 || asyncResponse.getStatus().getCode() == LCMCommandStatus.SUCCESS.getResponseCode()) { + asyncResponse.getStatus().setCode(LCMCommandStatus.UPDATE_AAI_FAILURE.getResponseCode()); + asyncResponse.getStatus().setMessage(LCMCommandStatus.UPDATE_AAI_FAILURE.getResponseMessage()); + updated = true; + } + }else if(isTTLEnd){ + asyncResponse.getStatus().setCode(LCMCommandStatus.EXPIRED_REQUEST_FAILURE.getResponseCode()); + asyncResponse.getStatus().setMessage(LCMCommandStatus.EXPIRED_REQUEST_FAILURE.getResponseMessage()); + updated = true; + } + if (logger.isTraceEnabled()) + logger.trace("Exiting from updateAsyncResponseStatus with (asyncResponse = "+ ObjectUtils.toString(asyncResponse)+")"); + return updated; + }*/ + + + /** + * This method perform following operations required if TTL ends when request still waiting in execution queue . + * It posts asynchronous response to message bus (DMaaP). + * Unlock VNF Id + * Removes request from request registry. + * + * @param runtimeContext AsyncResponse object which contains VNF Id , timestamp , apiVersion, responseId, executionSuccess, payload, isExpired, action, startTime, vnfType, originatorId, subResponseId; + * @param updateAAI boolean flag which indicate AAI upodate status after request completion. + */ + @Override + public void onRequestTTLEnd(RuntimeContext runtimeContext, boolean updateAAI) { + if (logger.isTraceEnabled()) { + logger.trace("Entering to onRequestTTLEnd with " + + "AsyncResponse = " + ObjectUtils.toString(runtimeContext) + + ", updateAAI = " + ObjectUtils.toString(updateAAI)); + } + logger.error(LCMCommandStatus.EXPIRED_REQUEST_FAILURE.getResponseMessage()); + fillStatus(runtimeContext, LCMCommandStatus.EXPIRED_REQUEST_FAILURE, null); + postMessageToDMaaP(runtimeContext.getRequestContext().getAction(), runtimeContext.getRpcName(), runtimeContext.getResponseContext()); + resetLock(runtimeContext.getVnfContext().getId(), runtimeContext.getResponseContext().getCommonHeader().getRequestId(), runtimeContext.isLockAcquired(), true); + requestRegistry.removeRequest( + new UniqueRequestIdentifier(runtimeContext.getResponseContext().getCommonHeader().getOriginatorId(), + runtimeContext.getResponseContext().getCommonHeader().getRequestId(), + runtimeContext.getResponseContext().getCommonHeader().getSubRequestId())); + } + + private SvcLogicContext getVnfdata(String vnf_id, String prefix, SvcLogicContext ctx) throws VNFNotFoundException { + String key = "vnf-id = '" + vnf_id + "'"; + if (logger.isTraceEnabled()) { + logger.trace("Entering to getVnfdata with " + + "vnfId = " + vnf_id + + ", prefix = " + prefix + + ", SvcLogicContex = " + ObjectUtils.toString(ctx)); + } + try { + QueryStatus response = aaiService.query("generic-vnf", false, null, key, prefix, null, ctx); + if (QueryStatus.NOT_FOUND.equals(response)) { + throw new VNFNotFoundException("VNF not found for vnf_id = " + vnf_id); + } else if (QueryStatus.FAILURE.equals(response)) { + throw new RuntimeException("Error Querying AAI with vnfID = " + vnf_id); + } + logger.info("AAIResponse: " + response.toString()); + } catch (SvcLogicException e) { + logger.error("Error in getVnfdata " + e); + throw new RuntimeException(e); + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting from getVnfdata with (SvcLogicContext = " + ObjectUtils.toString(ctx) + ")"); + } + return ctx; + } + + private boolean postVnfdata(String vnf_id, String status, String prefix, SvcLogicContext ctx) throws VNFNotFoundException { + if (logger.isTraceEnabled()) { + logger.trace("Entering to postVnfdata with " + + "vnfId = " + vnf_id + + ", status = " + status + + ", prefix = " + prefix + + ", SvcLogicContext = " + ObjectUtils.toString(ctx)); + } + String key = "vnf-id = '" + vnf_id + "'"; + Map<String, String> data = new HashMap<>(); + data.put("orchestration-status", status); + try { + QueryStatus response = aaiService.update("generic-vnf", key, data, prefix, ctx); + if (QueryStatus.NOT_FOUND.equals(response)) { + throw new VNFNotFoundException("VNF not found for vnf_id = " + vnf_id); + } + logger.info("AAIResponse: " + response.toString()); + if (response.toString().equals("SUCCESS")) { + if (logger.isTraceEnabled()) { + logger.trace("Exiting from postVnfdata with (Result = " + ObjectUtils.toString(true) + ")"); + } + return true; + } + + } catch (SvcLogicException e) { + logger.error("Error in postVnfdata " + e); + throw new RuntimeException(e); + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting from postVnfdata with (Result = " + ObjectUtils.toString(false) + ")"); + } + return false; + } + + private void initMetric() { + if (logger.isDebugEnabled()) + logger.debug("Metric getting initialized"); + MetricService metricService = getMetricservice(); + metricRegistry = metricService.createRegistry("APPC"); + DispatchingFuntionMetric dispatchingFuntionMetric = metricRegistry.metricBuilderFactory(). + dispatchingFunctionCounterBuilder(). + withName("DISPATCH_FUNCTION").withType(MetricType.COUNTER). + withAcceptRequestValue(0) + .withRejectRequestValue(0) + .build(); + if (metricRegistry.register(dispatchingFuntionMetric)) { + Metric[] metrics = new Metric[]{dispatchingFuntionMetric}; + LogPublisher logPublisher = new LogPublisher(metricRegistry, metrics); + LogPublisher[] logPublishers = new LogPublisher[1]; + logPublishers[0] = logPublisher; + PublishingPolicy manuallyScheduledPublishingPolicy = metricRegistry.policyBuilderFactory(). + scheduledPolicyBuilder().withPublishers(logPublishers). + withMetrics(metrics). + build(); + if (logger.isDebugEnabled()) + logger.debug("Policy getting initialized"); + manuallyScheduledPublishingPolicy.init(); + if (logger.isDebugEnabled()) + logger.debug("Metric initialized"); + } + } + + + private MetricService getMetricservice() { + BundleContext bctx = FrameworkUtil.getBundle(MetricService.class).getBundleContext(); + ServiceReference sref = bctx.getServiceReference(MetricService.class.getName()); + if (sref != null) { + logger.info("Metric Service from bundlecontext"); + return (MetricService) bctx.getService(sref); + } else { + logger.info("Metric Service error from bundlecontext"); + logger.warn("Cannot find service reference for org.openecomp.appc.metricservice.MetricService"); + return null; + } + } +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestValidatorImpl.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestValidatorImpl.java new file mode 100644 index 000000000..0871a8f97 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestValidatorImpl.java @@ -0,0 +1,382 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.requesthandler.impl; + +import org.apache.commons.lang.ObjectUtils; +import org.openecomp.appc.common.constant.Constants; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.domainmodel.lcm.*; +import org.openecomp.appc.executor.UnstableVNFException; +import org.openecomp.appc.executor.objects.UniqueRequestIdentifier; +import org.openecomp.appc.i18n.Msg; +import org.openecomp.appc.lifecyclemanager.LifecycleManager; +import org.openecomp.appc.lifecyclemanager.objects.LifecycleException; +import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException; +import org.openecomp.appc.logging.LoggingConstants; +import org.openecomp.appc.logging.LoggingUtils; +import org.openecomp.appc.requesthandler.exceptions.*; +import org.openecomp.appc.requesthandler.helper.RequestRegistry; +import org.openecomp.appc.requesthandler.helper.RequestValidator; +import org.openecomp.appc.workflow.WorkFlowManager; +import org.openecomp.appc.workflow.objects.WorkflowExistsOutput; +import org.openecomp.appc.workflow.objects.WorkflowRequest; +import org.openecomp.appc.workingstatemanager.WorkingStateManager; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicException; +import org.openecomp.sdnc.sli.SvcLogicResource; +import org.openecomp.sdnc.sli.aai.AAIService; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +import java.util.Calendar; +import java.util.Date; + + +public class RequestValidatorImpl implements RequestValidator { + + private AAIService aaiService; + + private LifecycleManager lifecyclemanager; + + private WorkFlowManager workflowManager; + + private WorkingStateManager workingStateManager; + + private final RequestRegistry requestRegistry = new RequestRegistry(); + + private final Configuration configuration = ConfigurationFactory.getConfiguration(); + private final EELFLogger logger = EELFManager.getInstance().getLogger(RequestValidatorImpl.class); + private final EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger(); + + public void setLifecyclemanager(LifecycleManager lifecyclemanager) { + this.lifecyclemanager = lifecyclemanager; + } + + public void setWorkflowManager(WorkFlowManager workflowManager) { + this.workflowManager = workflowManager; + } + + public void setWorkingStateManager(WorkingStateManager workingStateManager) { + this.workingStateManager = workingStateManager; + } + + public RequestValidatorImpl() { + } + + @Override + public void validateRequest(RuntimeContext runtimeContext) throws VNFNotFoundException, RequestExpiredException, UnstableVNFException, InvalidInputException, DuplicateRequestException, NoTransitionDefinedException, LifecycleException, WorkflowNotFoundException,DGWorkflowNotFoundException { + if (logger.isTraceEnabled()){ + logger.trace("Entering to validateRequest with RequestHandlerInput = "+ ObjectUtils.toString(runtimeContext)); + } + getAAIservice(); + validateInput(runtimeContext.getRequestContext()); + checkVNFWorkingState(runtimeContext); + String vnfId = runtimeContext.getRequestContext().getActionIdentifiers().getVnfId(); + VNFContext vnfContext = queryAAI(vnfId); + runtimeContext.setVnfContext(vnfContext); + + queryLCM(runtimeContext.getVnfContext().getStatus(), runtimeContext.getRequestContext().getAction()); + VNFOperation operation = runtimeContext.getRequestContext().getAction(); + if(!operation.isBuiltIn()) { + // for built-in operations skip WF presence check + queryWFM(vnfContext, runtimeContext.getRequestContext()); + } + } + + private boolean isValidTTL(String ttl) { + if (logger.isTraceEnabled()){ + logger.trace("Entering to isValidTTL where ttl = "+ ObjectUtils.toString(ttl)); + } + if (ttl == null || ttl.length() == 0) { + if (logger.isTraceEnabled()) { + logger.trace("Exiting from isValidTT with (result = "+ ObjectUtils.toString(false)+")"); + } + return false; + } + try { + Integer i = Integer.parseInt(ttl); + if (logger.isTraceEnabled()) { + logger.trace("Exiting from isValidTTL with (result = "+ ObjectUtils.toString(i > 0)+")"); + } + return (i > 0); + } catch (NumberFormatException e) { + if (logger.isTraceEnabled()) { + logger.trace("Exiting from isValidTTL with (result = "+ ObjectUtils.toString(false)+")"); + } + return false; + } + } + + private void validateInput(RequestContext requestContext) throws RequestExpiredException, InvalidInputException, DuplicateRequestException { + if (logger.isTraceEnabled()){ + logger.trace("Entering to validateInput with RequestHandlerInput = "+ ObjectUtils.toString(requestContext)); + } + if (requestContext.getActionIdentifiers().getVnfId() == null || requestContext.getAction() == null + || requestContext.getActionIdentifiers().getVnfId().length() == 0 || requestContext.getAction().name().length() == 0 || + null == requestContext.getCommonHeader().getApiVer()) { + if (logger.isDebugEnabled()) { + logger.debug("vnfID = " + requestContext.getActionIdentifiers().getVnfId() + ", action = " + requestContext.getAction().name()); + } + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.REQUEST_VALIDATOR, + EELFResourceManager.format(Msg.APPC_INVALID_INPUT), + this.getClass().getCanonicalName()); + + throw new InvalidInputException("vnfID or command is null"); + } + CommonHeader commonHeader = requestContext.getCommonHeader(); + + checkForDuplicateRequest(commonHeader); + + Calendar inputTimeStamp = DateToCalendar(commonHeader.getTimeStamp()); + Calendar currentTime = Calendar.getInstance(); + + // If input timestamp is of future, we reject the request + if (inputTimeStamp.getTime().getTime() > currentTime.getTime().getTime()) { + if (logger.isDebugEnabled()) { + logger.debug("Input Timestamp is of future = " + inputTimeStamp.getTime()); + } + throw new InvalidInputException("Input Timestamp is of future = " + inputTimeStamp.getTime()); + } + Integer ttl = readTTL(commonHeader); + logger.debug("TTL value set to (seconds) : " + ttl); + inputTimeStamp.add(Calendar.SECOND, ttl); + if (currentTime.getTime().getTime() >= inputTimeStamp.getTime().getTime()) { + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.REQUEST_VALIDATOR, + "TTL Expired: Current time - " + currentTime.getTime().getTime() + " Request time: " + inputTimeStamp.getTime().getTime() + " with TTL value: " + ttl, + this.getClass().getCanonicalName()); + + throw new RequestExpiredException("TTL Expired"); + } + if (logger.isDebugEnabled()) { + logger.debug("Validation of the request is successful"); + } + } + + + private static Calendar DateToCalendar(Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + return cal; + } + + // TODO: Get reference once via Blueprint and get rid of this method + private void getAAIservice() { + BundleContext bctx = FrameworkUtil.getBundle(AAIService.class).getBundleContext(); + // Get AAIadapter reference + ServiceReference sref = bctx.getServiceReference(AAIService.class.getName()); + if (sref != null) { + logger.info("AAIService from bundlecontext"); + aaiService = (AAIService) bctx.getService(sref); + + } else { + logger.info("AAIService error from bundlecontext"); + logger.warn("Cannot find service reference for org.openecomp.sdnc.sli.aai.AAIService"); + + } + } + + private VNFContext queryAAI(String vnfId) throws VNFNotFoundException { + SvcLogicContext ctx = new SvcLogicContext(); + ctx = getVnfdata(vnfId, "vnf", ctx); + + VNFContext vnfContext = new VNFContext(); + populateVnfContext(vnfContext, ctx); + + return vnfContext; + } + + private String queryLCM(String orchestrationStatus, VNFOperation action) throws LifecycleException, NoTransitionDefinedException { + if (logger.isTraceEnabled()) { + logger.trace("Entering to queryLCM with Orchestration Status = "+ ObjectUtils.toString(orchestrationStatus)+ + ", command = "+ ObjectUtils.toString(action)); + } + + String nextState = lifecyclemanager.getNextState(null, orchestrationStatus, action.name()); + if (logger.isDebugEnabled()) { + logger.trace("Exiting from queryLCM with (LCMResponse = "+ ObjectUtils.toString(nextState)+")"); + } + return nextState; + } + + private void queryWFM(VNFContext vnfContext, RequestContext requestContext) throws WorkflowNotFoundException,DGWorkflowNotFoundException { + + checkWorkflowExists(vnfContext, requestContext); + } + + private void checkWorkflowExists(VNFContext vnfContext, RequestContext requestContext) throws WorkflowNotFoundException,DGWorkflowNotFoundException { + + WorkflowExistsOutput workflowExistsOutput = workflowManager.workflowExists(getWorkflowQueryParams(vnfContext, requestContext)); + if (!workflowExistsOutput.isMappingExist()) { + if (logger.isDebugEnabled()) { + logger.debug("WorkflowManager : Workflow not found for vnfType = " + vnfContext.getType() + ", version = " + vnfContext.getVersion() + ", command = " + requestContext.getAction().name()); + } + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.WORKFLOW_MANAGER, + EELFResourceManager.format(Msg.APPC_WORKFLOW_NOT_FOUND, vnfContext.getType(), requestContext.getAction().name()), + this.getClass().getCanonicalName()); + + + throw new WorkflowNotFoundException("Workflow not found for vnfType = " + vnfContext.getType() + ", command = " + requestContext.getAction().name(),vnfContext.getType(),requestContext.getAction().name()); + } + if (!workflowExistsOutput.isDgExist()) { + if (logger.isDebugEnabled()) { + logger.debug("WorkflowManager : DG Workflow not found for vnfType = " + vnfContext.getType() + ", version = " + vnfContext.getVersion() + ", command = " + requestContext.getAction().name()+" "+workflowExistsOutput); + } + + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.WORKFLOW_MANAGER, + EELFResourceManager.format(Msg.APPC_WORKFLOW_NOT_FOUND, vnfContext.getType(), requestContext.getAction().name()), + this.getClass().getCanonicalName()); + + + throw new DGWorkflowNotFoundException("Workflow not found for vnfType = " + vnfContext.getType() + ", command = " + requestContext.getAction().name(), + workflowExistsOutput.getWorkflowModule(),workflowExistsOutput.getWorkflowName(),workflowExistsOutput.getWorkflowVersion()); + } + } + + private void populateVnfContext(VNFContext vnfContext, SvcLogicContext ctx) { + vnfContext.setType(ctx.getAttribute("vnf.vnf-type")); + vnfContext.setStatus(ctx.getAttribute("vnf.orchestration-status")); + vnfContext.setId(ctx.getAttribute("vnf.vnf-id")); + // TODO: Uncomment once A&AI supports VNF version + //vnfContext.setVersion(ctx.getAttribute("vnf.vnf-version")); + } + + private WorkflowRequest getWorkflowQueryParams(VNFContext vnfContext, RequestContext requestContext) { + + WorkflowRequest workflowRequest = new WorkflowRequest(); + workflowRequest.setVnfContext(vnfContext); + workflowRequest.setRequestContext(requestContext); + if (logger.isTraceEnabled()) { + logger.trace("Exiting from etWorkflowQueryParams with (WorkflowRequest = "+ ObjectUtils.toString(workflowRequest)+")"); + } + return workflowRequest; + } + + + private void checkForDuplicateRequest(CommonHeader header) throws DuplicateRequestException { + if (logger.isTraceEnabled()) { + logger.trace("Entering to checkForDuplicateRequest with RequestHeader = "+ ObjectUtils.toString(header)); + } + + UniqueRequestIdentifier requestIdentifier = new UniqueRequestIdentifier(header.getOriginatorId(), header.getRequestId(), header.getSubRequestId()); + boolean requestAccepted = requestRegistry.registerRequest(requestIdentifier); + if (!requestAccepted) { + if (logger.isDebugEnabled()) { + logger.debug("Duplicate Request with " + requestIdentifier); + } + throw new DuplicateRequestException("Duplicate Request with " + requestIdentifier); + } + } + + private void checkVNFWorkingState(RuntimeContext runtimeContext) throws UnstableVNFException { + + if (logger.isTraceEnabled()) { + logger.trace("Entering to checkVNFWorkingState with RequestHandlerInput = "+ ObjectUtils.toString(runtimeContext.getRequestContext())); + } + boolean forceFlag = runtimeContext.getRequestContext().getCommonHeader().getFlags() != null ? runtimeContext.getRequestContext().getCommonHeader().getFlags().isForce() : false; + String vnfId = runtimeContext.getRequestContext().getActionIdentifiers().getVnfId(); + + if (logger.isDebugEnabled()) { + logger.debug("forceFlag = " + forceFlag); + } + boolean isVNFStable = workingStateManager.isVNFStable(vnfId); + if (!isVNFStable && !forceFlag) { + if (logger.isDebugEnabled()) { + logger.debug("VNF is not stable for VNF ID = " + vnfId); + } + throw new UnstableVNFException("VNF is not stable for vnfID = " + vnfId); + } + + } + + + private Integer readTTL(CommonHeader header) { + if (logger.isTraceEnabled()) { + logger.trace("Entering to readTTL with RequestHandlerInput = "+ ObjectUtils.toString(header)); + } + if (header.getFlags()== null || !isValidTTL(String.valueOf(header.getFlags().getTtl()))) { + String defaultTTLStr = configuration.getProperty("org.openecomp.appc.workflow.default.ttl", String.valueOf(Constants.DEFAULT_TTL)); + Integer defaultTTL = Integer.parseInt(defaultTTLStr); + return defaultTTL; + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting from readTTL with (TTL = "+ ObjectUtils.toString(header.getFlags().getTtl())+")"); + } + return header.getFlags().getTtl(); + } + + + private SvcLogicContext getVnfdata(String vnf_id, String prefix, SvcLogicContext ctx) throws VNFNotFoundException { + if (logger.isTraceEnabled()) { + logger.trace("Entering to getVnfdata with vnfid = "+ ObjectUtils.toString(vnf_id) + ", prefix = "+ ObjectUtils.toString(prefix)+ ", SvcLogicContext"+ ObjectUtils.toString(ctx)); + } + + String key = "vnf-id = '" + vnf_id + "'"; + logger.debug("inside getVnfdata=== " + key); + try { + Date beginTimestamp = new Date(); + SvcLogicResource.QueryStatus response = aaiService.query("generic-vnf", false, null, key, prefix, null, ctx); + Date endTimestamp = new Date(); + String status = SvcLogicResource.QueryStatus.SUCCESS.equals(response) ? LoggingConstants.StatusCodes.COMPLETE : LoggingConstants.StatusCodes.ERROR; + LoggingUtils.logMetricsMessage( + beginTimestamp, + endTimestamp, + LoggingConstants.TargetNames.AAI, + LoggingConstants.TargetServiceNames.AAIServiceNames.QUERY, + status, + "", + response.name(), + this.getClass().getCanonicalName()); + if (SvcLogicResource.QueryStatus.NOT_FOUND.equals(response)) { + throw new VNFNotFoundException("VNF not found for vnf_id = " + vnf_id); + } else if (SvcLogicResource.QueryStatus.FAILURE.equals(response)) { + throw new RuntimeException("Error Querying AAI with vnfID = " + vnf_id); + } + logger.info("AAIResponse: " + response.toString()); + } catch (SvcLogicException e) { + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetServiceNames.AAIServiceNames.GET_VNF_DATA, + "Error in getVnfdata" + e, + this.getClass().getCanonicalName()); + + throw new RuntimeException(e); + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting from getVnfdata with (SvcLogicContext = "+ ObjectUtils.toString(ctx)+")"); + } + return ctx; + } + +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/WorkingStateManager.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/WorkingStateManager.java new file mode 100644 index 000000000..8755ad3f5 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/WorkingStateManager.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.workingstatemanager; + +import org.openecomp.appc.requesthandler.exceptions.VNFNotFoundException; +import org.openecomp.appc.workingstatemanager.objects.VNFWorkingState; + + +public interface WorkingStateManager { + + /** + * Return true if vnf state exists in working state map and state is STABLE else return false. If vnf does not exists in working state map throws vnf not found exception. + * @param vnfId vnf Id to be verified for stable state + * @return True if vnf Exists and state is STABLE else False. + */ + public boolean isVNFStable(String vnfId); + + /** + * Updates working state for given vnf Id. Returns true if update was allowed and succeeded. Update will success only if the existing vnf state is 'STABLE' or + * if the registered ownerId is equal to the given ownerId or if the forceFlag is true. + * Note on case of simultaneously updates the latest updates will be failed, and another attempts will be done after refetching the updated data from persistent store. + * @param vnfId vnf Id to be updated + * @param workingState new working state + * @param ownerId + * @param forceFlag - force to update also on case given onwerId is different then the registered one + */ + public boolean setWorkingState(String vnfId, VNFWorkingState workingState, String ownerId, boolean forceFlag); + +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/JdbcWorkingStateManager.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/JdbcWorkingStateManager.java new file mode 100644 index 000000000..07d97739a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/JdbcWorkingStateManager.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.workingstatemanager.impl; + +import java.sql.Connection; + +import org.openecomp.appc.dao.util.JdbcConnectionFactory; +import org.openecomp.appc.workingstatemanager.WorkingStateManager; + +public abstract class JdbcWorkingStateManager implements WorkingStateManager { + + private JdbcConnectionFactory connectionFactory; + + public void setConnectionFactory(JdbcConnectionFactory connectionFactory) { + this.connectionFactory = connectionFactory; + } + + protected Connection openDbConnection() { + return connectionFactory.openDbConnection(); + } + + protected void closeDbConnection(Connection connection) { + connectionFactory.closeDbConnection(connection); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/RequestHandlerMessages.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/RequestHandlerMessages.java new file mode 100644 index 000000000..1de81606e --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/RequestHandlerMessages.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.workingstatemanager.impl; + + +public class RequestHandlerMessages { + public final static String VNF_WORKING_STATE_UPDATED = "VNF WorkingState for vnfId ${vnfId} was updated to ${workingState} at attempt ${attempt} out of ${maxAttempts} with ownerId = ${ownerId} and forceFlag = ${forceFlag}"; + public final static String VNF_WORKING_STATE_WAS_NOT_UPDATED = "VNF WorkingState for vnfId ${vnfId} was not updated to ${workingState} attempt ${attempt} out of ${maxAttempts} with ownerId = ${ownerId} and forceFlag = ${forceFlag}"; +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/WorkingStateManagerImpl.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/WorkingStateManagerImpl.java new file mode 100644 index 000000000..732a41304 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/WorkingStateManagerImpl.java @@ -0,0 +1,227 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.workingstatemanager.impl; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.lang.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.executor.objects.Params; +import org.openecomp.appc.message.RequestHandlerMessages; +import org.openecomp.appc.util.MessageFormatter; +import org.openecomp.appc.workingstatemanager.objects.VNFWorkingState; +import org.openecomp.appc.workingstatemanager.objects.VnfWorkingStateDto; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.apache.commons.lang3.StringUtils; + + +public class WorkingStateManagerImpl extends JdbcWorkingStateManager { + + private static final String SQL_RETRIEVE_VNF_STATE_MANAGEMENT = "SELECT VNF_ID,STATE,OWNER_ID,UPDATED,VER FROM VNF_STATE_MANAGEMENT WHERE VNF_ID=?"; + private static final String SQL_INSERT_VNF_STATE_MANAGEMENT = "INSERT IGNORE INTO VNF_STATE_MANAGEMENT (VNF_ID,STATE,OWNER_ID,UPDATED,VER) VALUES (?, ?, ?, ?, ?)"; + private static final String SQL_UPDATE_VNF_STATE_MANAGEMENT = "UPDATE VNF_STATE_MANAGEMENT SET OWNER_ID=?, UPDATED=?, STATE=?, VER=? WHERE VNF_ID=? AND VER=?"; + private static final String SQL_CURRENT_TIMESTAMP = "SELECT CURRENT_TIMESTAMP()"; + private static int maxAttempts = ConfigurationFactory.getConfiguration().getIntegerProperty("org.openecomp.appc.workingstatemanager.maxAttempts",20); + + private static Map<String,VNFWorkingState> workingStateMap = new ConcurrentHashMap<>(); + private static final EELFLogger logger = EELFManager.getInstance().getLogger(WorkingStateManagerImpl.class); + + + /** + * Return true if vnf state exists in working state map and state is STABLE else return false. If vnf does not exists in working state map throws vnf not found exception. + * @param vnfId vnf Id to be verified for stable state + * @return True if vnf Exists and state is STABLE else False. + */ + @Override + public boolean isVNFStable(String vnfId){ + if (logger.isTraceEnabled()) { + logger.trace("Entering to isVNFStable with vnfId = "+ vnfId); + } + Connection connection = null; + boolean vnfStable = false; + try { + connection = openDbConnection(); + VnfWorkingStateDto vnfWorkingStateDto = retrieveVnfWorkingState(connection, vnfId); + vnfStable = isVNFStable(vnfWorkingStateDto); + } catch (SQLException e) { + String errMsg = StringUtils.isEmpty(e.getMessage())? e.toString() :e.getMessage(); + throw new RuntimeException(errMsg); + } finally { + if(connection != null) { + closeDbConnection(connection); + } + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting from isVNFStable for vnfId = "+ vnfId+" with Result = "+vnfStable); + } + return vnfStable; + } + + /** + * Updates working state for given vnf Id. Returns true if update was allowed and succeeded. Update will success only if the existing vnf state is 'STABLE' or + * if the registered ownerId is equal to the given ownerId or if the forceFlag is true. + * Note on case of simultaneously updates the latest updates will be failed, and another attempts will be done after refetching the updated data from persistent store. + * @param vnfId vnf Id to be updated + * @param workingState new working state + * @param ownerId + * @param forceFlag - force to update also on case given onwerId is different then the registered one + */ + @Override + public boolean setWorkingState(String vnfId, VNFWorkingState workingState, String ownerId, boolean forceFlag){ + boolean updated = false; + if (logger.isTraceEnabled()) { + logger.trace("Entering to setWorkingState with vnfId = "+ ObjectUtils.toString(vnfId)+ ", VNFWorkingState = " + workingState.name() + ", ownerId = "+ownerId+", forceFlag = "+forceFlag); + } + Connection connection = null; + try { + connection = openDbConnection(); + updated = setWorkingStateIfStableOrSameOwnerIdOrForce(connection, vnfId, workingState, ownerId, forceFlag, maxAttempts); + } catch (SQLException e) { + String errMsg = StringUtils.isEmpty(e.getMessage())? e.toString() :e.getMessage(); + throw new RuntimeException(errMsg); + } finally { + if(connection != null) { + closeDbConnection(connection); + } + } + + logger.trace("setWorkingState exit with output updated = "+updated); + return updated; + } + + public boolean setWorkingStateIfStableOrSameOwnerIdOrForce(Connection connection, String vnfId, VNFWorkingState workingState, String ownerId, boolean forceFlag, int maxAttempts) throws SQLException { + return setWorkingStateIfStableOrSameOwnerIdOrForce(connection, vnfId, workingState, ownerId, forceFlag,1,maxAttempts); + } + public boolean setWorkingStateIfStableOrSameOwnerIdOrForce(Connection connection, String vnfId, VNFWorkingState workingState, String ownerId, boolean forceFlag,int attempt, int maxAttempts) throws SQLException { + boolean updated = false; + VnfWorkingStateDto vnfWorkingStateDto = retrieveVnfWorkingState(connection, vnfId); + Long currentVersion = vnfWorkingStateDto != null ? vnfWorkingStateDto.getVer() : null; + if(forceFlag || isVNFStable(vnfWorkingStateDto) || vnfWorkingStateDto.getOwnerId().equals(ownerId)){ + updated = storeWorkingStateIfSameVersion(connection, vnfId, workingState, ownerId, currentVersion); + + Params params = new Params().addParam("vnfId", vnfId).addParam("workingState",workingState.name()) + .addParam("attempt",attempt).addParam("maxAttempts",maxAttempts).addParam("ownerId",ownerId).addParam("forceFlag",forceFlag); + String logMessage; + if(updated) { + logMessage = MessageFormatter.format(RequestHandlerMessages.VNF_WORKING_STATE_UPDATED, params.getParams()); + }else { + logMessage = MessageFormatter.format(RequestHandlerMessages.VNF_WORKING_STATE_WAS_NOT_UPDATED, params.getParams()); + } + logger.debug(logMessage); + if(!updated && attempt<maxAttempts){ + setWorkingStateIfStableOrSameOwnerIdOrForce(connection, vnfId, workingState, ownerId, forceFlag,++attempt,maxAttempts); + } + + } + return updated; + } + + + public boolean storeWorkingStateIfSameVersion(Connection connection, String vnfId, VNFWorkingState workingState, String ownerId, Long currentVersion) throws SQLException { + boolean stored = false; + if (currentVersion != null) { + stored = updateStateIfSameVersion(connection, vnfId, ownerId, workingState.name(), currentVersion); + } else { + stored = addVnfWorkingStateIfNotExists(connection, vnfId, ownerId, workingState.name()); + } + + return stored; + } + + private boolean isVNFStable(VnfWorkingStateDto vnfWorkingStateDto) { + if( vnfWorkingStateDto == null || vnfWorkingStateDto.getState() ==VNFWorkingState.STABLE){ + return true; + } + return false; + } + + public boolean updateStateIfSameVersion(Connection connection, String vnfId, String ownerId, String state, long currentVer) throws SQLException { + try(PreparedStatement statement = connection.prepareStatement(SQL_UPDATE_VNF_STATE_MANAGEMENT)) { + long newVer = (currentVer >= Long.MAX_VALUE) ? 1 : (currentVer + 1); + statement.setString(1, ownerId); + statement.setLong(2, getCurrentTime(connection)); + statement.setString(3, state); + statement.setLong(4, newVer); + statement.setString(5, vnfId); + statement.setLong(6, currentVer); + return (statement.executeUpdate() != 0); + } + } + + protected VnfWorkingStateDto retrieveVnfWorkingState(Connection connection, String vnfId) throws SQLException { + VnfWorkingStateDto res = null; + + try(PreparedStatement statement = connection.prepareStatement(SQL_RETRIEVE_VNF_STATE_MANAGEMENT)) { //VNF_ID,STATE,OWNER_ID,UPDATED,VER + statement.setString(1, vnfId); + try(ResultSet resultSet = statement.executeQuery()) { + if(resultSet.next()) { + res = new VnfWorkingStateDto(vnfId); + String stateString = resultSet.getString(2); + VNFWorkingState vnfWorkingState = VNFWorkingState.valueOf(stateString); + res.setState(vnfWorkingState); + res.setOwnerId(resultSet.getString(3)); + res.setUpdated(resultSet.getLong(4)); + res.setVer(resultSet.getLong(5)); + } + } + } + return res; + } + + private long getCurrentTime(Connection connection) throws SQLException { + long res = -1; + if(connection != null) { + try(PreparedStatement statement = connection.prepareStatement(SQL_CURRENT_TIMESTAMP)) { + try(ResultSet resultSet = statement.executeQuery()) { + if(resultSet.next()) { + res = resultSet.getTimestamp(1).getTime(); + } + } + } + } + if(res == -1) { + res = System.currentTimeMillis(); + } + return res; + } + + protected boolean addVnfWorkingStateIfNotExists(Connection connection, String vnfId, String ownerId, String state) throws SQLException { + boolean added = false; + try(PreparedStatement statement = connection.prepareStatement(SQL_INSERT_VNF_STATE_MANAGEMENT)) { //VNF_ID,STATE,OWNER_ID,UPDATED,VER + statement.setString(1, vnfId); + statement.setString(2, state); + statement.setString(3, ownerId); + statement.setLong(4, getCurrentTime(connection)); + statement.setLong(5, 1L); + int rowCount = statement.executeUpdate(); + added = rowCount != 0 ? true : false; + } + return added; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VNFWorkingState.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VNFWorkingState.java new file mode 100644 index 000000000..ad6973712 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VNFWorkingState.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.workingstatemanager.objects; + + +public enum VNFWorkingState { + STABLE,UNSTABLE,UNKNOWN; + public String toString(){ + return this.name(); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VnfWorkingStateDto.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VnfWorkingStateDto.java new file mode 100644 index 000000000..ed840f480 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VnfWorkingStateDto.java @@ -0,0 +1,90 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.workingstatemanager.objects; + + +public class VnfWorkingStateDto { + private String vnfId; + private VNFWorkingState state; + private String ownerId; + private long updated; + private long ver; + + public VnfWorkingStateDto() { + } + + public VnfWorkingStateDto(String vnfId) { + this.vnfId = vnfId; + } + + public String getVnfId() { + return vnfId; + } + + public void setVnfId(String vnfId) { + this.vnfId = vnfId; + } + + public VNFWorkingState getState() { + return state; + } + + public void setState(VNFWorkingState state) { + this.state = state; + } + + public String getOwnerId() { + return ownerId; + } + + public void setOwnerId(String ownerId) { + this.ownerId = ownerId; + } + + public long getUpdated() { + return updated; + } + + public void setUpdated(long updated) { + this.updated = updated; + } + + public long getVer() { + return ver; + } + + public void setVer(long ver) { + this.ver = ver; + } + + + @Override + public String toString() { + return "VnfWorkingStateDto{" + + "vnfId='" + vnfId + '\'' + + ", state=" + state + + ", ownerId='" + ownerId + '\'' + + ", updated=" + updated + + ", ver=" + ver + + '}'; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..785b6cb04 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- + Starter Blueprint Camel Definition appc-aai-adapter-blueprint +--> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + <bean id="requestHandlerBean" class="org.openecomp.appc.requesthandler.impl.RequestHandlerImpl" scope="singleton" > + <property name="commandExecutor" ref="commandExecutorRef" /> + <property name="requestValidator" ref="requestValidatorBean" /> + <property name="lockManager" ref="lockManagerRef" /> + <property name="workingStateManager" ref="workingStateManagerBean"/> + <property name="transactionRecorder" ref="transactionRecorderRef" /> + <property name="aaiService" ref="aaiServiceRef" /> + </bean> + + <bean id="requestValidatorBean" class="org.openecomp.appc.requesthandler.impl.RequestValidatorImpl" scope="singleton" > + <property name="lifecyclemanager" ref="lifecyclemanagerRef" /> + <property name="workflowManager" ref="workflowManagerRef" /> + <property name="workingStateManager" ref="workingStateManagerBean" /> + </bean> + + <service id="requestHandlerService" interface="org.openecomp.appc.requesthandler.RequestHandler" ref="requestHandlerBean"/> + <reference id="lifecyclemanagerRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.lifecyclemanager.LifecycleManager" /> + <reference id="workflowManagerRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.workflow.WorkFlowManager" /> + <reference id="commandExecutorRef" availability="optional" activation="eager" interface="org.openecomp.appc.executor.CommandExecutor" /> + <reference id="lockManagerRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.lockmanager.api.LockManager" /> + <reference id="transactionRecorderRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.transactionrecorder.TransactionRecorder" /> + <reference xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0" ext:proxy-method="classes" id="aaiServiceRef" availability="mandatory" activation="eager" interface="org.openecomp.sdnc.sli.aai.AAIService" /> + + <bean id="workingStateManagerBean" class="org.openecomp.appc.workingstatemanager.impl.WorkingStateManagerImpl" scope="singleton" > + <property name="connectionFactory"> + <bean class="org.openecomp.appc.dao.util.AppcJdbcConnectionFactory"> + <property name="schema" value="sdnctl"/> + </bean> + </property> + </bean> + +</blueprint> diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..2e2763f9a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,53 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + +#Property below provided by appc.properties +#dmaap.poolMembers=<DMAAP_IP>:3904 + +dmaap.topic.read=APPC-TEST2 +dmaap.topic.write=APPC-TEST2 +#dmaap.topic.read.filter={"class":"Assigned","field":"request"} +dmaap.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]} +dmaap.client.name=APPC-TEST-CLIENT-REQ-HDLR-MAIN +dmaap.client.name.id=0 +#dmaap.client.key=random +#dmaap.client.secret=random + +dmaap.threads.queuesize.min=1 +dmaap.threads.queuesize.max=1000 +dmaap.threads.poolsize.min=1 +dmaap.threads.poolsize.max=2 + +org.openecomp.appc.db.url.sdnctl=jdbc:mysql://127.0.0.1:3306/test +org.openecomp.appc.db.user.sdnctl=test +org.openecomp.appc.db.pass.sdnctl=123456 + +# +# This needs to be changed so that the action can be appended to the end of the URL path +# +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:topology-service +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider: +org.openecomp.appc.workingstatemanager.maxAttempts=20 diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestConverter.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestConverter.java new file mode 100644 index 000000000..46875a269 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestConverter.java @@ -0,0 +1,360 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.requesthandler; + +import com.fasterxml.jackson.core.JsonProcessingException; +import org.junit.Assert; +import org.junit.Test; +import org.openecomp.appc.domainmodel.lcm.*; +import org.openecomp.appc.executor.objects.LCMCommandStatus; +import org.openecomp.appc.requesthandler.conv.Converter; + +import javax.ws.rs.container.AsyncResponse; +import java.text.ParseException; +import java.util.Date; +import java.util.HashMap; + + +public class TestConverter { + private String expectedJsonBodyStr ="{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}}"; + private String expectedDmaapOutgoingMessageJsonStringTest ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"test\"}"; + private String expectedDmaapOutgoingMessageJsonStringRollback ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"rollback\"}"; + private String expectedDmaapOutgoingMessageJsonStringSnapshot ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"snapshot\"}"; + private String expectedDmaapOutgoingMessageJsonStringAudit ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"audit\"}"; + private String expectedDmaapOutgoingMessageJsonStringHealthCheck ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"health-check\"}"; + private String expectedDmaapOutgoingMessageJsonStringLiveUpgrade ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"live-upgrade\"}"; + private String expectedDmaapOutgoingMessageJsonStringLock ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"lock\"}"; + private String expectedDmaapOutgoingMessageJsonStringModifyConfig ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"modify-config\"}"; + private String expectedDmaapOutgoingMessageJsonStringSoftwareUpload ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"software-upload\"}"; + private String expectedDmaapOutgoingMessageJsonStringStop ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"stop\"}"; + private String expectedDmaapOutgoingMessageJsonStringSync ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"sync\"}"; + private String expectedDmaapOutgoingMessageJsonStringTerminate ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"terminate\"}"; + private String expectedDmaapOutgoingMessageJsonStringUnlock ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"unlock\"}"; + + @Test + public void convDateToZuluStringTest(){ + String dateToZuluString = Converter.convDateToZuluString(new Date(0L)); + Assert.assertEquals("1970-01-01T00:00:00.000Z", dateToZuluString); + } + + @Test + public void convAsyncResponseToBuilderTestTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Test; + String rpcName = action.name().toLowerCase(); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringTestTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Test; + String rpcName = action.name().toLowerCase(); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringTest,jsonStr); + } + + @Test + public void convPayloadObjectToJsonStringTest() throws JsonProcessingException, ParseException { + String jsonString = Converter.convPayloadObjectToJsonString("any valid JSON string value"); + Assert.assertEquals("any valid JSON string value", jsonString); + + HashMap<String, String> hashMap = new HashMap<>(); + hashMap.put("key","value"); + jsonString = Converter.convPayloadObjectToJsonString(hashMap); + Assert.assertEquals("{\"key\":\"value\"}", jsonString); + } + + @Test + public void convAsyncResponseToBuilderRollbackTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Rollback; + String rpcName = action.name().toLowerCase(); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringRollbackTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Rollback; + String rpcName = action.name().toLowerCase(); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringRollback,jsonStr); + } + + @Test + public void convAsyncResponseToBuilderSnapshotTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Snapshot; + String rpcName = action.name().toLowerCase(); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringSnapshotTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Snapshot; + String rpcName = action.name().toLowerCase(); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringSnapshot,jsonStr); + } + @Test + public void convAsyncResponseToBuilderAuditTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Audit; + String rpcName = action.name().toLowerCase(); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringAuditTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Audit; + String rpcName = action.name().toLowerCase(); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringAudit,jsonStr); + } + @Test + public void convAsyncResponseToBuilderHealthCheckTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.HealthCheck; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringHealthCheckTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.HealthCheck; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringHealthCheck,jsonStr); + } + @Test + public void convAsyncResponseToBuilderLiveUpgradeTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.LiveUpgrade; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringLiveUpgradeTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.LiveUpgrade; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringLiveUpgrade,jsonStr); + } + @Test + public void convAsyncResponseToBuilderLockTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Lock; + String rpcName = convertActionNameToUrl(action.name()); + + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringLockTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Lock; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringLock,jsonStr); + } + @Test + public void convAsyncResponseToBuilderModifyConfigTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.ModifyConfig; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringModifyConfigTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.ModifyConfig; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringModifyConfig,jsonStr); + } + @Test + public void convAsyncResponseToBuilderSoftwareUploadTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.SoftwareUpload; + String rpcName = convertActionNameToUrl(action.name()); + + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringSoftwareUploadTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.SoftwareUpload; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringSoftwareUpload,jsonStr); + } + @Test + public void convAsyncResponseToBuilderStopTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Stop; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringStopTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Stop; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringStop,jsonStr); + } + @Test + public void convAsyncResponseToBuilderSync() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Sync; + String rpcName = convertActionNameToUrl(action.name()); + + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringSync() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Sync; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringSync,jsonStr); + } + @Test + public void convAsyncResponseToBuilderTerminateTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Sync; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringTerminateTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Terminate; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringTerminate,jsonStr); + } + @Test + public void convAsyncResponseToBuilderUnlockTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Unlock; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringUnlockTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Unlock; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringUnlock,jsonStr); + } + /*@Test + public void convAsyncResponseToBuilderTest() throws JsonProcessingException { + AsyncResponse asyncResponse = buildAsyncResponse(); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringTest() throws JsonProcessingException { + AsyncResponse asyncResponse = buildAsyncResponse(); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonString,jsonStr); + }*/ + + + private ResponseContext buildAsyncResponse() { + ResponseContext asyncResponse = createResponseContextWithSubObjects(); + asyncResponse.getStatus().setCode(LCMCommandStatus.SUCCESS.getResponseCode()); + asyncResponse.getStatus().setMessage(LCMCommandStatus.SUCCESS.getResponseMessage()); + asyncResponse.getCommonHeader().setOriginatorId("oid"); + asyncResponse.getCommonHeader().setApiVer("2.0.0"); + asyncResponse.getCommonHeader().setRequestId("reqid"); + asyncResponse.getCommonHeader().setTimestamp(new Date(1000L)); + asyncResponse.setPayload("any valid JSON string value. Json escape characters need to be added to make it a valid json string value"); + return asyncResponse; + } + + private ResponseContext createResponseContextWithSubObjects() { + + ResponseContext responseContext = new ResponseContext(); + CommonHeader commonHeader = new CommonHeader(); + Flags flags = new Flags(); + Status status = new Status(); + responseContext.setCommonHeader(commonHeader); + responseContext.setStatus(status); + commonHeader.setFlags(flags); + return responseContext; + } + + private String convertActionNameToUrl(String action) { + String regex = "([a-z])([A-Z]+)"; + String replacement = "$1-$2"; + return action.replaceAll(regex, replacement) + .toLowerCase(); + } + + +} + + + diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestHandler.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestHandler.java new file mode 100644 index 000000000..e4c1e92d3 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestHandler.java @@ -0,0 +1,583 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.requesthandler; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mockito; +import org.openecomp.appc.domainmodel.lcm.*; +import org.openecomp.appc.executor.CommandExecutor; +import org.openecomp.appc.executor.UnstableVNFException; +import org.openecomp.appc.executor.objects.CommandExecutorInput; +import org.openecomp.appc.executor.objects.LCMCommandStatus; +import org.openecomp.appc.lifecyclemanager.LifecycleManager; +import org.openecomp.appc.lifecyclemanager.objects.LifecycleException; +import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException; +import org.openecomp.appc.lockmanager.api.LockException; +import org.openecomp.appc.lockmanager.api.LockManager; +import org.openecomp.appc.messageadapter.MessageAdapter; +import org.openecomp.appc.requesthandler.exceptions.*; +import org.openecomp.appc.requesthandler.impl.RequestHandlerImpl; +import org.openecomp.appc.requesthandler.impl.RequestValidatorImpl; +import org.openecomp.appc.requesthandler.objects.RequestHandlerInput; +import org.openecomp.appc.requesthandler.objects.RequestHandlerOutput; +import org.openecomp.appc.transactionrecorder.TransactionRecorder; +import org.openecomp.appc.transactionrecorder.objects.TransactionRecord; +import org.openecomp.appc.workflow.WorkFlowManager; +import org.openecomp.appc.workflow.objects.WorkflowExistsOutput; +import org.openecomp.appc.workflow.objects.WorkflowRequest; +import org.openecomp.appc.workingstatemanager.WorkingStateManager; +import org.openecomp.appc.workingstatemanager.objects.VNFWorkingState; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.osgi.framework.FrameworkUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.*; +import static org.mockito.Matchers.*; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest( {WorkingStateManager.class,FrameworkUtil.class, TransactionRecorder.class, RequestHandlerImpl.class,RequestValidatorImpl.class, TransactionRecorder.class}) +public class TestRequestHandler { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(TestRequestHandler.class); + + private RequestHandlerImpl requestHandler; + private RequestValidatorImpl requestValidator; + private WorkFlowManager workflowManager; + private WorkingStateManager workingStateManager ; + private LockManager lockManager; + + @Before + public void init() throws Exception { + + requestHandler = new RequestHandlerImpl(); + LifecycleManager lifecyclemanager= mock(LifecycleManager.class); + workflowManager= mock(WorkFlowManager.class); + CommandExecutor commandExecutor= mock(CommandExecutor.class); + MessageAdapter messageAdapter = mock(MessageAdapter.class); + workingStateManager = mock(WorkingStateManager.class); + lockManager = mock(LockManager.class); + TransactionRecorder transactionRecorder= mock(TransactionRecorder.class); + + requestHandler.setWorkingStateManager(workingStateManager); + requestHandler.setMessageAdapter(messageAdapter); + requestValidator = mock(RequestValidatorImpl.class); + requestValidator.setLifecyclemanager(lifecyclemanager); + requestValidator.setWorkingStateManager(workingStateManager); + requestValidator.setWorkflowManager(workflowManager); + requestValidator.setLifecyclemanager(lifecyclemanager); + requestHandler.setCommandExecutor(commandExecutor); + requestHandler.setRequestValidator(requestValidator); + requestHandler.setLockManager(lockManager); + requestHandler.setTransactionRecorder(transactionRecorder); + + doNothing().when(transactionRecorder).store((TransactionRecord) anyObject()); +// Mockito.when(commandExecutor.executeCommand((CommandExecutorInput)anyObject())).thenReturn(true); + Mockito.when(workingStateManager.isVNFStable("39")).thenReturn(true); + for(Integer i=130; i<=140 ; i++) + { + Mockito.when(workingStateManager.isVNFStable(i.toString())).thenReturn(true); + } + Mockito.when(workingStateManager.isVNFStable("39")).thenReturn(true); + Mockito.when(workingStateManager.isVNFStable("40")).thenReturn(true).thenReturn(false); + Mockito.when(workingStateManager.isVNFStable("38")).thenReturn(true).thenReturn(false); + Mockito.when(workingStateManager.isVNFStable("201")).thenReturn(true); + Mockito.when(workingStateManager.isVNFStable("202")).thenReturn(true).thenReturn(false); + Mockito.when(workingStateManager.isVNFStable("301")).thenReturn(true).thenReturn(false); + Mockito.when(workingStateManager.isVNFStable("302")).thenReturn(true).thenReturn(true); + Mockito.when(workingStateManager.isVNFStable("303")).thenReturn(true).thenReturn(true); + Mockito.when(workingStateManager.isVNFStable("309")).thenReturn(true).thenReturn(true); + Mockito.when(workingStateManager.isVNFStable("310")).thenReturn(true).thenReturn(true); + } + + private void threadSleep(){ + try { + Thread.sleep(5); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + @Test + public void testNegativeFlowWithRequestingUsedVnfId() throws Exception { + logger.debug("=====================testNegativeFlowWithRequestingUsedVnfId============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input1 = this.getRequestHandlerInput("131", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + mockRuntimeContextAndVnfContext(input1); + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + PowerMockito.doThrow(new LockException(" ")).when(lockManager).acquireLock(Matchers.anyString(), Matchers.anyString(), Matchers.anyByte()); + RequestHandlerOutput output1 = requestHandler.handleRequest(input1); + threadSleep (); + Assert.assertEquals(LCMCommandStatus.LOCKING_FAILURE.getResponseCode(), output1.getResponseContext().getStatus().getCode()); + logger.debug("testNegativeFlowWithRequestingUsedVnfId"); + logger.debug("=====================testNegativeFlowWithRequestingUsedVnfId============================="); + } + + @Test + public void testInvalidVNFExceptionRequest() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure, 0,false,originatorID, requestID, subRequestID,new Date()); + PowerMockito.doThrow(new VNFNotFoundException(" ")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.VNF_NOT_FOUND.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + @Test + public void testLifecycleException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + PowerMockito.doThrow(new LifecycleException(new Exception(),"Configured","test event")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.ACTION_NOT_SUPPORTED.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + + @Test + public void testRequestExpiredException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + PowerMockito.doThrow(new RequestExpiredException("")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.EXPIRED_REQUEST.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + @Test + public void testWorkflowNotFoundException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + PowerMockito.doThrow(new WorkflowNotFoundException("Unable to find the DG","VNF-2.0.0.0", "Test")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.WORKFLOW_NOT_FOUND.getResponseCode(), output.getResponseContext().getStatus().getCode());} + + @Test + public void testDGWorkflowNotFoundException() throws Exception { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + Mockito.when(workflowManager.workflowExists((WorkflowRequest) anyObject())).thenReturn(new WorkflowExistsOutput(true, true)); + RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure, 0, false, originatorID, requestID, subRequestID, new Date()); + PowerMockito.doThrow(new DGWorkflowNotFoundException("Unable to find the DG", "VNF-2.0.0.0", "temp", "Test")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.DG_WORKFLOW_NOT_FOUND.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + @Test + public void testInvalidInputException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + String originatorID1 = UUID.randomUUID().toString(); + String requestID1 = UUID.randomUUID().toString(); + String subRequestID1 = UUID.randomUUID().toString(); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input1 = this.getRequestHandlerInput("3009", VNFOperation.Configure,0,false,originatorID1, requestID1, subRequestID1,new Date()); + PowerMockito.doThrow(new InvalidInputException(" ")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output1 = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.INVALID_INPUT_PARAMETER.getResponseCode(), output1.getResponseContext().getStatus().getCode()); + } + + @Test + public void testNoTransitionDefinedException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("3010", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + PowerMockito.doThrow(new NoTransitionDefinedException("Invalid VNF State","Unstable","Test event")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.NO_TRANSITION_DEFINE.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + @Test + public void rejectInvalidRequest() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + PowerMockito.doThrow(new VNFNotFoundException(" ")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.VNF_NOT_FOUND.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + @Test + public void testUnstableWorkingState() throws Exception { + logger.debug("=====================testUnstableWorkingState============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + Mockito.when(workingStateManager.isVNFStable("37")).thenReturn(true,false); + RequestHandlerInput input = this.getRequestHandlerInput("37", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + mockRuntimeContextAndVnfContext(input); + RequestHandlerOutput output = requestHandler.handleRequest(input); + + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(), output.getResponseContext().getStatus().getCode()); + + RequestHandlerInput input1 = this.getRequestHandlerInput("37", VNFOperation.Configure,1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + PowerMockito.doThrow(new LockException(" ")).when(lockManager).acquireLock(Matchers.anyString(), Matchers.anyString(), Matchers.anyByte()); + mockRuntimeContextAndVnfContext(input1); + RequestHandlerOutput output1 = requestHandler.handleRequest(input1); + + Assert.assertEquals(LCMCommandStatus.LOCKING_FAILURE.getResponseCode(), output1.getResponseContext().getStatus().getCode()); + logger.debug("=====================testUnstableWorkingState============================="); + } + + @Test + public void testOnRequestExecutionEndSuccessForWorkingState() throws Exception { + logger.debug("=====================testOnRequestExecutionEndSuccessForWorkingState============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input1 = this.getRequestHandlerInput("137", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + mockRuntimeContextAndVnfContext(input1); + + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + + + RequestHandlerOutput output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode()); + threadSleep(); + + requestHandler.onRequestExecutionEnd(this.getAsyncResponse(true,LCMCommandStatus.SUCCESS,"137", "", "", ""),true); + + input1 = this.getRequestHandlerInput("137", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + mockRuntimeContextAndVnfContext(input1); + output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode()); + logger.debug("=====================testOnRequestExecutionEndSuccessForWorkingState============================="); + } + + private void mockRuntimeContextAndVnfContext(RequestHandlerInput input1) throws Exception { + RuntimeContext runtimeContext = PowerMockito.mock(RuntimeContext.class); + VNFContext vnfContext = new VNFContext(); + vnfContext.setType("SCP"); + vnfContext.setId("137"); + when(runtimeContext.getVnfContext()).thenReturn(vnfContext); + when(runtimeContext.getRequestContext()).thenReturn(input1.getRequestContext()); + when(runtimeContext.getRpcName()).thenReturn(input1.getRpcName()); + + + ResponseContext responseContext = new ResponseContext(); + responseContext.setStatus(new Status()); + responseContext.setAdditionalContext(new HashMap<String, String>(4)); + responseContext.setCommonHeader(input1.getRequestContext().getCommonHeader()); + runtimeContext.setResponseContext(responseContext); + when(runtimeContext.getResponseContext()).thenReturn(responseContext); + responseContext.setStatus(new Status()); + runtimeContext.setResponseContext(responseContext); + PowerMockito.whenNew(RuntimeContext.class).withAnyArguments().thenReturn(runtimeContext); + + } + + + @Test + public void testOnRequestExecutionEndFailureForWorkingState() throws Exception { + logger.debug("=====================testOnRequestExecutionEndFailureForWorkingState============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + + RequestHandlerInput input1 = this.getRequestHandlerInput("38", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + mockRuntimeContextAndVnfContext(input1); + RequestHandlerOutput output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode()); + threadSleep(); + requestHandler.onRequestExecutionEnd(this.getAsyncResponse(false,LCMCommandStatus.NO_TRANSITION_DEFINE,"38", "", "", ""),true); + + input1 = this.getRequestHandlerInput("38", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + PowerMockito.doThrow(new UnstableVNFException(" ")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + mockRuntimeContextAndVnfContext(input1); + output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.UNSTABLE_VNF.getResponseCode(),output.getResponseContext().getStatus().getCode()); + + logger.debug("=====================testOnRequestExecutionEndFailureForWorkingState============================="); + } + + @Test + public void testOnRequestExecutionEndTTLExpiredForWorkingState() throws Exception { + logger.debug("=====================testOnRequestExecutionEndFailureForWorkingState============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + + RequestHandlerInput input1 = this.getRequestHandlerInput("39", VNFOperation.Configure, 1, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + mockRuntimeContextAndVnfContext(input1); + + RequestHandlerOutput output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode()); + threadSleep(); + input1 = this.getRequestHandlerInput("39", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + PowerMockito.doThrow(new LockException(" ")).when(lockManager).acquireLock(Matchers.anyString(), Matchers.anyString(), Matchers.anyByte()); + output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.LOCKING_FAILURE.getResponseCode(),output.getResponseContext().getStatus().getCode()); + logger.debug("=====================testOnRequestExecutionEndFailureForWorkingState============================="); + } + + @Test + public void testOnRequestTTLEndForWorkingState() throws Exception { + logger.debug("=====================testOnRequestTTLEndForWorkingState============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + + RequestHandlerInput input1 = this.getRequestHandlerInput("40", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + mockRuntimeContextAndVnfContext(input1); + RequestHandlerOutput output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode()); + threadSleep(); + RuntimeContext response = this.getAsyncResponse(false,LCMCommandStatus.EXPIRED_REQUEST_FAILURE,"40", "", "", ""); + requestHandler.onRequestTTLEnd(response,true); + input1 = this.getRequestHandlerInput("40", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + PowerMockito.doThrow(new UnstableVNFException(" ")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.UNSTABLE_VNF.getResponseCode(),output.getResponseContext().getStatus().getCode()); + logger.debug("=====================testOnRequestTTLEndForWorkingState============================="); + } + + @Test + public void testForceCommandExecution() throws Exception { + logger.debug("=====================testForceCommandExecution============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input1 = this.getRequestHandlerInput("138", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + mockRuntimeContextAndVnfContext(input1); + + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode()); + threadSleep(); + RuntimeContext response = this.getAsyncResponse(false,LCMCommandStatus.ACCEPTED,"138", "", "", ""); + requestHandler.onRequestTTLEnd(response,true); + input1 = this.getRequestHandlerInput("138", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + input1.getRequestContext().getCommonHeader().getFlags().setForce(true); + mockRuntimeContextAndVnfContext(input1); + output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode()); + logger.debug("=====================testForceCommandExecution============================="); + } + + @Test + public void testOnRequestExecutionEndSuccess() throws VNFNotFoundException { + logger.debug("=====================Positive TEST - On Request Execution End SUCCESS- Starts ============================="); + Mockito.doReturn(true).when(workingStateManager).setWorkingState(anyString(),(VNFWorkingState) anyObject(), anyString(),anyBoolean()); + requestHandler.onRequestExecutionEnd(this.getAsyncResponse(true,LCMCommandStatus.SUCCESS,"201", "", "", ""),true); + logger.debug("=====================Positive TEST - On Request Execution End SUCCESS- Ends ============================="); + } + + @Test + public void testOnRequestExecutionEndFailure() throws VNFNotFoundException { + logger.debug("=====================Positive TEST - On Request Execution End FAILURE- Starts ============================="); + Mockito.doReturn(true).when(workingStateManager).setWorkingState(anyString(),(VNFWorkingState) anyObject(), anyString(),anyBoolean()); + requestHandler.onRequestExecutionEnd(this.getAsyncResponse(false,LCMCommandStatus.DG_FAILURE,"202", "", "", ""),true); + logger.debug("=====================Positive TEST - On Request Execution End FAILURE- Ends ============================="); + } + + private RequestHandlerInput getRequestHandlerInput(String vnfID, VNFOperation action, int ttl, boolean force,String originatorId, String requestId, String subRequestId,Date timeStamp){ + String API_VERSION= "2.0.0"; + RequestHandlerInput input = new RequestHandlerInput(); + RuntimeContext runtimeContext = createRuntimeContextWithSubObjects(); + RequestContext requestContext = runtimeContext.getRequestContext(); + input.setRequestContext(requestContext); + requestContext.getActionIdentifiers().setVnfId(vnfID); + requestContext.setAction(action); + input.setRpcName(convertActionNameToUrl(action.name())); + requestContext.getCommonHeader().setRequestId(requestId); + requestContext.getCommonHeader().setSubRequestId(subRequestId); + requestContext.getCommonHeader().setOriginatorId(originatorId); + requestContext.getCommonHeader().getFlags().setTtl(ttl); + requestContext.getCommonHeader().getFlags().setForce(force); + requestContext.getCommonHeader().setTimestamp(timeStamp); + requestContext.getCommonHeader().setApiVer(API_VERSION); + return input; + } + + private RuntimeContext getAsyncResponse(boolean wfStatus, LCMCommandStatus commandStatus, String vnfId, String originatorId, String requestId, String subRequestId) + { + RuntimeContext output = createRuntimeContextWithSubObjects(); + + + output.getRequestContext().getActionIdentifiers().setVnfId(vnfId); + output.getVnfContext().setId(vnfId); + output.getResponseContext().getCommonHeader().setApiVer("2.0.0"); + output.getResponseContext().getCommonHeader().setTimestamp(new Date()); + output.getResponseContext().getStatus().setCode(LCMCommandStatus.SUCCESS.getResponseCode()); + output.setTimeStart(new Date()); + output.getResponseContext().getCommonHeader().setOriginatorId(originatorId); + output.getResponseContext().getCommonHeader().setRequestId(requestId); + output.getResponseContext().getCommonHeader().setSubRequestId(subRequestId); + + output.getVnfContext().setType("FIREWALL"); + output.getRequestContext().setAction(VNFOperation.Configure); + output.setRpcName("configure"); + output.getResponseContext().setPayload(""); + return output; + } + + @Test + public void rejectDuplicateRequest() throws Exception { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("301", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + mockRuntimeContextAndVnfContext(input); + + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(), output.getResponseContext().getStatus().getCode()); + + input = this.getRequestHandlerInput("309", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + + PowerMockito.doThrow(new DuplicateRequestException(" ")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.DUPLICATE_REQUEST.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + @Test + public void removeRequestFromRegistryOnRequestCompletion() throws Exception { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("302", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + mockRuntimeContextAndVnfContext(input); + + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(), output.getResponseContext().getStatus().getCode()); + + RuntimeContext asyncResponse = this.getAsyncResponse(true,LCMCommandStatus.SUCCESS,"302",originatorID,requestID,subRequestID); + requestHandler.onRequestExecutionEnd(asyncResponse,true); + + input = this.getRequestHandlerInput("310", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + mockRuntimeContextAndVnfContext(input); + output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + @Test + public void removeRequestFromRegistryOnTTLExpiration() throws Exception { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("303", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + mockRuntimeContextAndVnfContext(input); + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(), output.getResponseContext().getStatus().getCode()); + + RuntimeContext asyncResponse = this.getAsyncResponse(true,LCMCommandStatus.ACCEPTED,"303",originatorID,requestID,subRequestID); + requestHandler.onRequestTTLEnd(asyncResponse,false); + + output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + /*@Test + public void getMetricserviceTest() throws Exception{ + Method method = RequestHandlerImpl.class.getDeclaredMethod("getMetricservice", null); + method.setAccessible(true); + method.invoke(null, null); + + }*/ + @Test + public void onRequestExecutionStartTest() throws Exception{ + Mockito.doReturn(true).when(workingStateManager).setWorkingState(anyString(),(VNFWorkingState) anyObject(), anyString(),anyBoolean()); + requestHandler.onRequestExecutionStart("303",false, null, true); + Assert.assertNotNull(requestHandler); + } + + + private RuntimeContext createRuntimeContextWithSubObjects() { + RuntimeContext runtimeContext = new RuntimeContext(); + RequestContext requestContext = new RequestContext(); + runtimeContext.setRequestContext(requestContext); + ResponseContext responseContext = createResponseContextWithSuObjects(); + runtimeContext.setResponseContext(responseContext); + CommonHeader commonHeader = new CommonHeader(); + requestContext.setCommonHeader(commonHeader); + Flags flags = new Flags(); + commonHeader.setFlags(flags); + ActionIdentifiers actionIdentifiers = new ActionIdentifiers(); + requestContext.setActionIdentifiers(actionIdentifiers); + VNFContext vnfContext = new VNFContext(); + runtimeContext.setVnfContext(vnfContext); + return runtimeContext; + + } + + private ResponseContext createResponseContextWithSuObjects(){ + ResponseContext responseContext = new ResponseContext(); + CommonHeader commonHeader = new CommonHeader(); + Flags flags = new Flags(); + Status status = new Status(); + responseContext.setCommonHeader(commonHeader); + responseContext.setStatus(status); + commonHeader.setFlags(flags); + return responseContext; + } + + private String convertActionNameToUrl(String action) { + String regex = "([a-z])([A-Z]+)"; + String replacement = "$1-$2"; + return action.replaceAll(regex, replacement) + .toLowerCase(); + } +} + diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestValidator.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestValidator.java new file mode 100644 index 000000000..6c287a580 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestValidator.java @@ -0,0 +1,626 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.requesthandler; + + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.openecomp.appc.domainmodel.lcm.*; +import org.openecomp.appc.executor.UnstableVNFException; +import org.openecomp.appc.lifecyclemanager.LifecycleManager; +import org.openecomp.appc.lifecyclemanager.objects.LifecycleException; +import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException; +import org.openecomp.appc.requesthandler.exceptions.*; +import org.openecomp.appc.requesthandler.impl.RequestHandlerImpl; +import org.openecomp.appc.requesthandler.impl.RequestValidatorImpl; +import org.openecomp.appc.requesthandler.objects.RequestHandlerInput; +import org.openecomp.appc.transactionrecorder.TransactionRecorder; +import org.openecomp.appc.workflow.WorkFlowManager; +import org.openecomp.appc.workflow.objects.WorkflowExistsOutput; +import org.openecomp.appc.workflow.objects.WorkflowRequest; +import org.openecomp.appc.workingstatemanager.WorkingStateManager; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicResource; +import org.openecomp.sdnc.sli.aai.AAIService; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Date; +import java.util.Map; +import java.util.UUID; + +import static junit.framework.TestCase.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Matchers.*; + + +@RunWith(PowerMockRunner.class) +@PrepareForTest( {WorkingStateManager.class,FrameworkUtil.class, TransactionRecorder.class, RequestHandlerImpl.class,RequestValidatorImpl.class, TransactionRecorder.class}) +public class TestRequestValidator { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(TestRequestHandler.class); + + private static final String TTL_FLAG= "TTL"; + + private RequestValidatorImpl requestValidator; + + AAIService aaiAdapter ; + LifecycleManager lifecyclemanager; + WorkFlowManager workflowManager; + WorkingStateManager workingStateManager ; +// AppcDAOImpl dao ; + + private final BundleContext bundleContext= Mockito.mock(BundleContext.class); + private final Bundle bundleService=Mockito.mock(Bundle.class); + private final ServiceReference sref=Mockito.mock(ServiceReference.class); + + + + @Before + public void init() throws Exception { + +// dao = Mockito.mock(AppcDAOImpl.class); +// PowerMockito.whenNew(AppcDAOImpl.class).withNoArguments().thenReturn(dao); +// Mockito.doNothing().when(dao).storeTransactionRecord((TransactionRecord)anyObject()); + // PowerMockito.when(dao.queryWorkflow(anyString(),anyString())).thenReturn(true); + + // *** + AAIService aaiService = Mockito.mock(AAIService.class);; + PowerMockito.mockStatic(FrameworkUtil.class); + PowerMockito.when(FrameworkUtil.getBundle(AAIService.class)).thenReturn(bundleService); + PowerMockito.when(bundleService.getBundleContext()).thenReturn(bundleContext); + PowerMockito.when(bundleContext.getServiceReference(AAIService.class.getName())).thenReturn(sref); + PowerMockito.when(bundleContext.getService(sref)).thenReturn(aaiService); + PowerMockito.when(aaiService.query(anyString(),anyBoolean(),anyString(),anyString(),anyString(),anyString(),(SvcLogicContext)anyObject())).thenAnswer(new Answer<SvcLogicResource.QueryStatus>() { + @Override + public SvcLogicResource.QueryStatus answer(InvocationOnMock invocation) throws Throwable { + Object[] args = invocation.getArguments(); + SvcLogicContext ctx =(SvcLogicContext)args[6]; + String prefix = (String)args[4]; + String key = (String)args[3]; + if(key.contains("'28'")){ + return SvcLogicResource.QueryStatus.FAILURE ; + }else if ( key.contains("'8'")) { + return SvcLogicResource.QueryStatus.NOT_FOUND ; + }else { + ctx.setAttribute(prefix + ".vnf-type", "FIREWALL"); + ctx.setAttribute(prefix + ".orchestration-status", "Instantiated"); + } + return SvcLogicResource.QueryStatus.SUCCESS ; + } + }); + PowerMockito.when(aaiService.update(anyString(),anyString(),(Map)anyObject(),anyString(),(SvcLogicContext)anyObject())).thenReturn(SvcLogicResource.QueryStatus.SUCCESS); + //PowerMockito.when(requestHandler.getVnfdata(anyString(), anyString(), (SvcLogicContext)anyObject())).thenReturn() + // *** + + + aaiAdapter = Mockito.mock(AAIService.class); + lifecyclemanager= Mockito.mock(LifecycleManager.class); + workflowManager= Mockito.mock(WorkFlowManager.class); + workingStateManager = Mockito.mock(WorkingStateManager.class); + + // transactionRecorder= spy(TransactionRecorder.class); + requestValidator = new RequestValidatorImpl(); +// requestValidator = Mockito.mock(RequestValidator.class); + requestValidator.setWorkflowManager(workflowManager); + requestValidator.setLifecyclemanager(lifecyclemanager); + requestValidator.setWorkingStateManager(workingStateManager); + + + /* Mockito.when(workingStateManager.isVNFStable("1")).thenReturn(true); + Mockito.when(aaiAdapter.requestGenericVnfData("1")).thenReturn(getGenericVnf("FIREWALL","INSTNATIATED"));*/ + // Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(true); + + /*PowerMockito.when(getAaiadapter().requestGenericVnfData("39")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("39")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("8")).thenThrow(new AAIAdapterException("404")); + Mockito.when(workingStateManager.isVNFStable("8")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("9")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("9")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("10")).thenReturn(getGenericVnf("WrongRouter","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("10")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("11")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("11")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("12")).thenReturn(getGenericVnf("FIREWALL","NOT_INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("12")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("13")).thenReturn(getGenericVnf("FIREWALL","TESTING")); + Mockito.when(workingStateManager.isVNFStable("13")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("14")).thenReturn(getGenericVnf("FIREWALL","REBUILDING")); + Mockito.when(workingStateManager.isVNFStable("14")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("26")).thenReturn(getGenericVnf("FIREWALL","NOT_INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("26")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("27")).thenReturn(getGenericVnf("FIREWALL","RESTARTING")); + Mockito.when(workingStateManager.isVNFStable("27")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("28")).thenThrow(new RuntimeException("AAI Down Excpetion")); + Mockito.when(workingStateManager.isVNFStable("28")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("35")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("35")).thenReturn(true);*/ + + /*for(Integer i=130; i<=140 ; i++) + { + PowerMockito.when(getAaiadapter().requestGenericVnfData(i.toString())).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable(i.toString())).thenReturn(true); + } + PowerMockito.when(getAaiadapter().requestGenericVnfData("39")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("39")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("40")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("40")).thenReturn(true).thenReturn(false); + + + PowerMockito.when(getAaiadapter().requestGenericVnfData("38")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("38")).thenReturn(true).thenReturn(false); + + + PowerMockito.when(getAaiadapter().requestGenericVnfData("201")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")).thenReturn(getGenericVnf("FIREWALL","CONFIGURED")); + Mockito.when(workingStateManager.isVNFStable("201")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("202")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")).thenReturn(getGenericVnf("FIREWALL","ERROR")); + Mockito.when(workingStateManager.isVNFStable("202")).thenReturn(true).thenReturn(false); + + PowerMockito.when(getAaiadapter().requestGenericVnfData("301")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("301")).thenReturn(true).thenReturn(false); + + PowerMockito.when(getAaiadapter().requestGenericVnfData("302")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("302")).thenReturn(true).thenReturn(true); + + PowerMockito.when(getAaiadapter().requestGenericVnfData("303")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("303")).thenReturn(true).thenReturn(true); + + PowerMockito.when(getAaiadapter().requestGenericVnfData("309")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("309")).thenReturn(true).thenReturn(true); + + PowerMockito.when(getAaiadapter().requestGenericVnfData("310")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("310")).thenReturn(true).thenReturn(true);*/ + } + public AAIService getAaiadapter() { + return this.aaiAdapter; + } +/* public GenericVnf getGenericVnf(String vnfType, String operationalState) { + GenericVnf genericVnf = new GenericVnf(); + genericVnf.setVnfType(vnfType); + // genericVnf.setOperationalState(operationalState); + genericVnf.setOrchestrationStatus(operationalState); + return genericVnf; + }*/ + private RequestHandlerInput getRequestHandlerInput(String vnfID, VNFOperation action, int ttl, boolean force, String originatorId, String requestId, String subRequestId, Date timeStamp){ + String API_VERSION= "2.0.0"; + RequestHandlerInput input = new RequestHandlerInput(); + RuntimeContext runtimeContext = createRuntimeContextWithSubObjects(); + RequestContext requestContext = runtimeContext.getRequestContext(); + input.setRequestContext(requestContext); + requestContext.getActionIdentifiers().setVnfId(vnfID); + requestContext.setAction(action); + if (action != null) { + input.setRpcName(convertActionNameToUrl(action.name())); + } + else{ + input.setRpcName(null); + } + requestContext.getCommonHeader().setRequestId(requestId); + requestContext.getCommonHeader().setSubRequestId(subRequestId); + requestContext.getCommonHeader().setOriginatorId(originatorId); + requestContext.getCommonHeader().getFlags().setTtl(ttl); + requestContext.getCommonHeader().getFlags().setForce(force); + requestContext.getCommonHeader().getTimeStamp(); + requestContext.getCommonHeader().setApiVer(API_VERSION); + requestContext.getCommonHeader().setTimestamp(timeStamp); + return input; + } + @Test + public void testNullVnfID() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testNullVnfID============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput(null, VNFOperation.Configure, 30, + false, UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(InvalidInputException e ) { + ex = e; + } +// assertEquals(new InvalidInputException("vnfID or command is null") ,ex); + assertNotNull(ex); + logger.debug("=====================testNullVnfID============================="); + } + + @Test + public void testPositiveFlowWithConfigure() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testPositiveFlowWithConfigure============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + Mockito.when(workingStateManager.isVNFStable("1")).thenReturn(true); + RequestHandlerInput input = this.getRequestHandlerInput("1", VNFOperation.Configure, 30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNull(ex); + logger.debug("testPositiveFlowWithConfigure"); + logger.debug("=====================testPositiveFlowWithConfigure============================="); + } + + @Test + public void testVnfNotFound() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testVnfNotFound============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("8", VNFOperation.Configure, 30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testVnfNotFound============================="); + } + + + + @Test + public void testNullCommand() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testNullCommand============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("7", null,30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(InvalidInputException e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testNullCommand============================="); + } + + @Test + public void testNullVnfIDAndCommand() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testNullVnfIDAndCommand============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput(null, null,30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(InvalidInputException e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testNullVnfIDAndCommand============================="); + } + + @Test + public void testWorkflowNotFound() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testWorkflowNotFound============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(false,false)); + RequestHandlerInput input = this.getRequestHandlerInput("10", VNFOperation.Configure, 30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testWorkflowNotFound============================="); + } + + @Test + public void testUnstableVnfWithConfigure() throws LifecycleException, NoTransitionDefinedException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testUnstableVnfWithConfigure============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(),anyString())).thenThrow( new NoTransitionDefinedException("","","")); + + RequestHandlerInput input = this.getRequestHandlerInput("11", VNFOperation.Configure, 30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testUnstableVnfWithConfigure============================="); + } + + @Test + public void testUnstableVnfWithTest() throws LifecycleException, NoTransitionDefinedException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testUnstableVnfWithTest============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(),anyString())).thenThrow( new NoTransitionDefinedException("","","")); + RequestHandlerInput input = this.getRequestHandlerInput("12", VNFOperation.Test,30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testUnstableVnfWithTest============================="); + } + + @Test + public void testUnstableVnfWithStart() throws LifecycleException, NoTransitionDefinedException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testUnstableVnfWithStart============================="); + Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(),anyString())).thenThrow( new NoTransitionDefinedException("","","")); + + RequestHandlerInput input = this.getRequestHandlerInput("13", VNFOperation.Start,30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testUnstableVnfWithStart============================="); + } + + @Test + public void testUnstableVnfWithTerminate() throws LifecycleException, NoTransitionDefinedException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testUnstableVnfWithTerminate============================="); + Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(),anyString())).thenThrow( new NoTransitionDefinedException("","","")); + RequestHandlerInput input = this.getRequestHandlerInput("14", VNFOperation.Terminate,30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testUnstableVnfWithTerminate============================="); + } + + @Test + public void testUnstableVnfWithRestart() throws LifecycleException, NoTransitionDefinedException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testUnstableVnfWithRestart============================="); + Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(),anyString())).thenThrow( new NoTransitionDefinedException("","","")); + + RequestHandlerInput input = this.getRequestHandlerInput("26", VNFOperation.Restart,30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testUnstableVnfWithRestart============================="); + } + + @Test + public void testUnstableVnfWithRebuild() throws LifecycleException, NoTransitionDefinedException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testUnstableVnfWithRebuild============================="); + Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(),anyString())).thenThrow( new NoTransitionDefinedException("","","")); + + // Mockito.doReturn(this.getGenericVnf("Firewall", "NOT_INSTANTIATED")).when(getAaiadapter()).requestGenericVnfData("8"); + RequestHandlerInput input = this.getRequestHandlerInput("27", VNFOperation.Rebuild,30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testUnstableVnfWithRebuild============================="); + } + + + + + @Test + public void testAAIDown() throws Exception { + logger.debug("=====================testAAIDown============================="); + // AAIAdapter aaiAdapter = Mockito.mock(AAIAdapterImpl.class); + // RequestHandler requestHandler=RequestHandlerSingleton.getRequestHandler(new WorkFlowManagerImpl(),aaiAdapter,new LifecycleManagerImpl()); + // RequestHandler requestHandler = new RequestHandlerImpl(new WorkFlowManagerImpl(),aaiAdapter,new LifecycleManagerImpl()); + RequestHandlerInput input = this.getRequestHandlerInput("28", VNFOperation.Configure, 30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testAAIDown============================="); + } + + @Test + public void testNegativeFlowWithTimeStamp() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testNegativeFlowWithTimeStamp============================="); + Date now = new Date(); + Date past = new Date(); + past.setTime(now.getTime() -1000000 ); + RequestHandlerInput input = this.getRequestHandlerInput("35", VNFOperation.Configure, 30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),past); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("testNegativeFlowWithTimeStamp"); + logger.debug("=====================testNegativeFlowWithTimeStamp============================="); + } + + + @Test + public void rejectDuplicateRequest() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + Mockito.when(workingStateManager.isVNFStable("301")).thenReturn(true); + Mockito.when(workingStateManager.isVNFStable("309")).thenReturn(true); + RequestHandlerInput input = this.getRequestHandlerInput("301", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + + RequestHandlerInput input1 = this.getRequestHandlerInput("309", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + RuntimeContext runtimeContext1 = putInputToRuntimeContext(input1); + + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNull(ex); + + try { + requestValidator.validateRequest(runtimeContext1); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + } + + @Test + public void testLockOperation() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException { + Mockito.when(workingStateManager.isVNFStable("no-matter")).thenReturn(true); + testOperation("no-matter", VNFOperation.Lock); + } + + @Test + public void testUnlockOperation() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException { + Mockito.when(workingStateManager.isVNFStable("no-matter")).thenReturn(true); + testOperation("no-matter", VNFOperation.Unlock); + } + + @Test + public void testCheckLockOperation() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException { + Mockito.when(workingStateManager.isVNFStable("no-matter")).thenReturn(true); + testOperation("no-matter", VNFOperation.CheckLock); + } + + @Test(expected = NoTransitionDefinedException.class) + public void testLockOperationNegative() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException { + Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(), eq(VNFOperation.Lock.toString()))).thenThrow(new NoTransitionDefinedException("", "", "")); + Mockito.when(workingStateManager.isVNFStable("no-matter")).thenReturn(true); + testOperation("no-matter", VNFOperation.Lock); + } + + @Test(expected = NoTransitionDefinedException.class) + public void testUnlockOperationNegative() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException { + Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(), eq(VNFOperation.Unlock.toString()))).thenThrow(new NoTransitionDefinedException("", "", "")); + Mockito.when(workingStateManager.isVNFStable("no-matter")).thenReturn(true); + testOperation("no-matter", VNFOperation.Unlock); + } + + @Test(expected = NoTransitionDefinedException.class) + public void testCheckLockOperationNegative() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException { + Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(), eq(VNFOperation.CheckLock.toString()))).thenThrow(new NoTransitionDefinedException("", "", "")); + Mockito.when(workingStateManager.isVNFStable("no-matter")).thenReturn(true); + testOperation("no-matter", VNFOperation.CheckLock); + } + + private void testOperation(String resource, VNFOperation operation) throws WorkflowNotFoundException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, InvalidInputException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, RequestExpiredException { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + + RequestHandlerInput input = this.getRequestHandlerInput(resource, operation, 0, false, originatorID, requestID, subRequestID, new Date()); + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + requestValidator.validateRequest(runtimeContext); + } + + + private RuntimeContext createRuntimeContextWithSubObjects() { + RuntimeContext runtimeContext = new RuntimeContext(); + RequestContext requestContext = new RequestContext(); + runtimeContext.setRequestContext(requestContext); + ResponseContext responseContext = createResponseContextWithSuObjects(); + runtimeContext.setResponseContext(responseContext); + CommonHeader commonHeader = new CommonHeader(); + requestContext.setCommonHeader(commonHeader); + Flags flags = new Flags(); + commonHeader.setFlags(flags); + ActionIdentifiers actionIdentifiers = new ActionIdentifiers(); + requestContext.setActionIdentifiers(actionIdentifiers); + VNFContext vnfContext = new VNFContext(); + runtimeContext.setVnfContext(vnfContext); + return runtimeContext; + + } + + private ResponseContext createResponseContextWithSuObjects(){ + ResponseContext responseContext = new ResponseContext(); + CommonHeader commonHeader = new CommonHeader(); + Flags flags = new Flags(); + Status status = new Status(); + responseContext.setCommonHeader(commonHeader); + responseContext.setStatus(status); + commonHeader.setFlags(flags); + return responseContext; + } + + private String convertActionNameToUrl(String action) { + String regex = "([a-z])([A-Z]+)"; + String replacement = "$1-$2"; + return action.replaceAll(regex, replacement) + .toLowerCase(); + } + + private RuntimeContext putInputToRuntimeContext(RequestHandlerInput input) { + RuntimeContext runtimeContext = createRuntimeContextWithSubObjects(); + runtimeContext.setRequestContext(input.getRequestContext()); + runtimeContext.setRpcName(input.getRpcName()); + runtimeContext.getVnfContext().setId(input.getRequestContext().getActionIdentifiers().getVnfId()); + //runtimeContext.getRequestContext().getActionIdentifiers().setVnfId(input.getRequestContext().getActionIdentifiers().getVnfId()); + return runtimeContext; + + //String vnfID, VNFOperation action, int ttl, boolean force, String originatorId, String requestId, String subRequestId, Date timeStamp + } +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/workingstatemanager/TestWorkingStateManager.java b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/workingstatemanager/TestWorkingStateManager.java new file mode 100644 index 000000000..33028465b --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/workingstatemanager/TestWorkingStateManager.java @@ -0,0 +1,110 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.workingstatemanager; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.dao.util.AppcJdbcConnectionFactory; +import org.openecomp.appc.workingstatemanager.impl.WorkingStateManagerImpl; +import org.openecomp.appc.workingstatemanager.objects.VNFWorkingState; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import java.util.UUID; + + + +public class TestWorkingStateManager { + private static final EELFLogger logger = EELFManager.getInstance().getLogger(TestWorkingStateManager.class); + WorkingStateManagerImpl workingStateManager; + + @Before + public void init() throws Exception { + workingStateManager = new WorkingStateManagerImpl(); + AppcJdbcConnectionFactory appcJdbcConnectionFactory = new AppcJdbcConnectionFactory(); + String schema = "sdnctl"; + appcJdbcConnectionFactory.setSchema(schema); + workingStateManager.setConnectionFactory(appcJdbcConnectionFactory); + String property = ConfigurationFactory.getConfiguration().getProperty(String.format("org.openecomp.appc.db.url.%s", schema)); + logger.info(property+" will be used as connection URL to mySQL."); + logger.warn("you can set connection URL to other IP by adding -DmysqlIp=<MYSQL_IP> in VM Option"); +// System.getProperties().getProperty("mys") + } + + @Test + // this test run on mysql you need to uncomment Ignore and to add -DmysqlIp=<MYSQL_IP> in VM Option, to make that test pass successfully. + @Ignore + public void testUpdateWorkingState() { + String vnfId = UUID.randomUUID().toString(); + String myOwnerId = "myOwnerId"; + String otherOwnerId = "otherOwnerId"; + boolean vnfStable = workingStateManager.isVNFStable(vnfId); + logger.info("isVNFStable returns "+vnfStable+" for vnfId "+vnfId); + + //set to unstable with force true + boolean updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, myOwnerId, true); + Assert.assertTrue(updated); + Assert.assertFalse(workingStateManager.isVNFStable(vnfId)); + + //negative test - try to set to any value by other ownerId when vnf state is UNSTABLE + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, otherOwnerId, false); + Assert.assertFalse(updated); + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNKNOWN, otherOwnerId, false); + Assert.assertFalse(updated); + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.STABLE, otherOwnerId, false); + Assert.assertFalse(updated); + + //positive test - set with same ownerId and force false + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, myOwnerId, false); + Assert.assertTrue(updated); + Assert.assertFalse(workingStateManager.isVNFStable(vnfId)); + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNKNOWN, myOwnerId, false); + Assert.assertTrue(updated); + Assert.assertFalse(workingStateManager.isVNFStable(vnfId)); + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.STABLE, myOwnerId, false); + Assert.assertTrue(updated); + Assert.assertTrue(workingStateManager.isVNFStable(vnfId)); + + //positive test - set with otherOwnerId and force false when VNF is stable + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNKNOWN, otherOwnerId, false); + Assert.assertTrue(updated); + Assert.assertFalse(workingStateManager.isVNFStable(vnfId)); + + //negative test - try to set to any value by myOwnerId when vnf state is UNKNOWN + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, myOwnerId, false); + Assert.assertFalse(updated); + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNKNOWN, myOwnerId, false); + Assert.assertFalse(updated); + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.STABLE, myOwnerId, false); + Assert.assertFalse(updated); + + //positive test - try to set to any value by myOwnerId when vnf state is UNKNOWN but with force + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, myOwnerId, true); + Assert.assertTrue(updated); + Assert.assertFalse(workingStateManager.isVNFStable(vnfId)); + } + + +} diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..2d75df419 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/resources/org/openecomp/appc/default.properties @@ -0,0 +1,107 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded to supply configuration options +#org.openecomp.appc.bootstrap.file=executor-test.properties +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + +# +# Certificate keystore and truststore +# +#org.openecomp.sdnc.sli.aai.ssl.trust=<jks_FILE_HERE> +#org.openecomp.sdnc.sli.aai.ssl.trust.psswd=adminadmin +#org.openecomp.sdnc.sli.aai.ssl.key=<p12_FILE_HERE> +#org.openecomp.sdnc.sli.aai.ssl.key.psswd=adminadmin +org.openecomp.sdnc.sli.aai.host.certificate.ignore=true +org.openecomp.sdnc.sli.aai.certificate.trust.all=true + +# +# Configuration file for A&AI Adapter +# + +# OPEN SOURCE - EXTERNAL A&AI INSTANCE IN TEST ENVIRONMENT +org.openecomp.sdnc.sli.aai.uri=https://10.0.1.1:8443 + +org.openecomp.sdnc.sli.aai.path.query=/aai/v8/search/sdn-zone-query + +# service instance +org.openecomp.sdnc.sli.aai.path.svcinst=/aai/v8/business/customers/customer/{customer-id}/service-subscriptions/service-subscription/{service-type}/service-instances +org.openecomp.sdnc.sli.aai.path.svcinst.query=/aai/v8/search/generic-query?key=service-instance.service-instance-id:{svc-instance-id}&start-node-type=service-instance&include=service-instance + +# complex +org.openecomp.sdnc.sli.aai.path.complexes=/aai/v8/cloud-infrastructure/complexes +org.openecomp.sdnc.sli.aai.path.complex=/aai/v8/cloud-infrastructure/complexes/complex/{physical-location-id} + +# vservers +org.openecomp.sdnc.sli.aai.path.vservers=/aai/v8/cloud-infrastructure/tenants/tenant/{tenant-id}/vservers +org.openecomp.sdnc.sli.aai.path.vserver =/aai/v8/cloud-infrastructure/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id} + +# generic-vnf +org.openecomp.sdnc.sli.aai.path.generic.vnfs=/aai/v8/network/generic-vnfs/generic-vnf/ +org.openecomp.sdnc.sli.aai.path.generic.vnf=/aai/v8/network/generic-vnfs/generic-vnf/{vnf-id} + +# +# Formatting +# +org.openecomp.sdnc.sli.aai.param.format=filter=%s:%s +org.openecomp.sdnc.sli.aai.param.vnf_type=vnf-type +org.openecomp.sdnc.sli.aai.param.physical.location.id=physical-location-id +org.openecomp.sdnc.sli.aai.param.service.type=service-type + + +org.openecomp.appc.logging.path=${user.home},etc,../etc,. +org.openecomp.appc.logging.file=logback.xml + +org.openecomp.appc.db.url.%s", schema), ""); +org.openecomp.appc.db.user.%s", schema), ""); +org.openecomp.appc.db.pass.%s", schema), ""); + + +#Property below provided by appc.properties +#dmaap.poolMembers=<DMAAP_IP>:3904 + +dmaap.topic.read=APPC-TEST2 +dmaap.topic.write=APPC-TEST2 +#dmaap.topic.read.filter={"class":"Assigned","field":"request"} +dmaap.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]} +dmaap.client.name=APPC-TEST-CLIENT-REQ-HDLR-TEST +dmaap.client.name.id=0 +#dmaap.client.key=random +#dmaap.client.secret=random + +dmaap.threads.queuesize.min=1 +dmaap.threads.queuesize.max=1000 +dmaap.threads.poolsize.min=1 +dmaap.threads.poolsize.max=2 + +# +# This needs to be changed so that the action can be appended to the end of the URL path +# +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:topology-service +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider: + +mysqlIp=127.0.0.1 +org.openecomp.appc.db.url.sdnctl=jdbc:mysql://${mysqlIp}:3306/test +org.openecomp.appc.db.user.sdnctl=test +org.openecomp.appc.db.pass.sdnctl=123456 + +org.openecomp.appc.workingstatemanager.maxAttempts=2 diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-features/.gitignore b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-features/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-features/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-features/pom.xml b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-features/pom.xml new file mode 100644 index 000000000..453a8e62f --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-features/pom.xml @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-request-handler</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <name>appc-request-handler-features</name> + <artifactId>appc-request-handler-features</artifactId> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-request-handler-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-request-handler-core</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <!--<plugin> + <!– launches the feature test, which validates that your karaf feature + can be installed inside of a karaf container. It doesn't validate that your + functionality works correctly, just that you have all of the dependent bundles + defined correctly. –> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.16</version> + <configuration> + <systemPropertyVariables> + <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId> + <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId> + <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version> + </systemPropertyVariables> + <dependenciesToScan> + <dependency>org.opendaylight.yangtools:features-test</dependency> + </dependenciesToScan> + <classpathDependencyExcludes> + <!– The dependencies which bring in AbstractDataBrokerTest class + brings in a second PaxExam container which results in the feature tests failing + with a message similar to: "ERROR o.ops4j.pax.exam.spi.PaxExamRuntime - Ambiguous + TestContainer ..." This excludes the container we don't want to use. –> + <classpathDependencyExcludes>org.ops4j.pax.exam:pax-exam-container-native</classpathDependencyExcludes> + </classpathDependencyExcludes> + </configuration> + </plugin>--> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + + <!-- Skipping ODL feature test --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <skipTests>true</skipTests> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-features/src/main/resources/features.xml b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-features/src/main/resources/features.xml new file mode 100644 index 000000000..cc8fe1192 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/appc-request-handler-features/src/main/resources/features.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="appc-request-handler-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + + <feature name='appc-request-handler' description="appc-request-handler" version='${project.version}'> + <bundle>mvn:org.openecomp.appc/transaction-recorder/${project.version}</bundle> + <bundle dependency="true">mvn:org.openecomp.appc/domain-model-lib/${project.version}</bundle> + <bundle start-level="75" start="true">mvn:org.openecomp.appc/appc-command-executor-api/${project.version}</bundle> + <bundle start-level="80" start="true">mvn:org.openecomp.appc/appc-request-handler-api/${project.version}</bundle> + <bundle start-level="85" start="true">mvn:org.openecomp.appc/appc-request-handler-core/${project.version}</bundle> + </feature> + +</features> diff --git a/app-c/appc/appc-dispatcher/appc-request-handler/pom.xml b/app-c/appc/appc-dispatcher/appc-request-handler/pom.xml new file mode 100644 index 000000000..9f06a54dd --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-request-handler/pom.xml @@ -0,0 +1,22 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-request-handler</artifactId> + <packaging>pom</packaging> + <name>APPC Request Handler</name> + <description>APPC Request Handler</description> + + <!-- ================================================================================== --> + <!-- The modules we build --> + <!-- ================================================================================== --> + <modules> + <module>appc-request-handler-api</module> + <module>appc-request-handler-core</module> + <module>appc-request-handler-features</module> + </modules> + +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/.gitignore b/app-c/appc/appc-dispatcher/appc-workflow-management/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-workflow-management/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/.gitignore b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/pom.xml b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/pom.xml new file mode 100644 index 000000000..afd545501 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/pom.xml @@ -0,0 +1,48 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-workflow-management</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-workflow-management-api</artifactId> + <packaging>bundle</packaging> + + <name>appc-workflow-management-api</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-data-access-lib</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>domain-model-lib</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Export-Package>org.openecomp.appc.dao.objects,org.openecomp.appc.workflow,org.openecomp.appc.workflow.helper,org.openecomp.appc.workflow.objects</Export-Package> + <!--<Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic,appc-data-access-lib,javax.json;scope=compile|runtime;inline=false</Embed-Dependency>--> + <!--<Embed-Transitive>true</Embed-Transitive>--> + <!--<Import-Package>!groovy.lang,!javax.*,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package>--> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/WorkFlowManager.java b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/WorkFlowManager.java new file mode 100644 index 000000000..abcebb6c6 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/WorkFlowManager.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.workflow; + +import org.openecomp.appc.workflow.objects.WorkflowExistsOutput; +import org.openecomp.appc.workflow.objects.WorkflowRequest; +import org.openecomp.appc.workflow.objects.WorkflowResponse; + +public interface WorkFlowManager { + /** + * Execute workflow and return response. + * This method execute workflow with following steps. + * Retrieve workflow(DG) details - module, version and mode from database based on command and vnf Type from incoming request. + * Execute workflow (DG) using SVC Logic Service reference + * Return response of workflow (DG) to caller. + * @param workflowRequest workflow execution request which contains vnfType, command, requestId, targetId, payload and (optional) confID; + * @return Workflow Response which contains execution status and payload from DG if any + */ + WorkflowResponse executeWorkflow(WorkflowRequest workflowRequest); + + /** + * Check if workflow (DG) exists in database + * @param workflowQueryParams workflow request with command and vnf Type + * @return WorkflowExistsOutput.mappingExist True if workflow mapping exists else False. WorkflowExistsOutput.dgExist True if DG workflow exists else False. + */ + WorkflowExistsOutput workflowExists(WorkflowRequest workflowQueryParams); + +} diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowExistsOutput.java b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowExistsOutput.java new file mode 100644 index 000000000..a88fe1e61 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowExistsOutput.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.workflow.objects; + +public class WorkflowExistsOutput { + + private boolean mappingExist ; + private boolean dgExist; + private String workflowModule; + private String workflowName; + private String workflowVersion; + + + public WorkflowExistsOutput() { + } + + public WorkflowExistsOutput(boolean mappingExist, boolean dgExist) { + this.mappingExist = mappingExist; + this.dgExist = dgExist; + } + + public boolean isMappingExist() { + return mappingExist; + } + + public void setMappingExist(boolean mappingExist) { + this.mappingExist = mappingExist; + } + + public boolean isDgExist() { + return dgExist; + } + + public void setDgExist(boolean dgExist) { + this.dgExist = dgExist; + } + + public String getWorkflowName() { + return workflowName; + } + + public void setWorkflowName(String workflowName) { + this.workflowName = workflowName; + } + + public String getWorkflowVersion() { + return workflowVersion; + } + + public void setWorkflowVersion(String workflowVersion) { + this.workflowVersion = workflowVersion; + } + + public String getWorkflowModule() { + return workflowModule; + } + + public void setWorkflowModule(String workflowModule) { + this.workflowModule = workflowModule; + } + public boolean exists(){ + return mappingExist && dgExist; + } + + @Override + public String toString() { + return "WorkflowExistsOutput{" + + "mappingExist=" + mappingExist + + ", dgExist=" + dgExist + + ", workflowModule='" + workflowModule + '\'' + + ", workflowName='" + workflowName + '\'' + + ", workflowVersion='" + workflowVersion + '\'' + + '}'; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowRequest.java b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowRequest.java new file mode 100644 index 000000000..97e5f81bc --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowRequest.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.workflow.objects; + +import org.openecomp.appc.domainmodel.lcm.RequestContext; +import org.openecomp.appc.domainmodel.lcm.ResponseContext; +import org.openecomp.appc.domainmodel.lcm.VNFContext; + + +public class WorkflowRequest { + + private RequestContext requestContext; + private ResponseContext responseContext; + private VNFContext vnfContext; + + public RequestContext getRequestContext() { + return requestContext; + } + + public void setRequestContext(RequestContext requestContext) { + this.requestContext = requestContext; + } + + public ResponseContext getResponseContext() { + return responseContext; + } + + public void setResponseContext(ResponseContext responseContext) { + this.responseContext = responseContext; + } + + public VNFContext getVnfContext() { + return vnfContext; + } + + public void setVnfContext(VNFContext vnfContext) { + this.vnfContext = vnfContext; + } + + @Override + public String toString() { + return "WorkflowRequest{" + + "requestContext=" + requestContext + + ", responseContext=" + responseContext + + ", vnfContext=" + vnfContext + + '}'; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowResponse.java b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowResponse.java new file mode 100644 index 000000000..f9584b91f --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowResponse.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.workflow.objects; + +import java.util.Properties; + +import org.openecomp.appc.domainmodel.lcm.ResponseContext; + + +public class WorkflowResponse { + + private ResponseContext responseContext; + + public ResponseContext getResponseContext() { + return responseContext; + } + + public void setResponseContext(ResponseContext responseContext) { + this.responseContext = responseContext; + } + + @Override + public String toString() { + return "WorkflowResponse{" + + "responseContext=" + responseContext + + '}'; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/.gitignore b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/pom.xml b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/pom.xml new file mode 100644 index 000000000..e13b6e5b9 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/pom.xml @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + + <!-- + + 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. + --> + + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-workflow-management</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-workflow-management-core</artifactId> + <packaging>bundle</packaging> + + <name>appc-workflow-management-core Bundle</name> + <description>appc-workflow-management-core OSGi bundle project.</description> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-data-access-lib</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-workflow-management-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-ranking-framework-lib</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic,appc-data-access-lib,javax.json;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Export-Service>org.openecomp.appc.workflow.WorkFlowManager</Export-Service> + <Import-Package>org.openecomp.appc.workflow,org.openecomp.appc.workflow.objects,!groovy.lang,!javax.*,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/common/constant/Constants.java b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/common/constant/Constants.java new file mode 100644 index 000000000..9ca021790 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/common/constant/Constants.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.common.constant; + +public class Constants { + + public static final String DG_ATTRIBUTE_STATUS = "SvcLogic.status"; + public static final String DG_STATUS_SUCCESS = "success"; + public static final String DG_ATTRIBUTE_STATUS_CODE = "SvcLogic.status.code"; + public static final String DG_OUTPUT_STATUS_CODE = "output.status.code"; + public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; + + + /** + * The name of the property that contains the VM id value in the graph's context + */ + public static final String VF_ID = "org.openecomp.appc.vfid"; + + /** + * The name of the property that contains the VF Type value in the graph's context + */ + public static final String VF_TYPE = "org.openecomp.appc.vftype"; + + /** + * The name of the property that contains the service request id value in the graph's context + */ + public static final String REQUEST_ID = "org.openecomp.appc.reqid"; + + /** + * The name of the property that indicates which method of the IaaS adapter to call + */ + public static final String ACTION = "org.openecomp.appc.action"; + + public static final String PAYLOAD = "payload"; + + public static final String CONF_ID = "org.openecomp.appc.confid"; + + public static final String API_VERSION = "org.openecomp.appc.apiversion"; + + public static final String ORIGINATOR_ID = "org.openecomp.appc.originatorid"; + + public static final String OBJECT_ID ="org.openecomp.appc.objectid"; + + public static final String SUB_REQUEST_ID = "org.openecomp.appc.subrequestid"; + + public static final String ERROR_MESSAGE = "error-message"; + +} diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkFlowManagerImpl.java b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkFlowManagerImpl.java new file mode 100644 index 000000000..6b197ef19 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkFlowManagerImpl.java @@ -0,0 +1,343 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.workflow.impl; + +import java.text.SimpleDateFormat; +import java.util.Enumeration; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.lang.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.openecomp.appc.common.constant.Constants; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.domainmodel.lcm.RequestContext; +import org.openecomp.appc.domainmodel.lcm.ResponseContext; +import org.openecomp.appc.util.ObjectMapper; +import org.openecomp.appc.workflow.WorkFlowManager; +import org.openecomp.appc.workflow.objects.WorkflowExistsOutput; +import org.openecomp.appc.workflow.objects.WorkflowRequest; +import org.openecomp.appc.workflow.objects.WorkflowResponse; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.SvcLogicException; +import org.openecomp.sdnc.sli.provider.SvcLogicService; + + +public class WorkFlowManagerImpl implements WorkFlowManager{ + private SvcLogicService svcLogic = null; + private static final EELFLogger logger = EELFManager.getInstance().getLogger(WorkFlowManagerImpl.class); + private static final Configuration configuration = ConfigurationFactory.getConfiguration(); + + private final WorkflowResolver workflowResolver = new WorkflowResolver( + configuration.getIntegerProperty("org.openecomp.appc.workflow.resolver.refresh_interval", 300) + ); + + public void setSvcLogicServiceRef(SvcLogicService svcLogic) { + this.svcLogic = svcLogic; + } + + /** + * Execute workflow and return response. + * This method execute workflow with following steps. + * Retrieve workflow(DG) details - module, version and mode from database based on command and vnf Type from incoming request. + * Execute workflow (DG) using SVC Logic Service reference + * Return response of workflow (DG) to caller. + * + * @param workflowRequest workflow execution request which contains vnfType, command, requestId, targetId, payload and (optional) confID; + * @return Workflow Response which contains execution status and payload from DG if any + */ + + @Override + public WorkflowResponse executeWorkflow(WorkflowRequest workflowRequest) { + if (logger.isTraceEnabled()) { + logger.trace("Entering to executeWorkflow with WorkflowRequest = "+ ObjectUtils.toString(workflowRequest.toString())); + } + WorkflowResponse workflowResponse = new WorkflowResponse(); + workflowResponse.setResponseContext(workflowRequest.getResponseContext()); + + try { + + + WorkflowKey workflowKey = workflowResolver.resolve(workflowRequest.getRequestContext().getAction().name(), workflowRequest.getVnfContext().getType(), null,workflowRequest.getRequestContext().getCommonHeader().getApiVer()); + + Properties workflowParams = new Properties(); + String actionProperty = null; + String requestIdProperty=null; + String vfIdProperty =null; + if(!workflowRequest.getRequestContext().getCommonHeader().getApiVer().startsWith("1.")){ + /* + The following method call (populateDGContext) populates DG context with the + request parameters to maintain backward compatibility with old DGs, + we are not altering the old way of passing (org.openecomp.appc.vnfId and so on..) + This is still a temporary solution, the end solution should be agreed with + all stakeholders and implemented. + */ + populateDGContext(workflowParams,workflowRequest); + } else { + actionProperty = configuration.getProperty("org.openecomp.appc.workflow.action", String.valueOf(Constants.ACTION)); + requestIdProperty = configuration.getProperty("org.openecomp.appc.workflow.request.id", String.valueOf(Constants.REQUEST_ID)); + vfIdProperty = configuration.getProperty("org.openecomp.appc.workflow.vfid", String.valueOf(Constants.VF_ID)); + String payloadProperty = configuration.getProperty("org.openecomp.appc.workflow.payload", String.valueOf(Constants.PAYLOAD)); + String vfTypeProperty = configuration.getProperty("org.openecomp.appc.workflow.vftype", String.valueOf(Constants.VF_TYPE)); + String apiVerProperty = configuration.getProperty("org.openecomp.appc.workflow.apiVersion", String.valueOf(Constants.API_VERSION)); + String originatorIdProperty = configuration.getProperty("org.openecomp.appc.workflow.originatorId",Constants.ORIGINATOR_ID); + String subRequestId = configuration.getProperty("org.openecomp.appc.workflow.subRequestId",Constants.SUB_REQUEST_ID); + + workflowParams.put(actionProperty,workflowRequest.getRequestContext().getAction().name()); + workflowParams.put(requestIdProperty, workflowRequest.getRequestContext().getCommonHeader().getRequestId()); + workflowParams.put(vfIdProperty, workflowRequest.getVnfContext().getId()); + workflowParams.put(vfTypeProperty,workflowRequest.getVnfContext().getType()); + workflowParams.put(apiVerProperty,workflowRequest.getRequestContext().getCommonHeader().getApiVer()); + workflowParams.put(originatorIdProperty,workflowRequest.getRequestContext().getCommonHeader().getOriginatorId()); + workflowParams.put(subRequestId,workflowRequest.getRequestContext().getCommonHeader().getSubRequestId()); + + Object payloadJson = workflowRequest.getRequestContext().getPayload(); + if(payloadJson!=null) { + try { + Map<String, String> payloadProperties = ObjectMapper.map(payloadJson); + workflowParams.putAll(payloadProperties); + + if (logger.isDebugEnabled()) { + logger.debug("DG properties: " + workflowParams); + } + } catch (Exception e) { + logger.error("Error parsing payload json string", e); + Properties workflowPrp = new Properties(); + workflowPrp.setProperty("error-message", "Error parsing payload json string"); + fillStatus(501, "Error parsing payload json string: "+e.getMessage(), workflowRequest.getResponseContext()); + if (logger.isTraceEnabled()) { + logger.trace("Exiting from executeWorkflow with (workflowResponse = "+ObjectUtils.toString(workflowResponse)+")"); + } + return workflowResponse; + } + } + if (logger.isDebugEnabled()) { + logger.debug("DG parameters "+ actionProperty +":"+ workflowRequest.getRequestContext().getAction().name()+", "+ + requestIdProperty +":"+ workflowRequest.getRequestContext().getCommonHeader().getRequestId()+", "+ + vfIdProperty +":"+ workflowRequest.getVnfContext().getId()); + + logger.debug("Starting DG Execution for request "+workflowRequest.getRequestContext().getCommonHeader().getRequestId()); + } + } + if (workflowRequest.getRequestContext().getCommonHeader().getApiVer().startsWith("1.")){ + workflowParams.put("isBwcMode","true"); + } else { + workflowParams.put("isBwcMode", "false"); + } + + SVCLogicServiceExecute(workflowKey, workflowRequest.getRequestContext(), workflowParams , workflowResponse); + if (logger.isTraceEnabled()) { + logger.trace("Completed DG Execution for Request id: " + workflowRequest.getRequestContext().getCommonHeader().getRequestId() + "with response code: " + workflowResponse.getResponseContext().getStatus().getCode()); + } + }catch (Exception e){ + logger.error("Error Executing DG " +e.getMessage()); + fillStatus(501, "Error Executing DG "+e.getMessage(), workflowRequest.getResponseContext()); + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting from executeWorkflow with (workflowResponse = "+ ObjectUtils.toString(workflowResponse.getResponseContext().getStatus().getMessage())+")"); + } + return workflowResponse; + } + + private void populateDGContext(Properties workflowParams, WorkflowRequest workflowRequest) { + workflowParams.put("input.common-header.timestamp",new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").format(workflowRequest.getRequestContext().getCommonHeader().getTimeStamp())); + workflowParams.put("input.common-header.api-ver",workflowRequest.getRequestContext().getCommonHeader().getApiVer()); + workflowParams.put("input.common-header.request-id",workflowRequest.getRequestContext().getCommonHeader().getRequestId()); + workflowParams.put("input.common-header.originator-id",workflowRequest.getRequestContext().getCommonHeader().getOriginatorId()); + workflowParams.put("input.common-header.sub-request-id",workflowRequest.getRequestContext().getCommonHeader().getSubRequestId()); + workflowParams.put("input.action",workflowRequest.getRequestContext().getAction().toString()); + workflowParams.put("input.payload",null != workflowRequest.getRequestContext().getPayload() ? workflowRequest.getRequestContext().getPayload() : ""); + workflowParams.put("input.action-identifiers.vnf-id",workflowRequest.getVnfContext().getId()); + workflowParams.put("input.action-identifiers.vnfc-name",workflowRequest.getRequestContext().getActionIdentifiers().getVnfcName()!=null?workflowRequest.getRequestContext().getActionIdentifiers().getVnfcName():""); + workflowParams.put("input.action-identifiers.service-instance-id",workflowRequest.getRequestContext().getActionIdentifiers().getServiceInstanceId()!=null?workflowRequest.getRequestContext().getActionIdentifiers().getServiceInstanceId():""); + workflowParams.put("input.action-identifiers.vserver-id",workflowRequest.getRequestContext().getActionIdentifiers().getVserverId()!=null?workflowRequest.getRequestContext().getActionIdentifiers().getVserverId():""); + final Map<String, String> additionalContext; + if ((additionalContext = workflowRequest.getRequestContext().getAdditionalContext())!=null) { + for (Map.Entry<String, String> entry : additionalContext.entrySet()) { + workflowParams.put("input." + entry.getKey(), null != entry.getValue() ? entry.getValue() : ""); + } + } + } + + /** + * Check if workflow (DG) exists in database + * + * @param workflowQueryParams workflow request with command and vnf Type + * @return True if workflow exists else False. + */ + @Override + public WorkflowExistsOutput workflowExists(WorkflowRequest workflowQueryParams) { + WorkflowExistsOutput workflowExistsOutput = new WorkflowExistsOutput(false,false); + if (logger.isTraceEnabled()) { + logger.trace("Entering to workflowExists with WorkflowRequest = "+ObjectUtils.toString(workflowQueryParams.toString())); + } + + try { + WorkflowKey workflowKey = workflowResolver.resolve( + workflowQueryParams.getRequestContext().getAction().name(), + workflowQueryParams.getVnfContext().getType(), + workflowQueryParams.getVnfContext().getVersion(), + workflowQueryParams.getRequestContext().getCommonHeader().getApiVer()); + if (workflowKey != null) { + workflowExistsOutput.setMappingExist(true); + workflowExistsOutput.setWorkflowModule(workflowKey.module()); + workflowExistsOutput.setWorkflowName(workflowKey.name()); + workflowExistsOutput.setWorkflowVersion(workflowKey.version()); + if (isDGExists(workflowKey)) { + workflowExistsOutput.setDgExist(true); + }else{ + logger.warn( + String.format("SLI doesn't have DG for resolved mapping entry: DG module - '%s', DG name - '%s', DG version - '%s'", + workflowKey.module(), workflowKey.name(), workflowKey.version())); + } + }else{ + logger.warn( + String.format("Unable to resolve recipe matching action '%s', VNF type '%s' and VNF version '%s'", + workflowQueryParams.getRequestContext().getAction().name(), workflowQueryParams.getVnfContext().getType(), null)); + } + } catch (RuntimeException e) { + logger.error("Error querying workflow from database"+e.getMessage()); + throw e; + }catch (SvcLogicException e) { + logger.error("Error querying workflow from database"+e.getMessage()); + throw new RuntimeException(e); + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting workflowExists"); + } + return workflowExistsOutput; + } + + + private boolean isDGExists(WorkflowKey workflowKey) throws SvcLogicException { + return svcLogic.hasGraph(workflowKey.module(), workflowKey.name(), workflowKey.version(), "sync"); + } + + private void SVCLogicServiceExecute(WorkflowKey workflowKey, RequestContext requestContext, Properties workflowParams, WorkflowResponse workflowResponse) { + if (logger.isTraceEnabled()) { + logger.trace("Entering SVCLogicServiceExecute"); + } + + Properties respProps = null; + + try { + respProps = svcLogic.execute(workflowKey.module(), workflowKey.name(), workflowKey.version(), "sync", workflowParams); + } catch (Exception e) { + setWorkFlowResponseStatus(workflowResponse.getResponseContext(), "failure", "Unexpected SLI Adapter failure", 200); + + if (logger.isDebugEnabled()) { + logger.debug("Error while executing DG " + e.getMessage() + e.getStackTrace()); + } + logger.error("Error in DG", e.getMessage()+e.getStackTrace().toString()); + } + + if (respProps != null) { + if (!requestContext.getCommonHeader().getApiVer().startsWith("1.")) { + fillResponseContextByOutputFieldsFromDgContext(workflowResponse.getResponseContext(), respProps); + } + + final String commonStatus = respProps.getProperty(Constants.DG_ATTRIBUTE_STATUS); + final String specificStatusMessage = respProps.getProperty(Constants.DG_OUTPUT_STATUS_MESSAGE); + String dgOutputStatusCode = respProps.getProperty(Constants.DG_OUTPUT_STATUS_CODE); + int specificStatusCode = 0; + if (dgOutputStatusCode != null) { + specificStatusCode = Integer.parseInt(dgOutputStatusCode); + } + + setWorkFlowResponseStatus(workflowResponse.getResponseContext(), commonStatus, specificStatusMessage, specificStatusCode); + + if (logger.isDebugEnabled()) { + logger.debug("DG Execution Status: " + commonStatus); + } + } + + if (logger.isTraceEnabled()) { + logger.trace("Exiting from SVCLogicServiceExecute"); + } + } + + /** + * Filling response context by output.* fields from DG context. Works only for 2.* API version + * + * @param responseContext response context which you need to fill + * @param respProps DG context in a properties format + */ + private void fillResponseContextByOutputFieldsFromDgContext(ResponseContext responseContext, Properties respProps) { + + Enumeration<?> e = respProps.propertyNames(); + while (e.hasMoreElements()){ + String key = (String) e.nextElement(); + if (key.startsWith("output.")){ + if (!key.startsWith("output.common-header.") && !key.startsWith("output.status.")){ + + if (key.equalsIgnoreCase("output.payload")){ + responseContext.setPayload(respProps.getProperty(key)); + } else { + responseContext.addKeyValueToAdditionalContext(key, respProps.getProperty(key)); + } + } + } + } + } + + /** + * Filling responceContext status code amd message according to responce messages and codes from DG. + * + * @param responseContext response cotext + * @param commonStatus common status message from DG ("success" or "failure") + * @param specificStatusMessage specific status message from specific DG node + * @param specificStatusCode specific status code from specific DG node + */ + private void setWorkFlowResponseStatus(ResponseContext responseContext, String commonStatus, String specificStatusMessage, int specificStatusCode) { + if (null == specificStatusMessage) { specificStatusMessage = ""; } + if (commonStatus.equalsIgnoreCase(Constants.DG_STATUS_SUCCESS)){ + if (specificStatusCode != 0 ){ + fillStatus(specificStatusCode, specificStatusMessage, responseContext); + } else { + fillStatus(400, commonStatus, responseContext); + } + } else { + String errorMsg = StringUtils.isEmpty(specificStatusMessage) ? "DG execution failure" : specificStatusMessage; + if (specificStatusCode != 0){ + fillStatus(specificStatusCode, specificStatusMessage, responseContext); + } else { + fillStatus(401, specificStatusMessage, responseContext); + } + } + } + + /** + * filling responseContext by status code and status message + * + * @param code 3-digit status code + * @param message explanation of a status code + * @param responceContext response context which will be store status code and status message + */ + private void fillStatus(int code, String message, ResponseContext responceContext) { + responceContext.getStatus().setCode(code); + responceContext.getStatus().setMessage(message); + } + + +} diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowKey.java b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowKey.java new file mode 100644 index 000000000..b0f68f8c6 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowKey.java @@ -0,0 +1,59 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.workflow.impl; + +class WorkflowKey { + private final String name; + private final String version; + private final String module; + + WorkflowKey(String name, String version, String module) { + this.name = name; + this.version = version; + this.module = module; + } + + String name() { + return name; + } + + String version() { + return version; + } + + String module() { + return module; + } + + @Override + public String toString() { + StringBuilder buff = new StringBuilder(128); + buff.append("{"); + buff.append("module = ").append(module); + buff.append(", "); + buff.append("name = ").append(name); + buff.append(", "); + buff.append("version = ").append(version); + buff.append("}"); + return buff.toString(); + } +} diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowResolver.java b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowResolver.java new file mode 100644 index 000000000..1c8fb5738 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowResolver.java @@ -0,0 +1,139 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.workflow.impl; + +import java.util.concurrent.locks.ReentrantLock; + +import org.openecomp.appc.rankingframework.RankedAttributesContext; +import org.openecomp.appc.rankingframework.RankedAttributesResolver; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +class WorkflowResolver { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(WorkFlowManagerImpl.class); + + private long interval; + + private volatile long lastUpdate = 0l; + private volatile boolean isUpdateInProgress = false; + private volatile RankedAttributesResolver<WorkflowKey> dgResolver; + + private final ReentrantLock INIT_LOCK = new ReentrantLock(); + + WorkflowResolver(int interval) { + this.interval = interval * 1000; + } + + private RankedAttributesResolver<WorkflowKey> createResolver() { + WorkflowResolverDataReader reader = new WorkflowResolverDataReader(); + return reader.read(); + } + + private boolean isExpired() { + return (System.currentTimeMillis() - lastUpdate) > interval; + } + + private RankedAttributesResolver<WorkflowKey> resolver() { + + /* + * In general case, the method implementation is non-blocking. The first + * thread that identifies data expiration will be used to refresh it. In + * meanwhile, any other thread will get the old instance without waiting + * for the updated one. The only exception is the very first time when + * previous instance doesn't exist - in such a cases all the threads + * will be waiting on INIT_LOCK while one of them initializes the + * resolver instance. NOTE: The initialization is intentionally + * implemented in lazy manner to make sure the bundle is initialized + * properly on startup regardless whether or not the data is correct. + * Afterwards, the resolver may be instantiated as many times as needed. + */ + + try { + + if (dgResolver == null) { + INIT_LOCK.lock(); + if (dgResolver != null) { + INIT_LOCK.unlock(); + } + } + + if (!isUpdateInProgress && isExpired()) { + + boolean doUpgrade = false; + + synchronized (this) { + if (!isUpdateInProgress) { + isUpdateInProgress = true; + doUpgrade = true; + } + } + + if (doUpgrade) { + + logger.info("DG resolver configuration data has expired - initiating refresh"); + + try { + RankedAttributesResolver<WorkflowKey> temp = createResolver(); + dgResolver = temp; + lastUpdate = System.currentTimeMillis(); + + logger.info("DG resolver configuration data has been refreshed successfully"); + } finally { + isUpdateInProgress = false; + } + } + } + } finally { + if (INIT_LOCK.isHeldByCurrentThread()) { + INIT_LOCK.unlock(); + } + } + + return dgResolver; + } + + WorkflowKey resolve(final String action, final String vnfType, final String vnfVersion,final String apiVersion) { + + RankedAttributesContext context = new RankedAttributesContext() { + @Override + public Object getAttributeValue(String name) { + switch (name) { + case "action": + return action; + case "api_version": + return apiVersion; + case "vnf_type": + return vnfType; + case "vnf_version": + return vnfVersion; + default: + throw new IllegalStateException(name); + } + } + }; + + WorkflowKey wfKey = resolver().resolve(context); + + return wfKey; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowResolverDataReader.java b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowResolverDataReader.java new file mode 100644 index 000000000..3ffeddcdf --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowResolverDataReader.java @@ -0,0 +1,128 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.workflow.impl; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; + +import org.openecomp.appc.dao.util.DBUtils; +import org.openecomp.appc.rankingframework.AbstractRankedAttributesResolverFactory; +import org.openecomp.appc.rankingframework.ConfigurationEntry; +import org.openecomp.appc.rankingframework.ConfigurationSet; +import org.openecomp.appc.rankingframework.RankedAttributesResolver; + +class WorkflowResolverDataReader { + + private static final String QUERY_STMT = "SELECT action,api_version,vnf_type,vnf_version,dg_name,dg_version,dg_module FROM VNF_DG_MAPPING"; + + private static final Collection<String> ATTRIBUTE_NAMES = Arrays.asList("action","api_version", "vnf_type", "vnf_version"); + + private static class ConfigurationSetAdaptor implements ConfigurationSet<WorkflowKey> { + + private final ResultSet resultSet; + + private class ResultSetIterator implements Iterator<ConfigurationEntry<WorkflowKey>>, ConfigurationEntry<WorkflowKey> { + @Override + public boolean hasNext() { + try { + return resultSet.next(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + + @Override + public ConfigurationEntry<WorkflowKey> next() { + return this; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public Object getAttributeValue(String name) { + try { + return resultSet.getObject(name); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + + @Override + public WorkflowKey getResult() { + try { + return new WorkflowKey(resultSet.getString("dg_name"), resultSet.getString("dg_version"), resultSet.getString("dg_module")); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + } + + ConfigurationSetAdaptor(ResultSet resultSet) { + this.resultSet = resultSet; + } + + @Override + public Iterable<ConfigurationEntry<WorkflowKey>> getEntries() { + return new Iterable<ConfigurationEntry<WorkflowKey>>() { + + @Override + public Iterator<ConfigurationEntry<WorkflowKey>> iterator() { + return new ResultSetIterator(); + } + }; + } + + @Override + public Collection<String> getRankedAttributeNames() { + return ATTRIBUTE_NAMES; + } + } + + RankedAttributesResolver<WorkflowKey> read() { + try { + try (Connection conn = DBUtils.getConnection("sdnctl")) { + try (PreparedStatement stmt = conn.prepareStatement(QUERY_STMT)) { + try (ResultSet res = stmt.executeQuery()) { + if (res.next()) { + res.beforeFirst(); + ConfigurationSet<WorkflowKey> resolverConfig = new ConfigurationSetAdaptor(res); + return AbstractRankedAttributesResolverFactory.getInstance().create(resolverConfig); + } else { + // TODO: Return empty object + throw new IllegalStateException(); + } + } + } + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..a03984a38 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + + <reference id="svcLogicServiceRef" availability="mandatory" activation="eager" interface="org.openecomp.sdnc.sli.provider.SvcLogicService" /> + + <bean id="workflowManagementBean" class="org.openecomp.appc.workflow.impl.WorkFlowManagerImpl" scope="singleton"> + <property name="svcLogicServiceRef" ref="svcLogicServiceRef" /> + </bean> + + <service id="workflowManagementService" interface="org.openecomp.appc.workflow.WorkFlowManager" ref="workflowManagementBean" /> + +</blueprint> diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..44745d049 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,52 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + + +#Property below provided by appc.properties +#dmaap.poolMembers=<DMAAP_IP>:3904 + +dmaap.topic.read=APPC-TEST2 +dmaap.topic.write=APPC-TEST2 +#dmaap.topic.read.filter={"class":"Assigned","field":"request"} +dmaap.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]} +dmaap.client.name=APPC-TEST-CLIENT-WF-MGMT-MAIN +dmaap.client.name.id=0 +#dmaap.client.key=random +#dmaap.client.secret=random + +dmaap.threads.queuesize.min=1 +dmaap.threads.queuesize.max=1000 +dmaap.threads.poolsize.min=1 +dmaap.threads.poolsize.max=2 + +# Tolerance interval (in seconds) between invalidation of DG resolver configuration +org.openecomp.appc.workflow.resolver.refresh_interval=300 + +# +# This needs to be changed so that the action can be appended to the end of the URL path +# +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:topology-service +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider: diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/test/java/org/openecomp/appc/workflow/TestWorkFlowManager.java b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/test/java/org/openecomp/appc/workflow/TestWorkFlowManager.java new file mode 100644 index 000000000..0a4b0de76 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/test/java/org/openecomp/appc/workflow/TestWorkFlowManager.java @@ -0,0 +1,186 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.workflow; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.openecomp.appc.workflow.impl.WorkFlowManagerImpl; +import org.openecomp.appc.workflow.objects.WorkflowRequest; +import org.openecomp.sdnc.sli.SvcLogicException; +import org.openecomp.sdnc.sli.SvcLogicGraph; +import org.openecomp.sdnc.sli.SvcLogicNode; +import org.openecomp.sdnc.sli.SvcLogicStore; +import org.openecomp.sdnc.sli.provider.SvcLogicActivator; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@PrepareForTest( {SvcLogicActivator.class, FrameworkUtil.class, WorkFlowManagerImpl.class} ) +public class TestWorkFlowManager { + public TestWorkFlowManager() { + } + + private WorkFlowManagerImpl workflowManger ; + private String command="Configure"; + protected SvcLogicGraph svcLogicGraph=null; + + + // + private final SvcLogicStore svcLogicStore= Mockito.mock(SvcLogicStore.class); + private final BundleContext bundleContext=Mockito.mock(BundleContext.class); + private final Bundle bundleSvcLogicService=Mockito.mock(Bundle.class); + private final ServiceReference serviceReferenceSvcLogicService=Mockito.mock(ServiceReference.class); + + + + @Before + public void setupMock() throws Exception { + /* + // DAO Mock + dao = Mockito.mock(AppcDAOImpl.class); + PowerMockito.whenNew(AppcDAOImpl.class).withNoArguments().thenReturn(dao); + + // SVC Logic Mock + SvcLogicServiceImpl svcLogicService=new SvcLogicServiceImpl(); + PowerMockito.mockStatic(SvcLogicActivator.class); + PowerMockito.mockStatic(FrameworkUtil.class); + PowerMockito.when(SvcLogicActivator.getStore()).thenReturn(svcLogicStore); + PowerMockito.when(FrameworkUtil.getBundle(SvcLogicService.class)).thenReturn(bundleSvcLogicService); + PowerMockito.when(bundleSvcLogicService.getBundleContext()).thenReturn(bundleContext); + PowerMockito.when(bundleContext.getServiceReference(SvcLogicService.NAME)).thenReturn(serviceReferenceSvcLogicService); + PowerMockito.when(bundleContext.getService(serviceReferenceSvcLogicService)).thenReturn(svcLogicService); + + try { + PowerMockito.when(svcLogicStore.fetch(anyString(), eq("FIREWALL_Configure"), anyString(), anyString())).thenReturn(createGraph("FIREWALL_Configure")); + PowerMockito.when(svcLogicStore.fetch(anyString(), eq("FIREWALL_Restart"), anyString(), anyString())).thenReturn(createGraph("FIREWALL_Restart")); + PowerMockito.when(svcLogicStore.fetch(anyString(), eq("FIREWALL_Test"), anyString(), anyString())).thenReturn(createGraph("FIREWALL_Test")); + PowerMockito.when(svcLogicStore.fetch(anyString(), eq("FIREWALL_Rebuild"), anyString(), anyString())).thenReturn(createGraph("FIREWALL_Rebuild")); + PowerMockito.when(svcLogicStore.fetch(anyString(), eq("FIREWALL_Terminate"), anyString(), anyString())).thenReturn(createGraph("FIREWALL_Terminate")); + PowerMockito.when(svcLogicStore.fetch(anyString(), eq("FIREWALL_Start"), anyString(), anyString())).thenReturn(createGraph("FIREWALL_Start")); + svcLogicService.registerExecutor("switch", new SwitchNodeExecutor()); + svcLogicService.registerExecutor("execute",new ReturnNodeExecutor()); + svcLogicService.registerExecutor("return",new ReturnNodeExecutor()); + } catch (SvcLogicException e) { + e.printStackTrace(); + } + + workflowManger = new WorkFlowManagerImpl(); + + PowerMockito.when(getDao().retrieveWorkflowDetails("FIREWALL","Configure")).thenReturn(getWorkflow()); + PowerMockito.when(getDao().retrieveWorkflowDetails("FIREWALL","")).thenThrow(new DAOException()); + PowerMockito.when(getDao().retrieveWorkflowDetails("","Configure")).thenThrow(new DAOException()); + */ + } + + @Test + public void testEmptyVnfTypeFlow(){ + /* + WorkflowRequest workflowRequest = getWorkflowRequest("","1","1",command); + setSvcLogicGraph(createGraph(""+"_"+command)); + WorkflowResponse response =workflowManger.executeWorkflow(workflowRequest); + assertFalse(response.isExecutionSuccess()); + */ + } + + /* + @Test + public void testExecuteWorkflow(){ + //PowerMockito.when(getDao().retrieveWorkflowDetails(anyString(),anyString())).thenReturn(getWorkflow()); + WorkflowRequest workflowRequest = getWorkflowRequest("FIREWALL","1","1",command); + setSvcLogicGraph(createGraph("FIREWALL"+"_"+command)); + WorkflowResponse response =workflowManger.executeWorkflow(workflowRequest); + assertFalse(response.isExecutionSuccess()); + } + + @Test + public void testExecuteWorkflowEmptyPayload(){ + //PowerMockito.when(getDao().retrieveWorkflowDetails(anyString(),anyString())).thenReturn(getWorkflow()); + WorkflowRequest workflowRequest = getWorkflowRequest("FIREWALL","1","1",command); + workflowRequest.setPayload("{payload:\"payload\"}"); + setSvcLogicGraph(createGraph(""+"_"+command)); + WorkflowResponse response =workflowManger.executeWorkflow(workflowRequest); + assertFalse(response.isExecutionSuccess()); + } + + @Test + public void testWorkflowExist(){ + //PowerMockito.when(getDao().queryWorkflow(anyString(),anyString())).thenReturn(true); + WorkflowRequest workflowRequest = getWorkflowRequest("FIREWALL","1","1",command); + boolean success = workflowManger.workflowExists(workflowRequest); + assertTrue(success); + } + + @Test + public void testWorkflowExistFalse(){ + //PowerMockito.when(getDao().queryWorkflow(anyString(),anyString())).thenReturn(false); + WorkflowRequest workflowRequest = getWorkflowRequest("FIREWALL","1","1",command); + setSvcLogicGraph(createGraph(""+"_"+command)); + boolean success = workflowManger.workflowExists(workflowRequest); + assertFalse(success); + } + + + @Test + public void testEmptyCommandFlow(){ + WorkflowRequest workflowRequest = getWorkflowRequest("FIREWALL","1","1",""); + WorkflowResponse response =workflowManger.executeWorkflow(workflowRequest); + assertFalse(response.isExecutionSuccess()); + } + */ + + + public void setSvcLogicGraph(SvcLogicGraph svcLogicGraph) { + this.svcLogicGraph = svcLogicGraph; + } + + public SvcLogicGraph getSvcLogicGraph() { + return svcLogicGraph; + } + + protected SvcLogicGraph createGraph(String rpc) { + SvcLogicGraph svcLogicGraph = new SvcLogicGraph(); + svcLogicGraph.setModule("APPC"); + svcLogicGraph.setRpc(rpc); + svcLogicGraph.setMode("sync"); + svcLogicGraph.setVersion("2.0.0"); + SvcLogicNode svcLogicRootNode = new SvcLogicNode(1, "switch", svcLogicGraph); + SvcLogicNode svcLogicConfigureNode = new SvcLogicNode(2, "return", svcLogicGraph); + SvcLogicNode svcLogicOtherNode = new SvcLogicNode(3, "return", svcLogicGraph); + try { + svcLogicConfigureNode.setAttribute("status", "success"); + svcLogicOtherNode.setAttribute("status", "failure"); + svcLogicRootNode.setAttribute("test", "$org.openecomp.appc.action"); + svcLogicRootNode.addOutcome("Configure", svcLogicConfigureNode); + svcLogicRootNode.addOutcome("Other", svcLogicOtherNode); + } catch (SvcLogicException e) { + e.printStackTrace(); + } + svcLogicGraph.setRootNode(svcLogicRootNode); + return svcLogicGraph; + } +} diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/test/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/test/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..713e03430 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/test/resources/org/openecomp/appc/default.properties @@ -0,0 +1,100 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded to supply configuration options +#org.openecomp.appc.bootstrap.file=executor-test.properties +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + + +# +# Certificate keystore and truststore +# +#org.openecomp.sdnc.sli.aai.ssl.trust=<jks_FILE_HERE> +#org.openecomp.sdnc.sli.aai.ssl.trust.psswd=adminadmin +#org.openecomp.sdnc.sli.aai.ssl.key=<p12_FILE_HERE> +#org.openecomp.sdnc.sli.aai.ssl.key.psswd=adminadmin +org.openecomp.sdnc.sli.aai.host.certificate.ignore=true +org.openecomp.sdnc.sli.aai.certificate.trust.all=true + +# +# Configuration file for A&AI Adapter +# + +# OPEN SOURCE - EXTERNAL A&AI INSTANCE IN TEST ENVIRONMENT +org.openecomp.sdnc.sli.aai.uri=https://10.0.1.1:8443 + +org.openecomp.sdnc.sli.aai.path.query=/aai/v8/search/sdn-zone-query + +# service instance +org.openecomp.sdnc.sli.aai.path.svcinst=/aai/v8/business/customers/customer/{customer-id}/service-subscriptions/service-subscription/{service-type}/service-instances +org.openecomp.sdnc.sli.aai.path.svcinst.query=/aai/v8/search/generic-query?key=service-instance.service-instance-id:{svc-instance-id}&start-node-type=service-instance&include=service-instance + +# complex +org.openecomp.sdnc.sli.aai.path.complexes=/aai/v8/cloud-infrastructure/complexes +org.openecomp.sdnc.sli.aai.path.complex=/aai/v8/cloud-infrastructure/complexes/complex/{physical-location-id} + +# vservers +org.openecomp.sdnc.sli.aai.path.vservers=/aai/v8/cloud-infrastructure/tenants/tenant/{tenant-id}/vservers +org.openecomp.sdnc.sli.aai.path.vserver =/aai/v8/cloud-infrastructure/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id} + +# generic-vnf +org.openecomp.sdnc.sli.aai.path.generic.vnfs=/aai/v8/network/generic-vnfs/generic-vnf/ +org.openecomp.sdnc.sli.aai.path.generic.vnf=/aai/v8/network/generic-vnfs/generic-vnf/{vnf-id} + +# +# Formatting +# +org.openecomp.sdnc.sli.aai.param.format=filter=%s:%s +org.openecomp.sdnc.sli.aai.param.vnf_type=vnf-type +org.openecomp.sdnc.sli.aai.param.physical.location.id=physical-location-id +org.openecomp.sdnc.sli.aai.param.service.type=service-type + + +org.openecomp.appc.logging.path=${user.home},etc,../etc,. +org.openecomp.appc.logging.file=logback.xml + +org.openecomp.appc.db.url.%s", schema), ""); +org.openecomp.appc.db.user.%s", schema), ""); +org.openecomp.appc.db.pass.%s", schema), ""); + +# This value is provided in appc.properties +#dmaap.poolMembers=<DMAAP_IP>:3904 + +dmaap.topic.read=APPC-TEST2 +dmaap.topic.write=APPC-TEST2 +#dmaap.topic.read.filter={"class":"Assigned","field":"request"} +dmaap.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]} +dmaap.client.name=APPC-TEST-CLIENT +dmaap.client.name.id=0 +#dmaap.client.key=random +#dmaap.client.secret=random + +dmaap.threads.queuesize.min=1 +dmaap.threads.queuesize.max=1000 +dmaap.threads.poolsize.min=2 +dmaap.threads.poolsize.max=2 + +# +# This needs to be changed so that the action can be appended to the end of the URL path +# +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:topology-service +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider: diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/.gitignore b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/pom.xml b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/pom.xml new file mode 100644 index 000000000..93ea295ab --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/pom.xml @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-workflow-management</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <name>appc-workflow-management-features</name> + <artifactId>appc-workflow-management-features</artifactId> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-workflow-management-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-workflow-management-core</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <!--<plugin> + <!– launches the feature test, which validates that your karaf feature + can be installed inside of a karaf container. It doesn't validate that your + functionality works correctly, just that you have all of the dependent bundles + defined correctly. –> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.16</version> + <configuration> + <systemPropertyVariables> + <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId> + <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId> + <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version> + </systemPropertyVariables> + <dependenciesToScan> + <dependency>org.opendaylight.yangtools:features-test</dependency> + </dependenciesToScan> + <classpathDependencyExcludes> + <!– The dependencies which bring in AbstractDataBrokerTest class + brings in a second PaxExam container which results in the feature tests failing + with a message similar to: "ERROR o.ops4j.pax.exam.spi.PaxExamRuntime - Ambiguous + TestContainer ..." This excludes the container we don't want to use. –> + <classpathDependencyExcludes>org.ops4j.pax.exam:pax-exam-container-native</classpathDependencyExcludes> + </classpathDependencyExcludes> + </configuration> + </plugin>--> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + + <!-- Skipping ODL feature test --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <skipTests>true</skipTests> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/src/main/resources/features.xml b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/src/main/resources/features.xml new file mode 100644 index 000000000..ae1105d2b --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/src/main/resources/features.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="appc-workflow-management-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + + <feature name='appc-workflow-management' description="application executor" version='${project.version}'> + <bundle>mvn:org.openecomp.appc/appc-workflow-management-api/${project.version}</bundle> + <bundle>mvn:org.openecomp.appc/appc-workflow-management-core/${project.version}</bundle> + <bundle start="true" dependency="true">mvn:org.openecomp.appc/appc-ranking-framework-lib/${project.version}</bundle> + </feature> + +</features> diff --git a/app-c/appc/appc-dispatcher/appc-workflow-management/pom.xml b/app-c/appc/appc-dispatcher/appc-workflow-management/pom.xml new file mode 100644 index 000000000..63b8b4ee7 --- /dev/null +++ b/app-c/appc/appc-dispatcher/appc-workflow-management/pom.xml @@ -0,0 +1,22 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-workflow-management</artifactId> + <packaging>pom</packaging> + <name>APPC Workflow Management</name> + <description>APPC Workflow Management</description> + + <!-- ================================================================================== --> + <!-- The modules we build --> + <!-- ================================================================================== --> + <modules> + <module>appc-workflow-management-api</module> + <module>appc-workflow-management-core</module> + <module>appc-workflow-management-features</module> + </modules> + +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-dispatcher/pom.xml b/app-c/appc/appc-dispatcher/pom.xml new file mode 100644 index 000000000..c8c851f75 --- /dev/null +++ b/app-c/appc/appc-dispatcher/pom.xml @@ -0,0 +1,78 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-dispatcher</artifactId> + <packaging>pom</packaging> + <name>APPC Dispatcher</name> + <description>APPC Dispatcher</description> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-mockito</artifactId> + <version>1.6.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-all</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-junit4</artifactId> + <version>1.6.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.objenesis</groupId> + <artifactId>objenesis</artifactId> + <version>2.2</version> + <scope>test</scope> + </dependency> + </dependencies> + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <version>2.3.7</version> + <extensions>true</extensions> + </plugin> + </plugins> + </pluginManagement> + </build> + <!-- ================================================================================== --> + <!-- The modules we build --> + <!-- ================================================================================== --> + <modules> + <module>appc-dispatcher-common</module> + <module>appc-lifecycle-management</module> + <module>appc-workflow-management</module> + <module>appc-command-executor</module> + <module>appc-request-handler</module> + <module>appc-license-manager</module> + <module>appc-dispatcher-features</module> + <module>appc-dispatcher-installer</module> + </modules> + +</project> diff --git a/app-c/appc/appc-event-listener/.gitignore b/app-c/appc/appc-event-listener/.gitignore new file mode 100644 index 000000000..8509d88df --- /dev/null +++ b/app-c/appc/appc-event-listener/.gitignore @@ -0,0 +1,20 @@ +# Target dirs in all projects +**/target/* + +# Generated models and features +/model/bin/* +/features/bin/* + +# MANIFEST.MF is updated on every clean install +/appc-adapters/appc-*-adapter/appc-*-adapter-bundle/src/main/resources/META-INF/MANIFEST.MF +MANIFEST.MF + +# Karaf Assembly +#/appc-adapters/appc-*-adapter/appc-*-adapter-installer/src/assembly/* + + +*.prefs +.classpath +.project +/.settings/ +/target/ diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/.gitignore b/app-c/appc/appc-event-listener/appc-event-listener-bundle/.gitignore new file mode 100644 index 000000000..76a83c1cf --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/.gitignore @@ -0,0 +1,7 @@ +/bin/* +/target/ +/.settings/ +/bin/ +/target/ +/logs/ +/debug-logs/
\ No newline at end of file diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/pom.xml b/app-c/appc/appc-event-listener/appc-event-listener-bundle/pom.xml new file mode 100644 index 000000000..1ebec4a74 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/pom.xml @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-event-listener</artifactId> + <version>1.0.0</version> + </parent> + + <artifactId>appc-event-listener-bundle</artifactId> + <packaging>bundle</packaging> + <name>Event Listener - bundle</name> + + <dependencies> +<!-- + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-rest-bundle</artifactId> + <version>${project.version}</version> + </dependency> +--> + <dependency> + <groupId>com.att.eelf</groupId> + <artifactId>eelf-core</artifactId> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dmaap-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> +<!-- + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-rest-model</artifactId> + <version>${project.version}</version> + </dependency> +--> + + <dependency> + <groupId>equinoxSDK381</groupId> + <artifactId>org.eclipse.osgi</artifactId> + </dependency> + + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-core</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-annotations</artifactId> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>org.openecomp.appc.listener</Bundle-SymbolicName> + <Bundle-Activator>org.openecomp.appc.listener.AppcEventListenerActivator</Bundle-Activator> + <Export-Package>org.openecomp.appc.listener</Export-Package> + <Import-Package> + !com.datastax.*, + !com.ibm.icu.text, + !com.jcraft.jzlib, + !groovy.lang, + !javax.jms, + !net.sf.ehcache, + !net.spy.memcached, + !org.apache.commons.lang3, + !org.apache.log, + !org.apache.log4j.*, + !org.apache.zookeeper.*, + !org.jasypt.*, + !org.codehaus.commons.compiler, + !org.codehaus.groovy.*, + !org.codehaus.jackson.*, + !org.codehaus.jackson.map.*, + !org.codehaus.janino, + !org.I0Itec.*, + !com.sun.faces.*, + *;resolution:=optional</Import-Package> + <Embed-Dependency>*;scope=compile|runtime;artifactId=!appc-metric-bundle|sli-common|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis|pax-*</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + </configuration> + </plugin> + + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/AbstractListener.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/AbstractListener.java new file mode 100644 index 000000000..b36f4d7e6 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/AbstractListener.java @@ -0,0 +1,159 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener; + +import java.security.SecureRandom; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.commons.lang3.concurrent.BasicThreadFactory; +import org.openecomp.appc.listener.impl.EventHandlerImpl; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +public abstract class AbstractListener implements Listener { + + private final EELFLogger LOG = EELFManager.getInstance().getLogger(AbstractListener.class); + + protected AtomicBoolean run = new AtomicBoolean(false); + + protected int QUEUED_MIN = 1; + protected int QUEUED_MAX = 10; + + protected int THREAD_MIN = 4; + protected int THREAD_MAX = THREAD_MIN; // Fixed thread pool + protected int THREAD_SCALE_DOWN_SEC = 10; // Number of seconds to wait until we remove idle threads + + protected ThreadPoolExecutor executor; + + protected EventHandler dmaap; + + protected ListenerProperties props; + + private String listenerId; + + public AbstractListener(ListenerProperties props) { + updateProperties(props); + + dmaap = new EventHandlerImpl(props); + if (dmaap.getClientId().equals("0")) { + dmaap.setClientId(String.valueOf(new SecureRandom().nextInt(1000))); + } + + BlockingQueue<Runnable> threadQueue = new ArrayBlockingQueue<Runnable>(QUEUED_MAX + QUEUED_MIN + 1); + executor = new ThreadPoolExecutor(THREAD_MIN, THREAD_MAX, THREAD_SCALE_DOWN_SEC, TimeUnit.SECONDS, threadQueue, + new JobRejectionHandler()); + + // Custom Named thread factory + BasicThreadFactory threadFactory = new BasicThreadFactory.Builder().namingPattern("DMaaP-Worker-%d").build(); + executor.setThreadFactory(threadFactory); + + run.set(true); + } + + /** + * Starts a loop that will only end after stop() or stopNow() are called. The loop will read messages off the DMaaP + * topic and perform some action on them while writing messages back to DMaaP at critical points in the execution. + * Inherited from Runnable. + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + LOG.error("Listener.run() has not been implemented"); + } + + @Override + public void stop() { + run.set(false); + LOG.info(String.format("Stopping with %d messages in queue", executor.getQueue().size())); + executor.shutdown(); + try { + executor.awaitTermination(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + LOG.error("Listener graceful stop() failed", e); + } + + // close DMaaP clients + if (dmaap != null) { + dmaap.closeClients(); + } + LOG.info("Listener Thread Pool Finished"); + } + + @Override + public void stopNow() { + run.set(false); + LOG.info(String.format("StopNow called. Orphaning %d messages in the queue", executor.getQueue().size())); + executor.getQueue().clear(); + stop(); + } + + @Override + public String getBenchmark() { + return String.format("%s - No benchmarking implemented.", getListenerId()); + } + + @Override + public String getListenerId() { + return listenerId; + } + + // Sets the id of the listener in + @Override + public void setListenerId(String id) { + listenerId = id; + } + + private void updateProperties(ListenerProperties properties) { + this.props = properties; + QUEUED_MIN = + Integer.valueOf(props.getProperty(ListenerProperties.KEYS.THREADS_MIN_QUEUE, String.valueOf(QUEUED_MIN))); + QUEUED_MAX = + Integer.valueOf(props.getProperty(ListenerProperties.KEYS.THREADS_MAX_QUEUE, String.valueOf(QUEUED_MAX))); + THREAD_MIN = + Integer.valueOf(props.getProperty(ListenerProperties.KEYS.THREADS_MIN_POOL, String.valueOf(THREAD_MIN))); + THREAD_MAX = + Integer.valueOf(props.getProperty(ListenerProperties.KEYS.THREADS_MAX_POOL, String.valueOf(THREAD_MAX))); + + listenerId = props.getPrefix(); + } + + /** + * This class will be used to handle what happens when we cannot add a job because of a ThreadPool issue. It does + * not get invoked if there is any fault with the job. NOTE: So far, this has only been seen when doing a + * {@link Listener#stopNow} + * + */ + class JobRejectionHandler implements RejectedExecutionHandler { + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + LOG.error(String.format("A job was rejected. [%s]", r)); + } + + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/AppcEventListenerActivator.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/AppcEventListenerActivator.java new file mode 100644 index 000000000..4c2e28196 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/AppcEventListenerActivator.java @@ -0,0 +1,185 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener; + +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.listener.impl.ControllerImpl; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; + +/** + * This activator is used to initialize and terminate the dmaap listener controller and pool(s) + * <p> + * The DMaaP listener is responsible for listening to a topic on the Universal Event Bus and reading in messages that + * conform to the DCAE message format for APPC. These messages will then be parsed and passed along to the APPC Provider + * to take action on. The listener will also send messages out on DMaaP during critical phases. The messages sent out will + * have a status of: + * <ul> + * <li><i>PENDING</i> - The listener has read the message off of DMaaP and has put it in the queue to be processed</li> + * <li><i>ACTIVE</i> - The listener has begun actually processing the request and is waiting on the appc provider to + * complete the request</li> + * <li><i>SUCCESS</i> or <i>FAILURE</i> - The listener has gotten a response back from the appc provider. If it is a + * FAILURE, a message should also be included</li> + * </ul> + * </p> + * <p> + * Activation of the bundle will provision 1 controller that in turn will provision 1 (or in the future more) listener + * to interact with DMaaP. Each listener will have a queue of messages read off of DMaaP and a thread pool of workers to + * process them. This worker is responsible for contacting appc provider to perform the action + * </p> + * <p> + * When the bundle is deactivated, the stopNow() method is called and the thread pool is emptied and all remaining jobs + * are orphaned. Alternatively stop() could be called which would allow all remaining jobs in the queue to complete at + * the cost of longer run time. + * </p> + * + * @since Aug 30, 2015 + * @version $Id$ + */ +public class AppcEventListenerActivator implements BundleActivator { + + /** + * The bundle registration + */ + private ServiceRegistration registration = null; + + /** + * The configuration object + */ + private Configuration configuration; + + /** + * The bundle context + */ + private static BundleContext context; + + /** + * The reference to the actual implementation object that implements the services + */ + private Controller adapter; + + /** + * The logger to be used + */ + private final EELFLogger LOG = EELFManager.getInstance().getLogger(AppcEventListenerActivator.class); + + /** + * Called when this bundle is started so the Framework can perform the bundle-specific activities necessary to start + * this bundle. This method can be used to register services or to allocate any resources that this bundle needs. + * <p> + * This method must complete and return to its caller in a timely manner. + * </p> + * + * @param ctx + * The execution context of the bundle being started. + * @throws java.lang.Exception + * If this method throws an exception, this bundle is marked as stopped and the Framework will remove + * this bundle's listeners, unregister all services registered by this bundle, and release all services + * used by this bundle. + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext ctx) throws Exception { + LOG.info("Starting Bundle " + getName()); + + context = ctx; + + configuration = ConfigurationFactory.getConfiguration(); + + Properties props = configuration.getProperties(); + + Set<ListenerProperties> listeners = new HashSet<ListenerProperties>(); + + // Configure App-C Closed Loop Listener +/* ListenerProperties clProps = new ListenerProperties("appc.ClosedLoop", props); + clProps.setListenerClass(org.openecomp.appc.listener.CL.impl.ListenerImpl.class); + listeners.add(clProps);*/ + + // Configure App-C 1607 Closed Loop Listener + ListenerProperties cl1607Props = new ListenerProperties("appc.ClosedLoop1607", props); + cl1607Props.setListenerClass(org.openecomp.appc.listener.CL1607.impl.ListenerImpl.class); + listeners.add(cl1607Props); + + +/* ListenerProperties clLCMProps = new ListenerProperties("appc.LCM", props); + clLCMProps.setListenerClass(org.openecomp.appc.listener.LCM.impl.ListenerImpl.class); + listeners.add(clLCMProps);*/ + +/* + ListenerProperties clLCMProps1607 = new ListenerProperties("appc.LCM1607", props); + clLCMProps1607.setListenerClass(org.openecomp.appc.listener.LCM1607.impl.ListenerImpl.class); + listeners.add(clLCMProps1607); +*/ + + adapter = new ControllerImpl(listeners); + if (ctx != null && registration == null) { + LOG.info("Registering service DMaaP Controller"); + registration = ctx.registerService(Controller.class, adapter, null); + } + adapter.start(); + + LOG.info("DMaaP Listener started successfully"); + } + + /** + * Called when this bundle is stopped so the Framework can perform the bundle-specific activities necessary to stop + * the bundle. In general, this method should undo the work that the BundleActivator.start method started. There + * should be no active threads that were started by this bundle when this bundle returns. A stopped bundle must not + * call any Framework objects. + * <p> + * This method must complete and return to its caller in a timely manner. + * </p> + * + * @param ctx + * The execution context of the bundle being stopped. + * @throws java.lang.Exception + * If this method throws an exception, the bundle is still marked as stopped, and the Framework will + * remove the bundle's listeners, unregister all services registered by the bundle, and release all + * services used by the bundle. * + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext ctx) throws Exception { + boolean stopNow = true; + LOG.info("Stopping DMaaP Listener. StopNow=" + stopNow); + adapter.stop(stopNow); + if (registration != null) { + registration.unregister(); + registration = null; + } + LOG.info("DMaaP Listener stopped successfully"); + } + + public String getName() { + return "DMaaP Listener"; + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/impl/ListenerImpl.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/impl/ListenerImpl.java new file mode 100644 index 000000000..3f0f8a112 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/impl/ListenerImpl.java @@ -0,0 +1,128 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL.impl; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; +import java.util.concurrent.RejectedExecutionException; + +import org.openecomp.appc.listener.AbstractListener; +import org.openecomp.appc.listener.ListenerProperties; +import org.openecomp.appc.listener.CL.model.IncomingMessage; +import org.openecomp.appc.listener.CL.model.Status; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; + +public class ListenerImpl extends AbstractListener { + + private final EELFLogger LOG = EELFManager.getInstance().getLogger(ListenerImpl.class); + + private long startTime = 0; + + public ListenerImpl(ListenerProperties props) { + super(props); + String url = props.getProperty("provider.url"); + LOG.info("DMaaP Provider Endpoint: " + url); + ProviderOperations.setUrl(url); + + // Set Basic Auth + String user = props.getProperty("provider.user"); + String pass = props.getProperty("provider.pass"); + ProviderOperations.setAuthentication(user, pass); + } + + @Override + public void run() { + // Some vars for benchmarking + startTime = System.currentTimeMillis(); + + LOG.info("Running DMaaP Listener"); + + while (run.get()) { + // Only update if the queue is low. otherwise we read in more + // messages than we need + try { + if (executor.getQueue().size() <= QUEUED_MIN) { + LOG.debug("DMaaP queue running low. Querying for more jobs"); + List<IncomingMessage> messages = dmaap.getIncomingEvents(IncomingMessage.class, QUEUED_MAX); + LOG.debug(String.format("Read %d messages from dmaap", messages.size())); + for (IncomingMessage incoming : messages) { + // Acknowledge that we read the event + LOG.info("Acknowledging Message: " + incoming.getId()); + dmaap.postStatus(incoming.toOutgoing(Status.PENDING, null).toString()); + } + for (IncomingMessage incoming : messages) { + // Add to pool if still running + if (run.get()) { + LOG.info(String.format("Adding DMaaP message to pool queue [%s]", incoming.getId())); + if (incoming.isValid()) { + try { + executor.execute(new WorkerImpl(incoming, dmaap)); + } catch (RejectedExecutionException rejectEx) { + LOG.error("Task Rejected: ", rejectEx); + } + } else { + // Badly formed message + LOG.error("Message was not valid. Rejecting"); + } + } else { + LOG.info("Run stopped. Orphaning Message: " + incoming.getId()); + } + } + } + } catch (Exception e) { + LOG.error("Exception " + e.getClass().getSimpleName() + " caught in DMaaP listener"); + LOG.error(EELFResourceManager.format(e)); + LOG.error("DMaaP Listener logging and ignoring the exception, continue..."); + } + } + + LOG.info("Stopping DMaaP Listener thread"); + + // We've told the listener to stop + // TODO - Should we: + // 1) Put a message back on the queue indicating that APP-C never got to + // the message + // or + // 2) Let downstream figure it out after timeout between PENDING and + // ACTIVE messages + } + + @Override + public String getBenchmark() { + long time = System.currentTimeMillis(); + DateFormat df = new SimpleDateFormat("HH:mm:ss"); + df.setTimeZone(TimeZone.getTimeZone("UTC")); + String runningTime = df.format(new Date(time - startTime)); + + String out = String.format("Running for %s and completed %d jobs using %d threads.", runningTime, + executor.getCompletedTaskCount(), executor.getPoolSize()); + LOG.info("***BENCHMARK*** " + out); + return out; + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/impl/ProviderOperations.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/impl/ProviderOperations.java new file mode 100644 index 000000000..7a53bcdd9 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/impl/ProviderOperations.java @@ -0,0 +1,296 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL.impl; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.Socket; +import java.net.URL; +import java.net.UnknownHostException; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.HttpVersion; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; +import org.apache.http.protocol.HTTP; +import org.json.JSONObject; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.listener.CL.model.IncomingMessage; +import org.openecomp.appc.listener.util.Mapper; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +public class ProviderOperations { + + private static final EELFLogger LOG = EELFManager.getInstance().getLogger(ProviderOperations.class); + + private static URL url; + + private static String basic_auth; + + //@formatter:off + @SuppressWarnings("nls") + private final static String TEMPLATE = "{\"input\": {\"common-request-header\": {\"service-request-id\": \"%s\"},\"vnf-resource\": {\"vm-id\": \"%s\"%s}}}"; + //@formatter:on + + /** + * Calls the AppcProvider to run a topology directed graph + * + * @param msg + * The incoming message to be run + * @return True if the result is success. Never returns false and throws an exception instead. + * @throws UnsupportedEncodingException + * @throws Exception + * if there was a failure processing the request. The exception message is the failure reason. + */ + @SuppressWarnings("nls") + public static boolean topologyDG(IncomingMessage msg) throws APPCException { + if (msg == null) { + throw new APPCException("Provided message was null"); + } + + HttpPost post = null; + try { + // Concatenate the "action" on the end of the URL + String path = url.getPath() + ":" + msg.getAction().getValue().toLowerCase(); + URL serviceUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), path); + + post = new HttpPost(serviceUrl.toExternalForm()); + post.setHeader("Content-Type", "application/json"); + post.setHeader("Accept", "application/json"); + + // Set Auth + if (basic_auth != null) { + post.setHeader("Authorization", "Basic " + basic_auth); + } + + String body = buildReqest(msg.getId(), msg.getUrl(), msg.getIdentityUrl()); + + + LOG.info(String.format("DMaaP ACTION PATH : %s", path)); + LOG.info(String.format("DMaaP ACTION BODY : %s", body)); + + StringEntity entity = new StringEntity(body); + entity.setContentType("application/json"); + post.setEntity(new StringEntity(body)); + } catch (UnsupportedEncodingException | MalformedURLException e) { + throw new APPCException(e); + } + + HttpClient client = getHttpClient(); + + int httpCode = 0; + String respBody = null; + try { + HttpResponse response = client.execute(post); + httpCode = response.getStatusLine().getStatusCode(); + respBody = IOUtils.toString(response.getEntity().getContent()); + } catch (IOException e) { + throw new APPCException(e); + } + + if (httpCode >= 200 && httpCode < 300 && respBody != null) { + JSONObject json; + try { + json = Mapper.toJsonObject(respBody); + } catch (Exception e) { + LOG.error("Error processing response from provider. Could not map response to json", e); + throw new APPCException("APPC has an unknown RPC error"); + } + boolean success; + String reason; + try { + JSONObject header = json.getJSONObject("output").getJSONObject("common-response-header"); + success = header.getBoolean("success"); + reason = header.getString("reason"); + } catch (Exception e) { + LOG.error("Unknown error prcoessing failed response from provider. Json not in expected format", e); + throw new APPCException("APPC has an unknown RPC error"); + } + if (success) { + return true; + } + String reasonStr = reason == null ? "Unknown" : reason; + LOG.warn(String.format("Topology Operation [%s] failed. Reason: %s", msg.getId(), reasonStr)); + throw new APPCException(reasonStr); + + } + throw new APPCException(String.format("Unexpected response from endpoint: [%d] - %s ", httpCode, respBody)); + } + + /** + * Updates the static var URL and returns the value; + * + * @return The new value of URL + */ + public static String getUrl() { + return url.toExternalForm(); + } + + public static void setUrl(String newUrl) { + try { + url = new URL(newUrl); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + /** + * Sets the basic authentication header for the given user and password. If either entry is null then set basic auth + * to null + * + * @param user + * The user with optional domain name + * @param password + * The password for the user + * @return The new value of the basic auth string that will be used in the request headers + */ + public static String setAuthentication(String user, String password) { + if (user != null && password != null) { + String authStr = user + ":" + password; + basic_auth = new String(Base64.encodeBase64(authStr.getBytes())); + } else { + basic_auth = null; + } + return basic_auth; + } + + /** + * Builds the request body for a topology operation + * + * @param id + * The request id + * @param action + * The action in lowercase + * @param url + * The vm's url + * @return A String containing the request body + */ + private static String buildReqest(String id, String url, String ident) { + String extraVmResource = ""; + if (ident != null) { + extraVmResource = String.format(", \"identity-url\": \"%s\"", ident); + } + return String.format(TEMPLATE, id, url, extraVmResource); + } + + @SuppressWarnings("deprecation") + private static HttpClient getHttpClient() throws APPCException { + HttpClient client; + if (url.getProtocol().equals("https")) { + try { + KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); + trustStore.load(null, null); + MySSLSocketFactory sf = new MySSLSocketFactory(trustStore); + sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); + + HttpParams params = new BasicHttpParams(); + HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); + HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); + + SchemeRegistry registry = new SchemeRegistry(); + registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + registry.register(new Scheme("https", sf, 443)); + registry.register(new Scheme("https", sf, 8443)); + registry.register(new Scheme("http", sf, 8181)); + + ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); + client = new DefaultHttpClient(ccm, params); + } catch (Exception e) { + client = new DefaultHttpClient(); + } + } else if (url.getProtocol().equals("http")) { + client = new DefaultHttpClient(); + } else { + throw new APPCException( + "The provider.topology.url property is invalid. The url did not start with http[s]"); + } + return client; + } + + @SuppressWarnings("deprecation") + public static class MySSLSocketFactory extends SSLSocketFactory { + private SSLContext sslContext = SSLContext.getInstance("TLS"); + + public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, + KeyStoreException, UnrecoverableKeyException { + super(truststore); + + TrustManager tm = new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; + } + }; + + sslContext.init(null, new TrustManager[] { + tm + }, null); + } + + @Override + public Socket createSocket(Socket socket, String host, int port, boolean autoClose) + throws IOException, UnknownHostException { + return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); + } + + @Override + public Socket createSocket() throws IOException { + return sslContext.getSocketFactory().createSocket(); + } + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/impl/WorkerImpl.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/impl/WorkerImpl.java new file mode 100644 index 000000000..1eb13f736 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/impl/WorkerImpl.java @@ -0,0 +1,79 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL.impl; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.listener.EventHandler; +import org.openecomp.appc.listener.CL.model.IncomingMessage; +import org.openecomp.appc.listener.CL.model.Status; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +public class WorkerImpl implements Runnable { + + private final EELFLogger LOG = EELFManager.getInstance().getLogger(WorkerImpl.class); + + // Should have all of the data we need for processing + private IncomingMessage event; + + // So we can post messages from inside the worker. + private EventHandler dmaap; + + public WorkerImpl(IncomingMessage message, EventHandler dmaap) { + this.event = message; + this.dmaap = dmaap; + } + + @Override + public void run() { + LOG.debug(String.format("Started working on %s", event.getId())); + dmaap.postStatus(event.toOutgoing(Status.ACTIVE, null)); + // Run the dg in a try catch to handle all exceptions and update the + // message at the end + try { + if (doDG(event)) { + dmaap.postStatus(event.toOutgoing(Status.SUCCESS, null)); + LOG.debug(String.format("Event %s finished successfully", event.getId())); + } else { + // Should never happen. Exception with message should be thrown instead. + LOG.error(String.format( + "We somehow returned false from doDG() instead of throwing exception. Incoming event [%s]", + event.toJson().toString())); + dmaap.postStatus(event.toOutgoing(Status.FAILURE)); + } + + } catch (Exception e) { + // Unknown exception from DG method. Fail and pass the exception + // along + String msg = "Exception: " + e.getMessage(); + LOG.warn(String.format("Event %s finished with failure. %s", event.getId(), msg)); + dmaap.postStatus(event.toOutgoing(Status.FAILURE, msg)); + } + + LOG.debug("Done working on " + event.getId()); + } + + private boolean doDG(IncomingMessage msg) throws APPCException { + return ProviderOperations.topologyDG(msg); + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/Action.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/Action.java new file mode 100644 index 000000000..a8fe8035b --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/Action.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL.model; + +public enum Action { + Restart("Restart"), Rebuild("Rebuild"), Migrate("Migrate"), Evacuate("Evacuate"); + + /** + * Converts the string to an Action + * + * @param value + * The string to try and convert. Is case insensitive + * @return The action matching the string or null if no match was found. + */ + public static Action toAction(String value) { + if (value != null) { + for (Action e : values()) { + if (e.getValue().toUpperCase().equals(value.toUpperCase())) { + return e; + } + } + } + + return null; + } + + private String value; + + private Action(String valueToUse) { + value = valueToUse; + } + + public final String getValue() { + return value; + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/CommonMessage.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/CommonMessage.java new file mode 100644 index 000000000..76a112618 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/CommonMessage.java @@ -0,0 +1,181 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL.model; + +import java.io.Serializable; + +import org.json.JSONObject; +import org.openecomp.appc.listener.util.Mapper; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion; + +/** + * This class holds attributes that are common to DMaaP messages both coming in from DCAE and being sent out by APPC + * + */ +@JsonSerialize(include = Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class CommonMessage implements Serializable { + + private static final long serialVersionUID = 1L; + + /* + * The unique id of the event as of 1602 + */ + @JsonProperty("eventID") + private String id; + + /* + * The time that the request was sent out. + */ + @JsonProperty("requestTime") + private String requestTime; + + /* + * The originator of the event + */ + @JsonProperty("requestClient") + private String requestClient; + + /* + * The system that sent the message + */ + @JsonProperty("from") + private String fromSystem; + + /* + * The actual trap message + */ + @JsonProperty("message") + private String message; + + /* + * The vm name associated with the event + */ + @JsonProperty("VMName") + private String vmName; + + /* + * The policy name on the incoming event + */ + @JsonProperty("policyName") + private String policyName; + + /* + * The policy version on the incoming event + */ + @JsonProperty("policyVersion") + private String policyVersion; + + @JsonIgnore + private long startTime = System.currentTimeMillis(); + + /* + * Getters and Setters + */ + + public String getId() { + return id; + } + + public String getRequestTime() { + return requestTime; + } + + public String getRequestClient() { + return requestClient; + } + + public String getFromSystem() { + return fromSystem; + } + + public String getMessage() { + return message; + } + + public String getPolicyName() { + return policyName; + } + + public String getPolicyVersion() { + return policyVersion; + } + + public String getVmName() { + return vmName; + } + + public long getStartTime() { + return startTime; + } + + public void setId(String eventId) { + id = eventId; + } + + public void setRequestTime(String requestTime) { + this.requestTime = requestTime; + } + + public void setRequestClient(String requestClient) { + this.requestClient = requestClient; + } + + public void setFromSystem(String fromSystem) { + this.fromSystem = fromSystem; + } + + public void setMessage(String message) { + this.message = message; + } + + public void setPolicyName(String name) { + policyName = name; + } + + public void setPolicyVersion(String version) { + policyVersion = version; + } + + public void setVmName(String vmName) { + this.vmName = vmName; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + } + + /** + * Convenience method to return a json representation of this object. + * + * @return The json representation of this object + */ + public JSONObject toJson() { + return Mapper.toJsonObject(this); + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/IncomingMessage.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/IncomingMessage.java new file mode 100644 index 000000000..60d1d004b --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/IncomingMessage.java @@ -0,0 +1,140 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion; + +/** + * This class reperesnts a message coming in from DCAE. + * + */ +@JsonSerialize(include = Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class IncomingMessage extends CommonMessage { + + private static final long serialVersionUID = 1L; + + /* + * The action being requested. Its presence signals that it is an incoming message and it is not present on outgoing + * messages + */ + @JsonProperty("request") + private String request; + + /* + * The url for the server used for auth. http://<compute>:<port>/<tenentId>/server/<serverID> + */ + @JsonProperty("VServerSelfLink") + private String Url; + + /* + * The tenant Id in OpenStack that the server belongs to + */ + @JsonProperty("TenantID") + private String TenantId; + + /* + * The VM's UUID in + */ + @JsonProperty("VMID") + private String VmId; + + @JsonProperty("Identity") + private String identityUrl; + + public String getRequest() { + return request; + } + + @JsonIgnore + public Action getAction() { + return Action.toAction(request); + } + + public String getUrl() { + return Url; + } + + public String getTenantId() { + return TenantId; + } + + public String getVmId() { + return VmId; + } + + public String getIdentityUrl() { + return identityUrl; + } + + public void setUrl(String Url) { + this.Url = Url; + } + + public void setTenantId(String TenantId) { + this.TenantId = TenantId; + } + + public void setVmId(String VmId) { + this.VmId = VmId; + } + + public void setRequest(String request) { + this.request = request; + } + + public void setIdentityUrl(String identityUrl) { + this.identityUrl = identityUrl; + } + + @Override + public String toString() { + String time = getRequestTime() != null ? getRequestTime() : "N/A"; + // String req = request != null ? request : "N/A"; + return String.format("[%s - %s]", time, getId()); + } + + public String toOutgoing(Status status) { + return toOutgoing(status, getMessage()); + } + + public String toOutgoing(Status status, String msg) { + OutgoingMessage out = new OutgoingMessage(this); + out.setResponse(status); + out.setMessage(msg); + return out.toResponse().toString(); + } + + /** + * Determines if this message should be parsed parsed. Will eventually check that the message is well formed, has + * all required fields, and had not exceeded any timing restrictions. + * + * @return True if the message should be parsed. False otherwise + */ + public boolean isValid() { + return true; + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/OutgoingMessage.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/OutgoingMessage.java new file mode 100644 index 000000000..fa8560ed2 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/OutgoingMessage.java @@ -0,0 +1,150 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL.model; + +import java.net.InetAddress; +import java.security.SecureRandom; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +import org.json.JSONObject; +import org.openecomp.appc.listener.util.Mapper; +import org.openecomp.appc.util.Time; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion; + +/** + * This class represents a message being sent out to DMaaP by APPC to update listeners on the status of a request + * + */ +@JsonSerialize(include = Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class OutgoingMessage extends CommonMessage { + + private static final long serialVersionUID = -5447940920271469613L; + + @JsonProperty("response") + private Status response; + + @JsonProperty("responseTime") + private String responseTime; + + @JsonProperty("originalRequest") + private String originalRequest; + + public OutgoingMessage() { + + } + + public OutgoingMessage(IncomingMessage msg) { + setId(msg.getId()); + setOriginalRequest(msg.getRequest()); + setRequestClient(msg.getRequestClient()); + setRequestTime(msg.getRequestTime()); + setVmName(msg.getVmName()); + setFromSystem(generateFrom()); + setResponse(Status.PENDING); + setPolicyName(msg.getPolicyName()); + setPolicyVersion(msg.getPolicyVersion()); + setStartTime(msg.getStartTime()); + } + + @JsonProperty("duration") + public long getDuration() { + return System.currentTimeMillis() - getStartTime(); + } + + public Status getResponse() { + return response; + } + + public String getResponseTime() { + return responseTime; + } + + public String getOriginalRequest() { + return originalRequest; + } + + @JsonIgnore + public void setResponse(Status response) { + this.response = response; + } + + public void setResponse(String responseString) { + this.response = Status.valueOf(responseString); + } + + public void setResponseTime(String responseTime) { + this.responseTime = responseTime; + } + + public void setOriginalRequest(String originalRequest) { + this.originalRequest = originalRequest; + } + + public void updateResponseTime() { + SecureRandom rand = new SecureRandom(); + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss.SSS"); + df.setTimeZone(TimeZone.getTimeZone("UTC")); + String date = df.format(new Date(Time.utcTime())); + this.responseTime = String.format("%s%03d", date, rand.nextInt(1000)); + } + + public String generateFrom() { + String name; + try { + InetAddress iAddress = InetAddress.getLocalHost(); + name = iAddress.getCanonicalHostName(); + } catch (Exception e) { + // Could not get anything from the InetAddress + name = "UnknownHost"; + } + return "appc@" + name; + } + + public JSONObject toResponse() { + updateResponseTime(); + JSONObject json = Mapper.toJsonObject(this); + + if (!json.has("message")) { + // If there is no message, parrot the status (response field) + // TODO - Can this be removed for 1602 making message truely optional? + json.put("message", this.getResponse().toString()); + } + + // Removed duplication of status from message for 1602 + // json.put("message", String.format("%s: %s", request, json.get("message"))); + + return json; + } + + @Override + public String toString() { + return String.format("%s - %s", getId(), getResponse()); + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/Status.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/Status.java new file mode 100644 index 000000000..d8e8b5c64 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/Status.java @@ -0,0 +1,74 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL.model; + +public enum Status { + /* + * APP-C acknowledges that it has read the event off of the wire. This is the initial status of an OutgoingEvent + */ + PENDING("PENDING"), + + /* + * APP-C has started processing the event + */ + ACTIVE("ACTIVE"), + + /* + * APP-C has finished processing the event without errors + */ + SUCCESS("SUCCESS"), + + /* + * APP-C has finished processing the event with errors + */ + FAILURE("FAILURE"); + + /** + * Converts the string to an Status + * + * @param value + * The string to try and convert. Is case insensitive + * @return The status matching the string or null if no match was found. + */ + public static Status toStatus(String value) { + if (value != null) { + for (Status e : values()) { + if (e.getValue().toUpperCase().equals(value.toUpperCase())) { + return e; + } + } + } + + return null; + } + + private String value; + + private Status(String valueToUse) { + value = valueToUse; + } + + public final String getValue() { + return value; + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/impl/ListenerImpl.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/impl/ListenerImpl.java new file mode 100644 index 000000000..5d3b741ff --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/impl/ListenerImpl.java @@ -0,0 +1,130 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL1607.impl; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; +import java.util.concurrent.RejectedExecutionException; + +import org.openecomp.appc.listener.AbstractListener; +import org.openecomp.appc.listener.ListenerProperties; +import org.openecomp.appc.listener.CL1607.model.IncomingMessage; +import org.openecomp.appc.listener.CL1607.model.Status; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; + +public class ListenerImpl extends AbstractListener { + + private final EELFLogger LOG = EELFManager.getInstance().getLogger(ListenerImpl.class); + + private long startTime = 0; + + public ListenerImpl(ListenerProperties props) { + super(props); + String url = props.getProperty("provider.url"); + LOG.info("DMaaP Provider Endpoint: " + url); + ProviderOperations.setUrl(url); + + // Set Basic Auth + String user = props.getProperty("provider.user"); + String pass = props.getProperty("provider.pass"); + ProviderOperations.setAuthentication(user, pass); + } + + @Override + public void run() { + // Some vars for benchmarking + startTime = System.currentTimeMillis(); + + LOG.info("Running DMaaP Listener"); + + while (run.get()) { + // Only update if the queue is low. otherwise we read in more + // messages than we need + try { + if (executor.getQueue().size() <= QUEUED_MIN) { + LOG.debug("DMaaP queue running low. Querying for more jobs"); + List<IncomingMessage> messages = dmaap.getIncomingEvents(IncomingMessage.class, QUEUED_MAX); + LOG.debug(String.format("Read %d messages from dmaap", messages.size())); + for (IncomingMessage incoming : messages) { + // Acknowledge that we read the event + LOG.info("Acknowledging Message: " + incoming.getHeader().getRequestID()); + + //TODO: Should we post a pending status for 1607 + //dmaap.postStatus(incoming.toOutgoing(Status.PENDING, null).toString()); + } + for (IncomingMessage incoming : messages) { + // Add to pool if still running + if (run.get()) { + LOG.info(String.format("Adding DMaaP message to pool queue [%s]", incoming.getHeader().getRequestID())); + if (incoming.isValid()) { + try { + executor.execute(new WorkerImpl(incoming, dmaap)); + } catch (RejectedExecutionException rejectEx) { + LOG.error("Task Rejected: ", rejectEx); + } + } else { + // Badly formed message + LOG.error("Message was not valid. Rejecting"); + } + } else { + LOG.info("Run stopped. Orphaning Message: " + incoming.getHeader().getRequestID()); + } + } + } + } catch (Exception e) { + LOG.error("Exception " + e.getClass().getSimpleName() + " caught in DMaaP listener"); + LOG.error(EELFResourceManager.format(e)); + LOG.error("DMaaP Listener logging and ignoring the exception, continue..."); + } + } + + LOG.info("Stopping DMaaP Listener thread"); + + // We've told the listener to stop + // TODO - Should we: + // 1) Put a message back on the queue indicating that APP-C never got to + // the message + // or + // 2) Let downstream figure it out after timeout between PENDING and + // ACTIVE messages + } + + @Override + public String getBenchmark() { + long time = System.currentTimeMillis(); + DateFormat df = new SimpleDateFormat("HH:mm:ss"); + df.setTimeZone(TimeZone.getTimeZone("UTC")); + String runningTime = df.format(new Date(time - startTime)); + + String out = String.format("Running for %s and completed %d jobs using %d threads.", runningTime, + executor.getCompletedTaskCount(), executor.getPoolSize()); + LOG.info("***BENCHMARK*** " + out); + return out; + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/impl/ProviderOperations.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/impl/ProviderOperations.java new file mode 100644 index 000000000..c300df154 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/impl/ProviderOperations.java @@ -0,0 +1,291 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL1607.impl; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.Socket; +import java.net.URL; +import java.net.UnknownHostException; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.HttpVersion; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; +import org.apache.http.protocol.HTTP; +import org.json.JSONObject; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.listener.CL1607.model.IncomingMessage; +import org.openecomp.appc.listener.util.Mapper; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +public class ProviderOperations { + + private static final EELFLogger LOG = EELFManager.getInstance().getLogger(ProviderOperations.class); + + private static URL url; + + private static String basic_auth; + + //@formatter:off + @SuppressWarnings("nls") + private final static String TEMPLATE = "{\"input\": {\"common-request-header\": {\"service-request-id\": \"%s\"},\"config-payload\": {\"config-url\": \"%s\",\"config-json\":\"%s\"}}}"; + //@formatter:on + + /** + * Calls the AppcProvider to run a topology directed graph + * + * @param msg + * The incoming message to be run + * @return True if the result is success. Never returns false and throws an exception instead. + * @throws UnsupportedEncodingException + * @throws Exception + * if there was a failure processing the request. The exception message is the failure reason. + */ + @SuppressWarnings("nls") + public static boolean topologyDG(IncomingMessage msg) throws APPCException { + if (msg == null) { + throw new APPCException("Provided message was null"); + } + + HttpPost post = null; + try { + // Concatenate the "action" on the end of the URL + String path = url.getPath() + ":" + msg.getAction().getValue(); + URL serviceUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), path); + + post = new HttpPost(serviceUrl.toExternalForm()); + post.setHeader("Content-Type", "application/json"); + post.setHeader("Accept", "application/json"); + + // Set Auth + if (basic_auth != null) { + post.setHeader("Authorization", "Basic " + basic_auth); + } + + //String body = buildReqest(msg.getId(), msg.getUrl(), msg.getIdentityUrl()); + String body = buildReqest(msg.getHeader().getRequestID(), msg.getPayload().getGenericVnfId(), msg.getPayload().getPgStreams()); + StringEntity entity = new StringEntity(body); + entity.setContentType("application/json"); + post.setEntity(new StringEntity(body)); + } catch (UnsupportedEncodingException | MalformedURLException e) { + throw new APPCException(e); + } + + HttpClient client = getHttpClient(); + + int httpCode = 0; + String respBody = null; + try { + HttpResponse response = client.execute(post); + httpCode = response.getStatusLine().getStatusCode(); + respBody = IOUtils.toString(response.getEntity().getContent()); + } catch (IOException e) { + throw new APPCException(e); + } + + if (httpCode == 200 && respBody != null) { + JSONObject json; + try { + json = Mapper.toJsonObject(respBody); + } catch (Exception e) { + LOG.error("Error prcoessing response from provider. Could not map response to json", e); + throw new APPCException("APPC has an unknown RPC error"); + } + boolean success; + String reason; + try { + JSONObject header = json.getJSONObject("output").getJSONObject("common-response-header"); + success = header.getBoolean("success"); + reason = header.getString("reason"); + } catch (Exception e) { + LOG.error("Unknown error prcoessing failed response from provider. Json not in expected format", e); + throw new APPCException("APPC has an unknown RPC error"); + } + if (success) { + return true; + } + String reasonStr = reason == null ? "Unknown" : reason; + LOG.warn(String.format("Topology Operation [%s] failed. Reason: %s", msg.getHeader().getRequestID(), reasonStr)); + throw new APPCException(reasonStr); + + } + throw new APPCException(String.format("Unexpected response from endpoint: [%d] - %s ", httpCode, respBody)); + } + + /** + * Updates the static var URL and returns the value; + * + * @return The new value of URL + */ + public static String getUrl() { + return url.toExternalForm(); + } + + public static void setUrl(String newUrl) { + try { + url = new URL(newUrl); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + /** + * Sets the basic authentication header for the given user and password. If either entry is null then set basic auth + * to null + * + * @param user + * The user with optional domain name + * @param password + * The password for the user + * @return The new value of the basic auth string that will be used in the request headers + */ + public static String setAuthentication(String user, String password) { + if (user != null && password != null) { + String authStr = user + ":" + password; + basic_auth = new String(Base64.encodeBase64(authStr.getBytes())); + } else { + basic_auth = null; + } + return basic_auth; + } + + /** + * Builds the request body for a topology operation + * + * @param id + * The request id + * @param url + * The vm's url + * + * @param pgstreams + * The streams to send to the traffic generator + * + * @return A String containing the request body + */ + private static String buildReqest(String id, String url, String pgstreams) { + + return String.format(TEMPLATE, id, url, pgstreams); + } + + @SuppressWarnings("deprecation") + private static HttpClient getHttpClient() throws APPCException { + HttpClient client; + if (url.getProtocol().equals("https")) { + try { + KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); + trustStore.load(null, null); + MySSLSocketFactory sf = new MySSLSocketFactory(trustStore); + sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); + + HttpParams params = new BasicHttpParams(); + HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); + HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); + + SchemeRegistry registry = new SchemeRegistry(); + registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + registry.register(new Scheme("https", sf, 443)); + registry.register(new Scheme("https", sf, 8443)); + registry.register(new Scheme("http", sf, 8181)); + + ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); + client = new DefaultHttpClient(ccm, params); + } catch (Exception e) { + client = new DefaultHttpClient(); + } + } else if (url.getProtocol().equals("http")) { + client = new DefaultHttpClient(); + } else { + throw new APPCException( + "The provider.topology.url property is invalid. The url did not start with http[s]"); + } + return client; + } + + @SuppressWarnings("deprecation") + public static class MySSLSocketFactory extends SSLSocketFactory { + private SSLContext sslContext = SSLContext.getInstance("TLS"); + + public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, + KeyStoreException, UnrecoverableKeyException { + super(truststore); + + TrustManager tm = new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; + } + }; + + sslContext.init(null, new TrustManager[] { + tm + }, null); + } + + @Override + public Socket createSocket(Socket socket, String host, int port, boolean autoClose) + throws IOException, UnknownHostException { + return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); + } + + @Override + public Socket createSocket() throws IOException { + return sslContext.getSocketFactory().createSocket(); + } + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/impl/WorkerImpl.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/impl/WorkerImpl.java new file mode 100644 index 000000000..52bcd2f5e --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/impl/WorkerImpl.java @@ -0,0 +1,82 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL1607.impl; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.listener.EventHandler; +import org.openecomp.appc.listener.CL1607.model.IncomingMessage; +import org.openecomp.appc.listener.CL1607.model.Status; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +public class WorkerImpl implements Runnable { + + private final EELFLogger LOG = EELFManager.getInstance().getLogger(WorkerImpl.class); + + // Should have all of the data we need for processing + private IncomingMessage event; + + // So we can post messages from inside the worker. + private EventHandler dmaap; + + public WorkerImpl(IncomingMessage message, EventHandler dmaap) { + this.event = message; + this.dmaap = dmaap; + } + + @Override + public void run() { + LOG.debug(String.format("Started working on %s", event.getHeader().getRequestID())); + + dmaap.postStatus(event.toOutgoing(Status.ACCEPTED)); + // Run the dg in a try catch to handle all exceptions and update the + // message at the end + try { + if (doDG(event)) { + dmaap.postStatus(event.toOutgoing(Status.SUCCESS)); + LOG.debug(String.format("Event %s finished successfully", event.getHeader().getRequestID())); + } else { + // Should never happen. Exception with message should be thrown instead. + LOG.error(String.format( + "We somehow returned false from doDG() instead of throwing exception. Incoming event [%s]", + event.toJson().toString())); + dmaap.postStatus(event.toOutgoing(Status.FAILURE)); + } + + } catch (Exception e) { + // Unknown exception from DG method. Fail and pass the exception + // along + String msg = "Exception: " + e.getMessage(); + LOG.warn(String.format("Event %s finished with failure. %s", event.getHeader().getRequestID(), msg)); + //TODO: should a message be included? there is nothing in the API spec for a msg? + //dmaap.postStatus(event.toOutgoing(Status.FAILURE, msg)); + dmaap.postStatus(event.toOutgoing(Status.FAILURE)); + } + + LOG.debug("Done working on " + event.getHeader().getRequestID()); + } + + private boolean doDG(IncomingMessage msg) throws APPCException { + return ProviderOperations.topologyDG(msg); + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/Action.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/Action.java new file mode 100644 index 000000000..9e7e923be --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/Action.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL1607.model; + +public enum Action { + Restart("Restart"), Rebuild("Rebuild"), Migrate("Migrate"), Evacuate("Evacuate"), Snapshot("Snapshot"),modifyconfig("ModifyConfig"); + + /** + * Converts the string to an Action + * + * @param value + * The string to try and convert. Is case insensitive + * @return The action matching the string or null if no match was found. + */ + public static Action toAction(String value) { + if (value != null) { + for (Action e : values()) { + if (e.getValue().toUpperCase().equals(value.toUpperCase())) { + return e; + } + } + } + + return null; + } + + private String value; + + private Action(String valueToUse) { + value = valueToUse; + } + + public final String getValue() { + return value; + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/CommonMessage.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/CommonMessage.java new file mode 100644 index 000000000..80a78095b --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/CommonMessage.java @@ -0,0 +1,340 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL1607.model; + +import java.io.Serializable; +import java.util.Collection; + +import org.json.JSONObject; +import org.openecomp.appc.listener.util.Mapper; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * This class holds attributes that are common to DMaaP messages both coming in from DCAE and being sent out by APPC + * + */ +@JsonSerialize(include = Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class CommonMessage implements Serializable { + /* + * { "CommonHeader": { "TimeStamp": "0000-00-00T00:00:00.000Z", "APIver": "1.01", "OriginatorID": "policy.pdp01", + * "RequestID": "b74d13c5-bb26-4b04-992c-4679dfc8280e", "SubrequestID": "1" }, "Action": "RESTART", "Payload": { + * "VServerSelfLink": + * "http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345", + * "VNF_NAME": "test", "VMID": "abc12345-1234-5678-890a-abcdefg12345", "TenantID": + * "abcde12345fghijk6789lmnopq123rst", "LOC_ID": "Test", "in-maint": "false", "Identity": + * "http://example.com:5000/v2.0", "Prov_status": "ACTIVE", "OAM_IPV4": "192.168.1.2", + * "is-closed-loop-disabled": "false", "VM_NAME": "basx0001vm034", "OAM_IPV6": "aaaa::bbbb:cccc:dddd:eeee/64" } } + */ + + private static final long serialVersionUID = 1L; + + /* + * The common header + */ + @JsonProperty("CommonHeader") + private CommonHeader header; + + /* + * The payload + */ + @JsonProperty("Payload") + private Payload payload; + + @JsonIgnore + private long startTime = System.currentTimeMillis(); + + /* + * Getters and Setters + */ + + public long getStartTime() { + return startTime; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + } + + /** + * @return the header + */ + public CommonHeader getHeader() { + return header; + } + + /** + * @param header + * the header to set + */ + public void setHeader(CommonHeader header) { + this.header = header; + } + + /** + * @return the payload + */ + public Payload getPayload() { + return payload; + } + + /** + * @param payload + * the payload to set + */ + public void setPayload(Payload payload) { + this.payload = payload; + } + + /** + * Convenience method to return a json representation of this object. + * + * @return The json representation of this object + */ + public JSONObject toJson() { + return Mapper.toJsonObject(this); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static class CommonHeader { + /* + * "CommonHeader": { "TimeStamp": "2016-05-11T13:53:53.146Z", "APIver": "1.01", "OriginatorID": "policy.pdp01", + * "RequestID": "b74d13c5-bb26-4b04-992c-4679dfc8280e", "SubrequestID": "1" } + */ + + /* + * The timestamp of the message + */ + @JsonProperty("TimeStamp") + private String timeStamp; + + /* + * The API version of the message + */ + @JsonProperty("APIver") + private String apiVer; + + /* + * The Originator ID of the message + */ + @JsonProperty("OriginatorID") + private String originatorId; + + /* + * The Request Id of the message + */ + @JsonProperty("RequestID") + private String requestID; + + /* + * The Subrequest Id of the message + */ + @JsonProperty("SubrequestID") + private String subRequestId; + + /** + * @return the timeStamp + */ + public String getTimeStamp() { + return timeStamp; + } + + /** + * @param timeStamp + * the timeStamp to set + */ + public void setTimeStamp(String timeStamp) { + this.timeStamp = timeStamp; + } + + /** + * @return the apiVer + */ + public String getApiVer() { + return apiVer; + } + + /** + * @param apiVer + * the apiVer to set + */ + public void setApiVer(String apiVer) { + this.apiVer = apiVer; + } + + /** + * @return the originatorId + */ + public String getOriginatorId() { + return originatorId; + } + + /** + * @param originatorId + * the originatorId to set + */ + public void setOriginatorId(String originatorId) { + this.originatorId = originatorId; + } + + /** + * @return the requestID + */ + public String getRequestID() { + return requestID; + } + + /** + * @param requestID + * the requestID to set + */ + public void setRequestID(String requestID) { + this.requestID = requestID; + } + + /** + * @return the subRequestId + */ + public String getSubRequestId() { + return subRequestId; + } + + /** + * @param subRequestId + * the subRequestId to set + */ + public void setSubRequestId(String subRequestId) { + this.subRequestId = subRequestId; + } + }; + + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Payload { + /* + * "Payload": { "VServerSelfLink": + * "http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345", + * "VNF_NAME": "test", "VMID": "abc12345-1234-5678-890a-abcdefg12345", "TenantID": + * "abcde12345fghijk6789lmnopq123rst", "LOC_ID": "Test", "in-maint": "false", "Identity": + * "http://example.com:5000/v2.0", "Prov_status": "ACTIVE", "OAM_IPV4": "192.168.1.2", + * "is-closed-loop-disabled": "false", "VM_NAME": "test", "OAM_IPV6": "aaaa::bbbb:cccc:dddd:eeee/64" } + */ + + /* + * The TenantID of the message + */ + @JsonProperty("generic-vnf.vnf-id") + private String genericVnfId; + + /** + * @return the TenantID + */ + public String getGenericVnfId() { + return genericVnfId; + } + + /** + * @param TenantID + * the TenantID to set + */ + public void setGenericVnfId(String genericVnfId) { + this.genericVnfId = genericVnfId; + } + + @JsonProperty("pg-streams") + private pgStreams pgStreams; + + /** + * @return the TenantID + */ + + public String getPgStreams() { + String r = "{\\\"pg-streams\\\": {\\\"pg-stream\\\":["; + boolean first = true; + for(pgStream p : this.pgStreams.streams){ + String n = "{\\\"id\\\":\\\""+p.getId()+"\\\", \\\"is-enabled\\\":\\\""+p.getIsEnabled()+"\\\"}"; + if(!first){ + r = r.concat(","); + } + first = false; + r = r.concat(n); + } + r= r.concat("]}}"); + return r; + } + + /** + * @param TenantID + * the TenantID to set + */ + public void setPgStreams(pgStreams pgStreams) { + this.pgStreams = pgStreams; + } + + + + + + }; + @JsonIgnoreProperties(ignoreUnknown = true) + public static class pgStreams { + @JsonProperty("pg-stream") + private Collection<pgStream> streams; + + public Collection<pgStream> getStreams() { + return streams; + } + + public void setStreams(Collection<pgStream> streams) { + this.streams = streams; + } + + + }; + @JsonIgnoreProperties(ignoreUnknown = true) + public static class pgStream{ + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getIsEnabled() { + return isEnabled; + } + public void setIsEnabled(String isEnabled) { + this.isEnabled = isEnabled; + } + @JsonProperty("id") + private String id; + @JsonProperty("is-enabled") + private String isEnabled; + }; + + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/IncomingMessage.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/IncomingMessage.java new file mode 100644 index 000000000..62d4d1b7d --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/IncomingMessage.java @@ -0,0 +1,88 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL1607.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion; + +/** + * This class represents a message coming in from DCAE. + * + */ +@JsonSerialize(include = Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class IncomingMessage extends CommonMessage { + + private static final long serialVersionUID = 1L; + + /* + * The action being requested. Its presence signals that it is an incoming message and it is not present on outgoing + * messages + */ + //TODO; use enum + @JsonProperty("Action") + private String action; + + + public String getRequest() { + return action; + } + + @JsonIgnore + public Action getAction() { + return Action.toAction(action); + } + + public void setRequest(String request) { + this.action = request; + } + +// @Override +// public String toString() { +// String time = getRequestTime() != null ? getRequestTime() : "N/A"; +// // String req = request != null ? request : "N/A"; +// return String.format("[%s - %s]", time, getId()); +// } + +// public String toOutgoing(Status status) { +// return toOutgoing(status); +// } + + public String toOutgoing(Status status) { + OutgoingMessage out = new OutgoingMessage(this); + out.setResponse(status); + return out.toResponse().toString(); + } + + /** + * Determines if this message should be parsed parsed. Will eventually check that the message is well formed, has + * all required fields, and had not exceeded any timing restrictions. + * + * @return True if the message should be parsed. False otherwise + */ + public boolean isValid() { + return true; + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/OutgoingMessage.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/OutgoingMessage.java new file mode 100644 index 000000000..7b766212d --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/OutgoingMessage.java @@ -0,0 +1,192 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL1607.model; + +import java.net.InetAddress; +import java.security.SecureRandom; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +import org.json.JSONObject; +import org.openecomp.appc.listener.util.Mapper; +import org.openecomp.appc.util.Time; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion; + +/** + * This class represents a message being sent out to DMaaP by APPC to update listeners on the status of a request + * + */ +@JsonSerialize(include = Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class OutgoingMessage extends CommonMessage { + + public OutgoingMessage() { + + } + + public OutgoingMessage(IncomingMessage msg) { + setHeader(msg.getHeader()); + setPayload(msg.getPayload()); +// setId(msg.getId()); +// setOriginalRequest(msg.getRequest()); +// setRequestClient(msg.getRequestClient()); +// setRequestTime(msg.getRequestTime()); +// setVmName(msg.getVmName()); +// setFromSystem(generateFrom()); +// setResponse(Status.PENDING); +// setPolicyName(msg.getPolicyName()); +// setPolicyVersion(msg.getPolicyVersion()); +// setStartTime(msg.getStartTime()); + } + + private static final long serialVersionUID = -5447940920271469613L; + /* + * The status of the response + */ + @JsonProperty("Status") + private OutStatus status; + + /** + * @return the status + */ + public OutStatus getStatus() { + return status; + } + + /** + * @param status the status to set + */ + public void setStatus(OutStatus status) { + this.status = status; + } + + public void updateResponseTime() { + SecureRandom rand = new SecureRandom(); + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss.SSS"); + df.setTimeZone(TimeZone.getTimeZone("UTC")); + String date = df.format(new Date(Time.utcTime())); + //this.responseTime = String.format("%s%03d", date, rand.nextInt(1000)); + } + + public String generateFrom() { + String name; + try { + InetAddress iAddress = InetAddress.getLocalHost(); + name = iAddress.getCanonicalHostName(); + } catch (Exception e) { + // Could not get anything from the InetAddress + name = "UnknownHost"; + } + return "appc@" + name; + } + + public JSONObject toResponse() { + updateResponseTime(); + JSONObject json = Mapper.toJsonObject(this); + + if (!json.has("message")) { + // If there is no message, parrot the status (response field) + // TODO - Can this be removed for 1602 making message truely optional? + //json.put("message", this.getResponse().toString()); + } + + // Removed duplication of status from message for 1602 + // json.put("message", String.format("%s: %s", request, json.get("message"))); + + return json; + } + +// @Override +// public String toString() { +// return String.format("%s - %s", getId(), getResponse()); +// } + + public static class OutStatus{ + @JsonProperty("Code") + private String code; + + @JsonProperty("Value") + private String value; + + /** + * @return the code + */ + public String getCode() { + return code; + } + + /** + * @param code the code to set + */ + public void setCode(String code) { + this.code = code; + } + + /** + * @return the value + */ + public String getValue() { + return value; + } + + /** + * @param value the value to set + */ + public void setValue(String value) { + this.value = value; + } + + } + + public void setResponse(Status newStatus) { + if(this.status == null){ + this.status = new OutStatus(); + } + + switch (newStatus){ + case ACCEPTED: + this.status.setValue(newStatus.getValue()); + this.status.setCode("100"); + break; + + case FAILURE: + this.status.setValue(newStatus.getValue()); + this.status.setCode("500"); + break; + + case SUCCESS: + this.status.setValue(newStatus.getValue()); + this.status.setCode("400"); + break; + default: + break; + + } + + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/Status.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/Status.java new file mode 100644 index 000000000..f7ec8febd --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/Status.java @@ -0,0 +1,69 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL1607.model; + +public enum Status { + /* + * APP-C acknowledges that it has read the event off of the wire. This is the initial status of an OutgoingEvent + */ + ACCEPTED("ACCEPTED"), + + /* + * APP-C has finished processing the event without errors + */ + SUCCESS("SUCCESS"), + + /* + * APP-C has finished processing the event with errors + */ + FAILURE("FAILURE"); + + /** + * Converts the string to an Status + * + * @param value + * The string to try and convert. Is case insensitive + * @return The status matching the string or null if no match was found. + */ + public static Status toStatus(String value) { + if (value != null) { + for (Status e : values()) { + if (e.getValue().toUpperCase().equals(value.toUpperCase())) { + return e; + } + } + } + + return null; + } + + private String value; + + private Status(String valueToUse) { + value = valueToUse; + } + + public final String getValue() { + return value; + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/Controller.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/Controller.java new file mode 100644 index 000000000..66793e248 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/Controller.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener; + +import java.util.Map; + +/** + * A controller is responsible for creating a listener for each ListenerProperties object that is passed in to it on + * instantiation. The controller will create a thread pool that will contain all of the listener threads so no listener + * can crash the controller. + * + */ +public interface Controller { + + /** + * Creates a new thread in the thread pool for an implementation of the {@see #Listener} class set in the + * ListenerProperties. This thread is run immediately after it is created. + */ + public void start(); + + /** + * Stops each of the listeners known by this controller. Takes an optional parameter that indicates the the listener + * should stop immediately rather than waiting for all threads to complete. + * + * @param stopNow + * Determines what method the listeners should use to shutdown. If true, listeners will use the stopNow() + * method. Otherwise they will use the stop() method. + */ + public void stop(boolean stopNow); + + /** + * @return A Map of ListenerProperties and the Listener object that is running in the controllers thread pool. + */ + public Map<ListenerProperties, Listener> getListeners(); + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/EventHandler.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/EventHandler.java new file mode 100644 index 000000000..5b2906f3c --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/EventHandler.java @@ -0,0 +1,185 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener; + +import java.util.Collection; +import java.util.List; +import java.util.Set; + +/** + * EventHandler defines a class that wraps DMaaP operations (most notably Get Message and Post Message) to make them + * easier to use. + * + */ +public interface EventHandler { + + /** + * Gets a list of messages as Strings on the read topic. + * + * @return A list of String messages. Never returns null. + */ + public List<String> getIncomingEvents(); + + /** + * Gets a list of messages as String on the read topic. + * + * @param limit + * The maximum amount of entries to return + * @return A list of String messages. Never returns null. + */ + public List<String> getIncomingEvents(int limit); + + /** + * Gets a list of messages Mapped to the given Class. If a message cannot be mapped to that class, it is discarded. + * + * @param cls + * The class to map the message to. + * @return A list of objects of the provided class. Never returns null. + */ + public <T> List<T> getIncomingEvents(Class<T> cls); + + /** + * Gets a list of messages Mapped to the given Class. If a message cannot be mapped to that class, it is discarded. + * + * @param cls + * The class to map the message to. + * @param limit + * The maximum amount of entries to return + * @return A list of objects of the provided class. Never returns null. + */ + public <T> List<T> getIncomingEvents(Class<T> cls, int limit); + + /** + * Posts the String message to the write topic(s). + * + * @param event + * The String to post. + */ + public void postStatus(String event); + + /** + * Posts the String message to the write topic(s) on the specified partition. Partitions are only used to guarantee + * ordering and do not impact if data is retreived. + * + * @param partition + * The partition to post to or null if no partition should be used. + * @param event + * The String to post. + */ + public void postStatus(String partition, String event); + + /** + * @return The client/group id used to read messages + */ + public String getClientId(); + + /** + * Set the client/group id used to read messages + * + * @param clientId + * The new clientId to use + */ + public void setClientId(String clientId); + + /** + * @return The client/group name to use. + */ + public String getClientName(); + + /** + * Set the client/group name used to read messages. + * + * @param clientName + * The new clientName to use + */ + public void setClientName(String clientName); + + /** + * @return The name of the topic to read from + */ + public String getReadTopic(); + + /** + * Set the name of the topic to read from. + * + * @param topic + * The new topic to read from + */ + public void setReadTopic(String topic); + + /** + * @return The name of the topic to write to + */ + public Set<String> getWriteTopics(); + + /** + * Set the name of the topic to write to + * + * @param topic + * The new topic to write to + */ + public void setWriteTopics(Set<String> topic); + + /** + * Adds a DMaaP host to the host pool + * + * @param host + * The host to add to the pool in <host>:<port> format + */ + public void addToPool(String host); + + /** + * Remove the host name from the pool if it exists + * + * @param host + * The host to add to the pool in <host>:<port> format + */ + public void removeFromPool(String host); + + /** + * Get all of the hosts in the DMaaP pool + * + * @return A collection of host in <host>:<port> format + */ + public Collection<String> getPool(); + + /** + * Clear any provided api credentials and make future requests as an unauthenticated user + */ + public void clearCredentials(); + + /** + * Set the api credentials and make future requests as an authenticated user + * + * @param access + * The access portion of the credentials (either user name or api key) + * @param secret + * The secret portion of the credentials (either password or api secret) + */ + public void setCredentials(String access, String secret); + + /** + * Close consumer/producer DMaaP clients + */ + public void closeClients(); + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/conv/Converter.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/conv/Converter.java new file mode 100644 index 000000000..021dfefc8 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/conv/Converter.java @@ -0,0 +1,85 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.LCM.conv; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.*; +import org.apache.commons.lang3.StringUtils; +import org.json.JSONObject; +import org.openecomp.appc.listener.LCM.model.DmaapMessage; +import org.openecomp.appc.listener.LCM.model.DmaapOutgoingMessage; +import org.openecomp.appc.listener.util.Mapper; + + +public class Converter { + + + public static DmaapOutgoingMessage convJsonNodeToDmaapOutgoingMessage(JsonNode inObj, String rpcName) { + DmaapOutgoingMessage outObj = new DmaapOutgoingMessage(); + outObj.setBody(inObj); + outObj.setRpcName(rpcName); + return outObj; + } + + public static String convDmaapOutgoingMessageToJsonString(DmaapMessage inObj) throws JsonProcessingException { +// return Mapper.toJsonString(inObj); + ObjectMapper objectMapper = new ObjectMapper(); + ObjectWriter writer = objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL).configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY,true) + .writer().withFeatures(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS); + return writer.writeValueAsString(inObj); + + } + + public static DmaapOutgoingMessage buildDmaapOutgoingMessageWithUnexpectedError(JsonNode dmaapInputBody, String rpcName,Exception inputException) { + DmaapOutgoingMessage dmaapOutgoingMessage = null; + String errMsg = StringUtils.isEmpty(inputException.getMessage())? inputException.toString() : inputException.getMessage(); + JSONObject commonHeaderJsonObject = Mapper.toJsonObject(dmaapInputBody.get("input").get("common-header")); + JSONObject jsonObjectOutput = new JSONObject().accumulate("common-header", commonHeaderJsonObject).accumulate("status", new JSONObject().accumulate("code",200).accumulate("value",errMsg)); + dmaapOutgoingMessage = new DmaapOutgoingMessage(); + dmaapOutgoingMessage.setRpcName(rpcName); + JSONObject jsonObjectBody = new JSONObject().accumulate("output",jsonObjectOutput); + JsonNode jsonNodeBody = Mapper.toJsonNodeFromJsonString(jsonObjectBody.toString()); + dmaapOutgoingMessage.setBody(jsonNodeBody); + return dmaapOutgoingMessage; + } + + public static String extractRequestIdWithSubId(JsonNode dmaapBody) { + String requestId; + //TODO: null pointer exception if dmaapBody is null, check if null or ensure is not null before calling + JsonNode commonHeaderJsonNode = dmaapBody.get("input").get("common-header"); + requestId = commonHeaderJsonNode.get("request-id").asText(); + requestId = requestId != null ? requestId : ""; + String subRequestId = commonHeaderJsonNode.get("sub-request-id").asText(); + if(!StringUtils.isEmpty(subRequestId)){ + requestId = requestId +"-"+subRequestId; + } + return requestId; + } + + public static Integer extractStatusCode(JsonNode event) { + Integer statusCode; + statusCode = event.get("output").get("status").get("code").asInt(); + return statusCode; + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/impl/ListenerImpl.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/impl/ListenerImpl.java new file mode 100644 index 000000000..dd877e98a --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/impl/ListenerImpl.java @@ -0,0 +1,159 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.LCM.impl; + +import com.fasterxml.jackson.databind.JsonNode; +import org.apache.commons.lang3.StringUtils; +import org.openecomp.appc.listener.AbstractListener; +import org.openecomp.appc.listener.ListenerProperties; +import org.openecomp.appc.listener.LCM.conv.Converter; +import org.openecomp.appc.listener.LCM.model.DmaapIncomingMessage; +import org.openecomp.appc.listener.LCM.operation.ProviderOperations; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; +import java.util.concurrent.RejectedExecutionException; + +public class ListenerImpl extends AbstractListener { + + private final EELFLogger LOG = EELFManager.getInstance().getLogger(ListenerImpl.class); + + private long startTime = 0; + + public ListenerImpl(ListenerProperties props) { + super(props); + + String url = props.getProperty("provider.url"); + LOG.info("DMaaP Provider Endpoint: " + url); + ProviderOperations.setUrl(url); + + // Set Basic Auth + String user = props.getProperty("provider.user"); + String pass = props.getProperty("provider.pass"); + ProviderOperations.setAuthentication(user, pass); + } + + @Override + public void run() { + // Some vars for benchmarking + startTime = System.currentTimeMillis(); + + LOG.info("Running DMaaP Listener"); + + while (run.get()) { + // Only update if the queue is low. otherwise we read in more + // messages than we need + try { + if (executor.getQueue().size() <= QUEUED_MIN) { + LOG.debug("DMaaP queue running low. Querying for more jobs"); + + + List<DmaapIncomingMessage> messages = dmaap.getIncomingEvents(DmaapIncomingMessage.class, QUEUED_MAX); + LOG.debug(String.format("Read %d messages from dmaap", messages.size())); + for (DmaapIncomingMessage incoming : messages) { + // Acknowledge that we read the event + if (isValid(incoming)) { + String requestIdWithSubId = getRequestIdWithSubId(incoming.getBody()); + LOG.info("Acknowledging Message: " + requestIdWithSubId); +// dmaap.postStatus(incoming.toOutgoing(OperationStatus.PENDING)); + } + } + for (DmaapIncomingMessage incoming : messages) { + String requestIdWithSubId = getRequestIdWithSubId(incoming.getBody()); + // Add to pool if still running + if (run.get()) { + if (isValid(incoming)) { + LOG.info(String.format("Adding DMaaP message to pool queue [%s]", requestIdWithSubId)); + try { + executor.execute(new WorkerImpl(incoming.getRpcName(),incoming.getBody(), dmaap)); + } catch (RejectedExecutionException rejectEx) { + LOG.error("Task Rejected: ", rejectEx); + } + } else { + // Badly formed message + LOG.error("Message was not valid. Rejecting message: "+incoming); + } + } else { + if (isValid(incoming)) { + LOG.info("Run stopped. Orphaning Message: " + requestIdWithSubId); + } + else { + // Badly formed message + LOG.error("Message was not valid. Rejecting message: "+incoming); + } + } + } + } + } catch (Exception e) { + LOG.error("Exception " + e.getClass().getSimpleName() + " caught in DMaaP listener"); + LOG.error(EELFResourceManager.format(e)); + LOG.error("DMaaP Listener logging and ignoring the exception, continue..."); + } + } + + LOG.info("Stopping DMaaP Listener thread"); + + // We've told the listener to stop + // TODO - Should we: + // 1) Put a message back on the queue indicating that APP-C never got to + // the message + // or + // 2) Let downstream figure it out after timeout between PENDING and + // ACTIVE messages + } + + private boolean isValid(DmaapIncomingMessage incoming) { + return ((incoming != null) && + incoming.getBody() != null + && !StringUtils.isEmpty(incoming.getRpcName())); + } + + @Override + public String getBenchmark() { + long time = System.currentTimeMillis(); + DateFormat df = new SimpleDateFormat("HH:mm:ss"); + df.setTimeZone(TimeZone.getTimeZone("UTC")); + String runningTime = df.format(new Date(time - startTime)); + + String out = String.format("Running for %s and completed %d jobs using %d threads.", runningTime, + executor.getCompletedTaskCount(), executor.getPoolSize()); + LOG.info("***BENCHMARK*** " + out); + return out; + } + + private String getRequestIdWithSubId(JsonNode event){ + String requestId = ""; + try { + requestId = Converter.extractRequestIdWithSubId(event); + } catch (Exception e) { + LOG.error("failed to parse request-id and sub-request-id. Json not in expected format", e); + } + return requestId; + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/impl/WorkerImpl.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/impl/WorkerImpl.java new file mode 100644 index 000000000..af8334ee4 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/impl/WorkerImpl.java @@ -0,0 +1,120 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.LCM.impl; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.listener.EventHandler; +import org.openecomp.appc.listener.LCM.conv.Converter; +import org.openecomp.appc.listener.LCM.model.DmaapOutgoingMessage; +import org.openecomp.appc.listener.LCM.operation.ProviderOperations; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; + +public class WorkerImpl implements Runnable { + + private final EELFLogger LOG = EELFManager.getInstance().getLogger(WorkerImpl.class); + + // Should have all of the data we need for processing + private JsonNode event; + + // So we can post messages from inside the worker. + private EventHandler dmaap; + private String rpcName; + + public WorkerImpl(String rpcName,JsonNode message, EventHandler dmaap) { + this.rpcName = rpcName; + this.event = message; + this.dmaap = dmaap; + } + + @Override + public void run() { + String requestIdWithSubId = extractRequestIdWithSubId(event); + LOG.debug(String.format("Started working on %s", requestIdWithSubId)); + + // Run the dg in a try catch to handle all exceptions and update the + // message at the end + try { + JsonNode outputJsonNode = doDG(rpcName, event); + DmaapOutgoingMessage dmaapOutgoingMessage= Converter.convJsonNodeToDmaapOutgoingMessage(outputJsonNode,rpcName); + postMessageToDMaaP(dmaapOutgoingMessage,requestIdWithSubId); + Integer statusCode = extractStatusCode(dmaapOutgoingMessage.getBody()); + if (ProviderOperations.isSucceeded(statusCode)) { + LOG.debug(String.format("Event %s finished successfully", requestIdWithSubId)); + } else { + LOG.warn(String.format("Event %s failed", requestIdWithSubId)); + } + + } catch (Exception e) { + // Unknown exception from DG method. Fail and pass the exception + // along + String msg = "Exception: " + e.getMessage(); + LOG.error(String.format("Event %s finished with failure. %s", requestIdWithSubId, msg)); + DmaapOutgoingMessage dmaapOutgoingMessage= Converter.buildDmaapOutgoingMessageWithUnexpectedError(event,rpcName,e); + postMessageToDMaaP(dmaapOutgoingMessage,requestIdWithSubId); + } + + LOG.debug("Done working on " + requestIdWithSubId); + } + + + private Integer extractStatusCode(JsonNode event) { + Integer statusCode = null; + try { + statusCode = Converter.extractStatusCode(event); + } catch (Exception e) { + LOG.error("failed to parse statusCode. Json not in expected format", e); + } + return statusCode; + } + + + private String extractRequestIdWithSubId(JsonNode event){ + String requestId = ""; + try { + requestId = Converter.extractRequestIdWithSubId(event); + } catch (Exception e) { + LOG.error("failed to parse request-id and sub-request-id. Json not in expected format", e); + } + return requestId; + } + + + + private void postMessageToDMaaP(DmaapOutgoingMessage dmaapOutgoingMessage,String requestIdWithSubId) { + String dmaapOutgoingMessageJsonString; + try { + dmaapOutgoingMessageJsonString = Converter.convDmaapOutgoingMessageToJsonString(dmaapOutgoingMessage); + dmaap.postStatus(dmaapOutgoingMessage.getCambriaPartition(),dmaapOutgoingMessageJsonString); + } catch (JsonProcessingException e) { + LOG.error("failed to postMessageToDMaaP requestIdWithSubId: "+requestIdWithSubId+" dmaapOutgoingMessage: "+dmaapOutgoingMessage, e); + } + } + + private JsonNode doDG(String rpcName, JsonNode msg) throws APPCException { + return ProviderOperations.topologyDG(rpcName,msg); + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/ActionIdentifiers.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/ActionIdentifiers.java new file mode 100644 index 000000000..f17b18147 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/ActionIdentifiers.java @@ -0,0 +1,81 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.LCM.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.io.Serializable; + + +public class ActionIdentifiers implements Serializable { + + @JsonProperty("service-instance-id") + private String serviceInstanceId; + @JsonProperty("vnf-id") + private String vnfID; + @JsonProperty("vnfc-name") + private String vnfcName; + @JsonProperty("vserver-id") + private String vserverId; + + public ActionIdentifiers() { + } + + public ActionIdentifiers(ActionIdentifiers actionIdentifiers) { + this.serviceInstanceId=actionIdentifiers.getServiceInstanceId(); + this.vnfID=actionIdentifiers.getVnfID(); + this.vnfcName=actionIdentifiers.getVnfcName(); + this.vserverId=actionIdentifiers.getVserverId(); + } + + public String getServiceInstanceId() { + return serviceInstanceId; + } + + public void setServiceInstanceId(String serviceInstanceId) { + this.serviceInstanceId = serviceInstanceId; + } + + public String getVnfID() { + return vnfID; + } + + public void setVnfID(String vnfID) { + this.vnfID = vnfID; + } + + public String getVnfcName() { + return vnfcName; + } + + public void setVnfcName(String vnfcName) { + this.vnfcName = vnfcName; + } + + public String getVserverId() { + return vserverId; + } + + public void setVserverId(String vserverId) { + this.vserverId = vserverId; + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/CommonHeader.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/CommonHeader.java new file mode 100644 index 000000000..363c6407d --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/CommonHeader.java @@ -0,0 +1,112 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.LCM.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.io.Serializable; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Map; + +import org.openecomp.appc.util.Time; + +public class CommonHeader implements Serializable { + @JsonProperty("timestamp") + private String timeStamp; + @JsonProperty("api-ver") + private String apiVer; + @JsonProperty("originator-id") + private String originatorId; + @JsonProperty("request-id") + private String requestID; + @JsonProperty("sub-request-id") + private String subRequestId; + @JsonProperty("flags") + private Map<String, String> flags; + + private static final DateFormat ZULU_FORMATTER = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SS'Z'"); + + public CommonHeader() { + } + + public CommonHeader(CommonHeader commonHeader) { + // changed to current system time + timeStamp = ZULU_FORMATTER.format(Time.utcDate()); + + apiVer = commonHeader.getApiVer(); + originatorId = commonHeader.getOriginatorId(); + requestID = commonHeader.getRequestID(); + subRequestId = commonHeader.getSubRequestId(); + flags = commonHeader.getFlags(); + } + + + + public String getTimeStamp() { + return timeStamp; + } + + public void setTimeStamp(String timeStamp) { + this.timeStamp = timeStamp; + } + + public String getApiVer() { + return apiVer; + } + + public void setApiVer(String apiVer) { + this.apiVer = apiVer; + } + + public String getRequestID() { + return requestID; + } + + public void setRequestID(String requestID) { + this.requestID = requestID; + } + + public String getOriginatorId() { + return originatorId; + } + + public void setOriginatorId(String originatorId) { + this.originatorId = originatorId; + } + + public String getSubRequestId() { + return subRequestId; + } + + public void setSubRequestId(String subRequestId) { + this.subRequestId = subRequestId; + } + + public Map<String, String> getFlags() { + return flags; + } + + public void setFlags(Map<String, String> flags) { + this.flags = flags; + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/DmaapIncomingMessage.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/DmaapIncomingMessage.java new file mode 100644 index 000000000..ec1e9e767 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/DmaapIncomingMessage.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.LCM.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import org.json.JSONObject; +import org.openecomp.appc.listener.util.Mapper; + +/** + * This class represents a message being sent out to DMaaP by APPC to update listeners on the status of a request + * + */ +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class DmaapIncomingMessage extends DmaapMessage{ + private final static String defaultCambriaPartition = "APP-C"; + + public DmaapIncomingMessage() { + super(); + setCambriaPartition(defaultCambriaPartition); + } + + + @Override + public String toString() { + return "DmaapIncomingMessage{"+super.toString()+"}"; + } +} + diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/DmaapMessage.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/DmaapMessage.java new file mode 100644 index 000000000..56099cb7e --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/DmaapMessage.java @@ -0,0 +1,79 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.LCM.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.JsonNode; + + +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class DmaapMessage{ + + @JsonProperty("cambria.partition") + private String cambriaPartition; + + @JsonProperty("rpc-name") + private String rpcName; + + @JsonProperty("body") + private JsonNode body; + + public DmaapMessage() { + } + + public String getCambriaPartition() { + return cambriaPartition; + } + + public void setCambriaPartition(String cambriaPartition) { + this.cambriaPartition = cambriaPartition; + } + + public String getRpcName() { + return rpcName; + } + + public void setRpcName(String rpcName) { + this.rpcName = rpcName; + } + + public JsonNode getBody() { + return body; + } + + public void setBody(JsonNode body) { + this.body = body; + } + + @Override + public String toString() { + return "DmaapMessage{" + + "cambriaPartition='" + cambriaPartition + '\'' + + ", rpcName='" + rpcName + '\'' + + ", body=" + body + + '}'; + } +} + diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/DmaapOutgoingMessage.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/DmaapOutgoingMessage.java new file mode 100644 index 000000000..6d7cb997e --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/DmaapOutgoingMessage.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.LCM.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import org.json.JSONObject; +import org.openecomp.appc.listener.util.Mapper; + +/** + * This class represents a message being sent out to DMaaP by APPC to update listeners on the status of a request + * + */ +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class DmaapOutgoingMessage extends DmaapMessage{ + private final static String defaultCambriaPartition = "MSO"; + + public DmaapOutgoingMessage() { + super(); + setCambriaPartition(defaultCambriaPartition); + } + + + @Override + public String toString() { + return "DmaapOutgoingMessage{"+super.toString()+"}"; + } +} + diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/InputBody.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/InputBody.java new file mode 100644 index 000000000..6fd0572f3 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/InputBody.java @@ -0,0 +1,102 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.LCM.model; + +import org.openecomp.appc.listener.LCM.operation.OperationStatus; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + + +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class InputBody { + + @JsonProperty("common-header") + private CommonHeader commonHeader; + + @JsonProperty("action-identifiers") + private ActionIdentifiers actionIdentifiers; + + @JsonProperty("action") + private String action; + + @JsonProperty("payload") + private Object payload; + + + public Object getPayload() { + return payload; + } + + public void setPayload(Object payload) { + this.payload = payload; + } + @JsonIgnore + public void setPayloadAsString(String payload) { + this.payload = payload; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public ActionIdentifiers getActionIdentifiers() { + return actionIdentifiers; + } + + public void setActionIdentifiers(ActionIdentifiers actionIdentifiers) { + this.actionIdentifiers = actionIdentifiers; + } + + public CommonHeader getCommonHeader() { + return commonHeader; + } + + public void setCommonHeader(CommonHeader commonHeader) { + this.commonHeader = commonHeader; + } + +// public String toOutgoing(OperationStatus operationStatus) { +// OutputBody out = new OutputBody(this); +// out.setStatus(new ResponseStatus(operationStatus.getCode(), operationStatus.getValue())); +// return out.toResponse().toString(); +// } + +// public String toOutgoing(OperationStatus operationStatus,String islocked) { +// OutputBody out = new OutputBody(this); +// out.setStatus(new ResponseStatus(operationStatus.getCode(), operationStatus.getValue())); +// out.setLocked(islocked); +// return out.toResponse().toString(); +// } + + @JsonIgnore + public boolean isValid() { + return getCommonHeader() != null; + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/OutputBody.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/OutputBody.java new file mode 100644 index 000000000..54b407b5f --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/OutputBody.java @@ -0,0 +1,98 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.LCM.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import org.json.JSONObject; +import org.openecomp.appc.listener.util.Mapper; + +/** + * This class represents a message being sent out to DMaaP by APPC to update listeners on the status of a request + * + */ +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class OutputBody { + + @JsonProperty("common-header") + private CommonHeader header; + + @JsonProperty("status") + private ResponseStatus status; + + @JsonProperty("payload") + private String payload; + + @JsonProperty("locked") + private String locked; + + public OutputBody() { + } + + + public JSONObject toResponse() { + return Mapper.toJsonObject(this); + } + + public OutputBody(InputBody msg) { + this.header = new CommonHeader(msg.getCommonHeader()); + } + + public String getLocked() { + return locked; + } + + public void setLocked(String locked) { + this.locked = locked; + } + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + public CommonHeader getHeader() { + return header; + } + + public void setHeader(CommonHeader header) { + this.header = header; + } + + public ResponseStatus getStatus() { + return status; + } + + public void setStatus(ResponseStatus status) { + this.status = status; + } + + @Override + public String toString() { + return String.format("%s - %s(%s)", getHeader().getRequestID(), getStatus().getCode(), getStatus().getValue()); + } +} + diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/ResponseStatus.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/ResponseStatus.java new file mode 100644 index 000000000..9186c444a --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/ResponseStatus.java @@ -0,0 +1,70 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.LCM.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + + +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class ResponseStatus { + @JsonProperty("code") + private Integer code; + @JsonProperty("message") + private String value; + + public ResponseStatus() { + } + + public ResponseStatus(Integer code, String value) { + this.code = code; + this.value = value; + } + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + code = code; + } + + public String getValue() { + return value; + } + + + + public void setValue(String value) { + value = value; + } + + @Override + public String toString() { + return "ResponseStatus{" + + "code=" + code + + ", value='" + value + '\'' + + '}'; + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/operation/GenericProviderOperationRequestFormatter.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/operation/GenericProviderOperationRequestFormatter.java new file mode 100644 index 000000000..5c54845cc --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/operation/GenericProviderOperationRequestFormatter.java @@ -0,0 +1,115 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.LCM.operation; + +import com.fasterxml.jackson.databind.JsonNode; +import org.json.JSONObject; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.listener.LCM.model.InputBody; +import org.openecomp.appc.listener.LCM.model.ResponseStatus; +import org.openecomp.appc.listener.util.Mapper; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import java.net.URL; + + + +public class GenericProviderOperationRequestFormatter implements ProviderOperationRequestFormatter { + + private final EELFLogger LOG = EELFManager.getInstance().getLogger(GenericProviderOperationRequestFormatter.class); + + //@formatter:off + @SuppressWarnings("nls") + private final static String TEMPLATE = "{\"input\": %s}"; + //@formatter:on + + @Override + public String buildPath(URL url, String rpcName) { + return url.getPath() + ":"+rpcName; + } + +// private String convertActionToUrl(String action) { +// String res = ""; +// switch (action) { +// case "SoftwareUpload": +// res = "software-upload"; +// break; +// case "LiveUpgrade": +// res = "live-upgrade"; +// break; +// case "HealthCheck": +// res = "health-check"; +// break; +// case "CheckLock": +// res = "check-lock"; +// break; +// default : +// res = action; +// } +// return res.toLowerCase(); +// } + + @Override + public String buildRequest(InputBody msg) { + JSONObject jsonObject = Mapper.toJsonObject(msg); + return String.format(TEMPLATE, jsonObject.toString()); + } + +/* @Override + public OperationStatus getOperationStatus(JSONObject responseBody) throws APPCException { + try { + JSONObject status = responseBody.getJSONObject("output").getJSONObject("status"); + return new OperationStatus(String.valueOf(status.getInt("code")), status.getString("message")); + } catch (Exception e) { + LOG.error("Unknown error processing failed response from provider. Json not in expected format", e); + throw new APPCException("APPC has an unknown RPC error"); + } + }*/ + + @Override + public ResponseStatus getResponseStatus(JsonNode responseBody)throws APPCException{ + try { + JsonNode status = responseBody.get("output").get("status"); + return new ResponseStatus(status.get("code").asInt(), status.get("message").asText()); + } catch (Exception e) { + LOG.error("Unknown error processing failed response from provider. Json not in expected format", e); + throw new APPCException("APPC has an unknown RPC error"); + } + } + + @Override + public String getLocked(JSONObject responseBody) throws APPCException { + try { + JSONObject outputObject=responseBody.getJSONObject("output"); + if(outputObject.has("locked")){ + return outputObject.getString("locked"); + }else{ + return null; + } + } catch (Exception e) { + LOG.error("Unknown error processing failed response from provider. Json not in expected format", e); + throw new APPCException("APPC has an unknown RPC error"); + } + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/operation/OperationStatus.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/operation/OperationStatus.java new file mode 100644 index 000000000..b2388af45 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/operation/OperationStatus.java @@ -0,0 +1,66 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.LCM.operation; + + +public class OperationStatus { + public final static OperationStatus PENDING = new OperationStatus("PENDING", "PENDING"); + public final static OperationStatus ACTIVE = new OperationStatus("ACTIVE", "ACTIVE"); + public final static OperationStatus SUCCESS = new OperationStatus("SUCCESS", "SUCCESS"); + public final static OperationStatus FAILURE = new OperationStatus("FAILURE", "FAILURE"); + + private String code; + private String value; + + public OperationStatus() { + } + + + public OperationStatus(String code, String value) { + this.code = code; + this.value = value; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public boolean isSucceeded() { + if (code == null) { + return false; + } + int intCode = Integer.parseInt(code); + return (intCode >= 200) && (intCode < 300); // All 2xx statuses are success + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/operation/ProviderOperationRequestFormatter.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/operation/ProviderOperationRequestFormatter.java new file mode 100644 index 000000000..33aa5b673 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/operation/ProviderOperationRequestFormatter.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.LCM.operation; + +import com.fasterxml.jackson.databind.JsonNode; +import org.json.JSONObject; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.listener.LCM.model.InputBody; +import org.openecomp.appc.listener.LCM.model.ResponseStatus; + +import java.net.URL; + + +public interface ProviderOperationRequestFormatter { + + String buildPath(URL url, String rpcName); + + String buildRequest(InputBody msg); + + ResponseStatus getResponseStatus(JsonNode json)throws APPCException; + + String getLocked(JSONObject json)throws APPCException; +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/operation/ProviderOperations.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/operation/ProviderOperations.java new file mode 100644 index 000000000..f5672a575 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/operation/ProviderOperations.java @@ -0,0 +1,260 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.LCM.operation; + +import com.fasterxml.jackson.databind.JsonNode; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpHeaders; +import org.apache.http.HttpResponse; +import org.apache.http.HttpVersion; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; +import org.apache.http.protocol.HTTP; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.listener.LCM.model.ResponseStatus; +import org.openecomp.appc.listener.util.Mapper; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.Socket; +import java.net.URL; +import java.net.UnknownHostException; +import java.security.*; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +public class ProviderOperations { + + private static final EELFLogger LOG = EELFManager.getInstance().getLogger(ProviderOperations.class); + + private static URL url; + private static String basic_auth; + + private static ProviderOperationRequestFormatter requestFormatter = new GenericProviderOperationRequestFormatter(); + + /** + * Calls the AppcProvider to run a topology directed graph + * + * @param msg The incoming message to be run + * @return True if the result is success. Never returns false and throws an exception instead. + * @throws UnsupportedEncodingException + * @throws Exception if there was a failure processing the request. The exception message is the failure reason. + */ + @SuppressWarnings("nls") + public static JsonNode topologyDG(String rpcName, JsonNode msg) throws APPCException { + if (msg == null) { + throw new APPCException("Provided message was null"); + } + + HttpPost post = null; + try { + + // Concatenate the "action" on the end of the URL + String path = requestFormatter.buildPath(url, rpcName); + URL serviceUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), path); + + post = new HttpPost(serviceUrl.toExternalForm()); + post.setHeader(HttpHeaders.CONTENT_TYPE, "application/json"); + post.setHeader(HttpHeaders.ACCEPT, "application/json"); + + // Set Auth + if (basic_auth != null) { + post.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + basic_auth); + } + + String body = Mapper.toJsonString(msg); + StringEntity entity = new StringEntity(body); + entity.setContentType("application/json"); + post.setEntity(new StringEntity(body)); + } catch (UnsupportedEncodingException | MalformedURLException e) { + throw new APPCException(e); + } + + HttpClient client = getHttpClient(); + + int httpCode = 0; + String respBody = null; + try { + HttpResponse response = client.execute(post); + httpCode = response.getStatusLine().getStatusCode(); + respBody = IOUtils.toString(response.getEntity().getContent()); + } catch (IOException e) { + throw new APPCException(e); + } + + if (httpCode >= 200 && httpCode < 300 && respBody != null) { + JsonNode json; + try { + json = Mapper.toJsonNodeFromJsonString(respBody); + } catch (Exception e) { + LOG.error("Error processing response from provider. Could not map response to json", e); + throw new APPCException("APPC has an unknown RPC error"); + } + + ResponseStatus responseStatus = requestFormatter.getResponseStatus(json); + + if (!isSucceeded(responseStatus.getCode())) { + LOG.warn(String.format("Operation failed [%s]", msg.toString())); + } + + return json; + } + + throw new APPCException(String.format("Unexpected response from endpoint: [%d] - %s ", httpCode, respBody)); + } + + /** + * Updates the static var URL and returns the value; + * + * @return The new value of URL + */ + public static String getUrl() { + return url.toExternalForm(); + } + + public static void setUrl(String newUrl) { + try { + url = new URL(newUrl); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + /** + * Sets the basic authentication header for the given user and password. If either entry is null then set basic auth + * to null + * + * @param user The user with optional domain name + * @param password The password for the user + * @return The new value of the basic auth string that will be used in the request headers + */ + public static String setAuthentication(String user, String password) { + if (user != null && password != null) { + String authStr = user + ":" + password; + basic_auth = new String(Base64.encodeBase64(authStr.getBytes())); + } else { + basic_auth = null; + } + return basic_auth; + } + + @SuppressWarnings("deprecation") + private static HttpClient getHttpClient() throws APPCException { + HttpClient client; + if (url.getProtocol().equals("https")) { + try { + KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); + trustStore.load(null, null); + MySSLSocketFactory sf = new MySSLSocketFactory(trustStore); + sf.setHostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); + + HttpParams params = new BasicHttpParams(); + HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); + HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); + + SchemeRegistry registry = new SchemeRegistry(); + registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + registry.register(new Scheme("https", sf, 443)); + registry.register(new Scheme("https", sf, 8443)); + registry.register(new Scheme("http", sf, 8181)); + + ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); + client = new DefaultHttpClient(ccm, params); + } catch (Exception e) { + client = new DefaultHttpClient(); + } + } else if (url.getProtocol().equals("http")) { + client = new DefaultHttpClient(); + } else { + throw new APPCException( + "The provider.topology.url property is invalid. The url did not start with http[s]"); + } + return client; + } + + @SuppressWarnings("deprecation") + public static class MySSLSocketFactory extends SSLSocketFactory { + private SSLContext sslContext = SSLContext.getInstance("TLS"); + + public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, + KeyStoreException, UnrecoverableKeyException { + super(truststore); + + TrustManager tm = new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; + } + }; + + sslContext.init(null, new TrustManager[]{ + tm + }, null); + } + + @Override + public Socket createSocket(Socket socket, String host, int port, boolean autoClose) + throws IOException, UnknownHostException { + return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); + } + + @Override + public Socket createSocket() throws IOException { + return sslContext.getSocketFactory().createSocket(); + } + } + + public static boolean isSucceeded(Integer code) { + if (code == null) { + return false; + } + return ((code == 100) || (code == 400)); // only 100 & 400 statuses are success + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/Listener.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/Listener.java new file mode 100644 index 000000000..a8e180404 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/Listener.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener; + +/** + * This interface defines a listener that subscribes to a DMaaP topic and continually polls for messages. The + * listener does all operations in the run() method and long running operations should be created in a separate worker + * thread. + * + */ +public interface Listener extends Runnable { + + /** + * Should start a continuous poll to get messages from the message bus only ending when stop() or stopNow() are + * called. + * + * @see java.lang.Runnable#run() + */ + @Override + public void run(); + + /** + * Signals the listener to stop accepting new messages to the queue and to cleanly finish processing all remaining + * messages in the queue. This can take a significant amount of time to complete depending on the thread pool + * characteristics. Similar to {@link #stopNow()} + */ + public void stop(); + + /** + * Signals the listener to stop accepting new messages to the queue and to destroy all remaining messages in the + * queue. This will complete quicker than {@link #stop()} at the cost of discarded requests. Recovery of these + * requests would have to be caught downstream. Similar to {@link #stop()} + */ + public void stopNow(); + + /** + * @return A string that shows various benchmarking data. Can be used by humans to tune the thread pool. + */ + public String getBenchmark(); + + /** + * @return The listener's id when requesting messages from DMaaP. Also known as the group id. + */ + public String getListenerId(); + + /** + * Sets the listener's id to use when requesting messages from DMaaP. Also known as the group id. + * + * @param idString + * The new listener id + */ + public void setListenerId(String idString); +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/ListenerProperties.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/ListenerProperties.java new file mode 100644 index 000000000..c6c374eb0 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/ListenerProperties.java @@ -0,0 +1,319 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener; + +import java.util.Properties; + +/** + * A class for instantiating Listener objects. It is primarily used to hold properties that start with the given prefix. + * It also holds a class that implements {@see Listener} and will be used by the controller to spawn a new listener + * object. + * + * @since Apr 25, 2016 + * @version $Id$ + */ +public class ListenerProperties { + + private String prefix; + + private Class<? extends Listener> listenerClass; + + private Properties props; + + /** + * Creates a new listener object with the given prefix and properties. Any property starting with the prefix is + * added to the internal properties object with the prefix removed. All other properties are ignored. + * ListenerProperties constructor + * + * @param prefix + * The prefix of the properties to load + * @param allProps + * The properties object to load from. + */ + public ListenerProperties(String prefix, Properties allProps) { + this.prefix = prefix; + props = new Properties(); + + String dottedPrefix = String.format("%s.", prefix); + for (String key : allProps.stringPropertyNames()) { + if (key.startsWith(dottedPrefix) && key.length() > dottedPrefix.length()) { + props.put(key.substring(dottedPrefix.length()), allProps.get(key)); + } + } + } + + /** + * @return The prefix of these properties + */ + public String getPrefix() { + return prefix; + } + + /** + * Sets the listener class. Will be used by {@see Controller} to instantiate the Listener thread for this object + * + * @param cls + * The class to be created. Implements {@see Listener} + */ + public void setListenerClass(Class<? extends Listener> cls) { + this.listenerClass = cls; + } + + /** + * @return The class that will be used by {@see Controller} to instantiate the Listener thread for this object + */ + public Class<? extends Listener> getListenerClass() { + return listenerClass; + } + + /** + * Returns a property matching a given KEYS + * + * @param key + * The KEYS object who's value to return. + * @return The value of the property or null if none exists + */ + public String getProperty(KEYS key) { + return getProperty(key, null); + } + + /** + * Returns a property matching a given string. + * + * @param key + * The key who's value to return. + * @return The value of the property or null if none exists + */ + public String getProperty(String key) { + return getProperty(key, null); + } + + /** + * Returns a property matching a given KEYS + * + * @param key + * The KEYS object who's value to return. + * @param defaultValue + * The value to return if the property is not found + * @return The value of the property or null if none exists + */ + public String getProperty(KEYS key, String defaultValue) { + return getProperty(key.getPropertySuffix(), defaultValue); + } + + /** + * Returns a property matching a given string. + * + * @param key + * The key who's value to return. + * @param defaultValue + * The value to return if the property is not found + * @return The value of the property or null if none exists + */ + public String getProperty(String key, String defaultValue) { + return props.getProperty(key, defaultValue); + } + + /** + * @return The properties object containing all properties + */ + public Properties getProperties() { + return props; + } + + /** + * Reads the <i>prefix</i>.disabled property to determine if the listener is disabled and should not be run by the + * controller. Defaults to false if property not set or value cannot be parsed. + * + * @return true if the listener is disabled and should not be started. false if the listener should be start + * normally (default). + */ + public boolean isDisabled() { + return Boolean.valueOf(getProperty(KEYS.DISABLED, "false")); + } + + @Override + public String toString() { + return String.format("%s", prefix); + } + + /** + * The message service types that are available. Choices are DMaaP and DMaaP. + * + * @since Apr 25, 2016 + * @version $Id$ + */ + public enum MessageService { + DMaaP("dmaap"); + + private String val; + + private MessageService(String val) { + this.val = val; + } + + public String getValue() { + return val; + } + + /** + * Tries to match a string to a MessageService. If no match is found, returns the default (DMaaP) + * + * @param input + * the string to try and match + * @return A MessasgeService + */ + public static MessageService parse(String input) { + if (input != null) { + for (MessageService ms : MessageService.values()) { + if (ms.getValue().equals(input.toLowerCase())) { + return ms; + } + } + } + return MessageService.DMaaP; // Default + } + } + + /** + * Set of common properties that will be used by most systems. Primarily relating to DMaaP and ThreadPools + * + * @since Apr 25, 2016 + * @version $Id$ + */ + public enum KEYS { + /** + * Property to determine if the listener should be disabled. If not set, defaults to false + */ + DISABLED("disabled"), + + /** + * Property for the message service type. Should be a lower case string. See MessageService. + */ + MESSAGE_SERVICE("service"), + + /** + * A hostname or comma separated list (no spaces) of hostnames of servers in a cluster. Can have ports included + * as well.<br> + * Examples: + * <ul> + * <li>server1.appc.openecomp.org</li> + * <li>server1.appc.openecomp.org:3904</li> + * <li>server1.appc.openecomp.org,server2.appc.openecomp.org</li> + * </ul> + */ + HOSTS("poolMembers"), + + /** + * The topic that will be used for DMaaP read operations. Can only support a single topic. + */ + TOPIC_READ("topic.read"), + + /** + * The topic or topics that will be used to write to. If multiple topics are provided, should be in a comma + * seperated list with no spaces.<br> + * Examples: + * <ul> + * <li>TOPIC-1</li> + * <li>TOPIC-1,TOPIC-2,ANOTHER-TOPIC</li> + * </ul> + */ + TOPIC_WRITE("topic.write"), + + /** + * The highland park filter to use on read requests. If you are reading and writing to the same topic this must + * be provided. Filter should be in JSON format (not url escaped). + */ + TOPIC_READ_FILTER("topic.read.filter"), + + /** + * The amount of time in seconds that the DMaaP polling connection should stay open for. Recommended to be set + * high (around 60 seconds) as most clients will return immediately and not wait until the timeout is up to + * return if they have data. + */ + TOPIC_READ_TIMEOUT("topic.read.timeout"), + + /** + * The name of the client to use. Should be unique to the application. + */ + CLIENT_NAME("client.name"), + + /** + * The id of the client to use. Should be unique for each instance of the application in an environment. + */ + CLIENT_ID("client.name.id"), + + /** + * The User (DMaaP) to use for authentication. If a user is provided, you must include the + * domain name (e.g. example<b>@example.com</b>). + */ + AUTH_USER_KEY("client.key"), + + /** + * The password (DMaaP) to use for authentication. + */ + AUTH_SECRET_KEY("client.secret"), + + /** + * The minimum amount of size of the queue. A client should request new messages once the queue has dropped + * below this size. + */ + THREADS_MIN_QUEUE("threads.queuesize.min"), + + /** + * The maximum size of the queue. A client will request no new messages once this maximum size has been reached. + */ + THREADS_MAX_QUEUE("threads.queuesize.max"), + + /** + * The minimum size of the worker threads pool. This is the pool each listener will use to launch longer running + * operations. + */ + THREADS_MIN_POOL("threads.poolsize.min"), + + /** + * The maximum size of the worker threads pool. This is the pool each listener will use to launch longer running + * operations. + */ + THREADS_MAX_POOL("threads.poolsize.max"); + + private String suffix; + + private KEYS(String val) { + this.suffix = val; + } + + /** + * @param prefix + * The prefix to prepend + * @return a fully property name that corroponds to what is used in the properties file. Format is PREFIX.KEY + */ + public String getFullProp(String prefix) { + return String.format("%s.%s", prefix, suffix); + } + + public String getPropertySuffix() { + return suffix; + } + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/impl/ControllerImpl.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/impl/ControllerImpl.java new file mode 100644 index 000000000..9e171915a --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/impl/ControllerImpl.java @@ -0,0 +1,126 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.impl; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.lang3.concurrent.BasicThreadFactory; +import org.openecomp.appc.listener.Controller; +import org.openecomp.appc.listener.Listener; +import org.openecomp.appc.listener.ListenerProperties; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + + +/** + * A common implementation of a controller. This controller should not need to be modified to implement new listeners + * + */ +public class ControllerImpl implements Controller { + + private final EELFLogger LOG = EELFManager.getInstance().getLogger(ControllerImpl.class); + + private int LISTENER_COUNT = 1; + + private Map<ListenerProperties, Listener> listeners = null; + + private ThreadPoolExecutor executor; + + /** + * Creates a Controller with the set of listener properties which will be used to start listener threads. + * + * @param properties + * A non null Set of ListenerProperties + */ + public ControllerImpl(Set<ListenerProperties> properties) { + listeners = new HashMap<ListenerProperties, Listener>(); + for (ListenerProperties props : properties) { + if (props.getClass() != null) { + listeners.put(props, null); + } else { + LOG.error(String.format( + "The ListenerProperties %s has no Listener class associated with it and will not run.", props)); + } + } + + LISTENER_COUNT = properties.size(); + + executor = new ThreadPoolExecutor(LISTENER_COUNT, LISTENER_COUNT, 1, TimeUnit.SECONDS, + new ArrayBlockingQueue<Runnable>(LISTENER_COUNT)); + + // Custom Named thread factory + BasicThreadFactory threadFactory = new BasicThreadFactory.Builder().namingPattern("Appc-Listener-%d").build(); + executor.setThreadFactory(threadFactory); + } + + @Override + public void start() { + LOG.info("Starting DMaaP Controller."); + for (ListenerProperties props : listeners.keySet()) { + try { + if (props.isDisabled()) { + LOG.warn(String.format("The listener %s is disabled and will not be run", props.getPrefix())); + } else { + Listener l = props.getListenerClass().getConstructor(ListenerProperties.class).newInstance(props); + l.setListenerId(props.getPrefix()); + listeners.put(props, l); + executor.execute(l); + } + } catch (Exception e) { + e.printStackTrace(); + LOG.error(String.format("Exception while starting listener %s.", props), e); + } + } + } + + @Override + public void stop(boolean stopNow) { + LOG.info("Stopping DMaaP Controller."); + Iterator<Listener> itr = listeners.values().iterator(); + while (itr.hasNext()) { + Listener l = itr.next(); + if (stopNow) { + l.stopNow(); + } else { + l.stop(); + } + itr.remove(); + } + executor.shutdown(); + try { + executor.awaitTermination(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + } + } + + @Override + public Map<ListenerProperties, Listener> getListeners() { + return listeners; + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/impl/EventHandlerImpl.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/impl/EventHandlerImpl.java new file mode 100644 index 000000000..590afbe8b --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/impl/EventHandlerImpl.java @@ -0,0 +1,326 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.impl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.openecomp.appc.adapter.dmaap.Consumer; +import org.openecomp.appc.adapter.dmaap.DmaapConsumer; +import org.openecomp.appc.adapter.dmaap.DmaapProducer; +import org.openecomp.appc.adapter.dmaap.Producer; +import org.openecomp.appc.adapter.dmaap.DmaapConsumer; +import org.openecomp.appc.adapter.dmaap.DmaapProducer; +import org.openecomp.appc.listener.EventHandler; +import org.openecomp.appc.listener.ListenerProperties; +import org.openecomp.appc.listener.ListenerProperties.MessageService; +import org.openecomp.appc.listener.util.Mapper; +import org.openecomp.appc.logging.LoggingConstants; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.slf4j.MDC; + +/** + * This class is a wrapper for the DMaaP client provided in appc-dmaap-adapter. Its aim is to ensure that only well formed + * messages are sent and received on DMaaP. + * + */ +public class EventHandlerImpl implements EventHandler { + + private final EELFLogger LOG = EELFManager.getInstance().getLogger(EventHandlerImpl.class); + + /* + * The amount of time in seconds to keep a connection to a topic open while waiting for data + */ + private int READ_TIMEOUT = 60; + + /* + * The pool of hosts to query against + */ + private Collection<String> pool; + + /* + * The topic to read messages from + */ + private String readTopic; + + /* + * The topic to write messages to + */ + private Set<String> writeTopics; + + /* + * The client (group) name to use for reading messages + */ + private String clientName; + + /* + * The id of the client (group) that is reading messages + */ + private String clientId; + + /* + * The api public key to use for authentication + */ + private String apiKey; + + /* + * The api secret key to use for authentication + */ + private String apiSecret; + + /* + * A json object containing filter arguments. + */ + private String filter_json; + + private MessageService messageService; + + private Consumer reader = null; + private Producer producer = null; + + public EventHandlerImpl(ListenerProperties props) { + pool = new HashSet<String>(); + writeTopics = new HashSet<String>(); + + if (props != null) { + readTopic = props.getProperty(ListenerProperties.KEYS.TOPIC_READ); + clientName = props.getProperty(ListenerProperties.KEYS.CLIENT_NAME, "APP-C"); + clientId = props.getProperty(ListenerProperties.KEYS.CLIENT_ID, "0"); + apiKey = props.getProperty(ListenerProperties.KEYS.AUTH_USER_KEY); + apiSecret = props.getProperty(ListenerProperties.KEYS.AUTH_SECRET_KEY); + + filter_json = props.getProperty(ListenerProperties.KEYS.TOPIC_READ_FILTER); + + READ_TIMEOUT = Integer + .valueOf(props.getProperty(ListenerProperties.KEYS.TOPIC_READ_TIMEOUT, String.valueOf(READ_TIMEOUT))); + + String hostnames = props.getProperty(ListenerProperties.KEYS.HOSTS); + if (hostnames != null && !hostnames.isEmpty()) { + for (String name : hostnames.split(",")) { + pool.add(name); + } + } + + String writeTopicStr = props.getProperty(ListenerProperties.KEYS.TOPIC_WRITE); + if (writeTopicStr != null) { + for (String topic : writeTopicStr.split(",")) { + writeTopics.add(topic); + } + } + + messageService = MessageService.parse(props.getProperty(ListenerProperties.KEYS.MESSAGE_SERVICE)); + + LOG.info(String.format( + "Configured to use %s client on host pool [%s]. Reading from [%s] filtered by %s. Wriring to [%s]. Authenticated using %s", + messageService, hostnames, readTopic, filter_json, writeTopics, apiKey)); + } + } + + @Override + public List<String> getIncomingEvents() { + return getIncomingEvents(1000); + } + + @Override + public List<String> getIncomingEvents(int limit) { + List<String> out = new ArrayList<String>(); + LOG.info(String.format("Getting up to %d incoming events", limit)); + // reuse the consumer object instead of creating a new one every time + if (reader == null) { + LOG.info("Getting Consumer..."); + reader = getConsumer(); + } + for (String item : reader.fetch(READ_TIMEOUT * 1000, limit)) { + out.add(item); + } + LOG.info(String.format("Read %d messages from %s as %s/%s.", out.size(), readTopic, clientName, clientId)); + return out; + } + + @Override + public <T> List<T> getIncomingEvents(Class<T> cls) { + return getIncomingEvents(cls, 1000); + } + + @Override + public <T> List<T> getIncomingEvents(Class<T> cls, int limit) { + List<String> incomingStrings = getIncomingEvents(limit); + return Mapper.mapList(incomingStrings, cls); + } + + @Override + public void postStatus(String event) { + postStatus(null, event); + } + + @Override + public void postStatus(String partition, String event) { + LOG.debug(String.format("Posting Message [%s]", event)); + if (producer == null) { + LOG.info("Getting Producer..."); + producer = getProducer(); + } + producer.post(partition, event); + } + + /** + * Returns a consumer object for direct access to our Cambria consumer interface + * + * @return An instance of the consumer interface + */ + protected Consumer getConsumer() { + LOG.debug(String.format("Getting Consumer: %s %s/%s/%s", pool, readTopic, clientName, clientId)); + if (filter_json == null && writeTopics.contains(readTopic)) { + LOG.error( + "*****We will be writing and reading to the same topic without a filter. This will cause an infinite loop.*****"); + } + Consumer out; + out = new DmaapConsumer(pool, readTopic, clientName, clientId, filter_json, apiKey, apiSecret); + for (String url : pool) { + if (url.contains("3905") || url.contains("https")) { + out.useHttps(true); + break; + } + } + return out; + } + + /** + * Returns a consumer object for direct access to our Cambria producer interface + * + * @return An instance of the producer interface + */ + protected Producer getProducer() { + LOG.debug(String.format("Getting Producer: %s %s", pool, readTopic)); + + Producer out; + out = new DmaapProducer(pool,writeTopics); + + if (apiKey != null && apiSecret != null) { + out.updateCredentials(apiKey, apiSecret); + } + + for (String url : pool) { + if (url.contains("3905") || url.contains("https")) { + out.useHttps(true); + break; + } + } + return out; + } + + @Override + public void closeClients() { + LOG.debug("Closing Consumer and Producer DMaaP clients"); + switch (messageService) { + case DMaaP: + if (reader != null) { + ((DmaapConsumer) reader).close(); + } + if (producer != null) { + ((DmaapProducer) producer).close(); + } + break; + default: + // close DMaaP clients + if (reader != null) { + ((DmaapConsumer) reader).close(); + } + if (producer != null) { + ((DmaapProducer) producer).close(); + } + } + } + + @Override + public String getClientId() { + return clientId; + } + + @Override + public void setClientId(String clientId) { + this.clientId = clientId; + } + + @Override + public String getClientName() { + return clientName; + } + + @Override + public void setClientName(String clientName) { + this.clientName = clientName; + MDC.put(LoggingConstants.MDCKeys.PARTNER_NAME, clientName); + } + + @Override + public void addToPool(String hostname) { + pool.add(hostname); + } + + @Override + public Collection<String> getPool() { + return pool; + } + + @Override + public void removeFromPool(String hostname) { + pool.remove(hostname); + } + + @Override + public String getReadTopic() { + return readTopic; + } + + @Override + public void setReadTopic(String readTopic) { + this.readTopic = readTopic; + } + + @Override + public Set<String> getWriteTopics() { + return writeTopics; + } + + @Override + public void setWriteTopics(Set<String> writeTopics) { + this.writeTopics = writeTopics; + } + + @Override + public void clearCredentials() { + apiKey = null; + apiSecret = null; + } + + @Override + public void setCredentials(String key, String secret) { + apiKey = key; + apiSecret = secret; + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/util/Mapper.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/util/Mapper.java new file mode 100644 index 000000000..cdb0d14f0 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/util/Mapper.java @@ -0,0 +1,134 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.util; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.databind.JsonNode; +import org.json.JSONObject; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class Mapper { + + private static final EELFLogger LOG = EELFManager.getInstance().getLogger(Mapper.class); + + private static ObjectMapper mapper = new ObjectMapper(); + + /** + * @return The object mapper that we are using. + */ + public static ObjectMapper getMapper() { + return mapper; + } + + /** + * Convert a String to a DcaeMessage + * + * @param data + * The json string to try and parse + * @return A DcaeMessage from the json string or null if it could not + */ + public static <T> T mapOne(String data, Class<T> cls) { + try { + return mapper.readValue(data, cls); + } catch (Exception e) { + LOG.warn(String.format("Could not map [ %s ] to %s", data, cls.getName()), e); + return null; + } + } + + public static <T> List<T> mapList(List<String> data, Class<T> cls) { + List<T> out = new ArrayList<T>(); + for (String s : data) { + T tmp = Mapper.mapOne(s, cls); + if (tmp != null) { + out.add(tmp); + } + } + return out; + } + + /** + * Convenience method to try and convert objects to json String + * + * @param obj + * The object to try and convert + * @return A json string representing the object or null if it could not be converted + */ + public static String toJsonString(Object obj) { + String jsonStr; + try { + if (obj instanceof JSONObject) { + jsonStr = obj.toString(); + }else { + jsonStr = mapper.writeValueAsString(obj); + } + return jsonStr; + } catch (Exception e) { + LOG.warn(String.format("Could not map %s to JSONObject.", obj), e); + return null; + } + } + + public static JSONObject toJsonObject(Object obj) { + String jsonStr; + try { + if (obj.getClass().equals(String.class)) { + jsonStr = (String) obj; + } else { + jsonStr = mapper.writeValueAsString(obj); + } + return new JSONObject(jsonStr); + } catch (Exception e) { + LOG.warn(String.format("Could not map %s to JSONObject.", obj), e); + return null; + } + } + public static JsonNode toJsonNodeFromJsonString(String jsonStr) { + JsonNode jsonNode = null; + if(jsonStr != null) { + try { + jsonNode = mapper.readTree(jsonStr); + } catch (IOException e) { + LOG.warn(String.format("Could not map %s to jsonNode.", jsonStr), e); + } + } + return jsonNode; + } + public static JsonNode toJsonNode(Object obj) { + JsonNode jsonNode = null; + String jsonStr = toJsonString(obj); + if(jsonStr != null) { + try { + jsonNode = mapper.readTree(jsonStr); + } catch (IOException e) { + LOG.warn(String.format("Could not map %s to JSONObject.", obj), e); + } + } + return jsonNode; + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..25c49ac4a --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,99 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# ${user.home} usually goes to /root if instantiation uses the appc-docker approach + +### ### +### ### +###Properties below that are commented out are/need to be provided in appc.properties### +### ### +### ### + + + + +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded to supply configuration options +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + + + + + +### ### +###Closed Loop - properties ### +### ### +appc.ClosedLoop.poolMembers=192.168.1.2:3904 +appc.ClosedLoop.topic.read=APPC-TEST2 +appc.ClosedLoop.topic.write=APPC-TEST2 +appc.ClosedLoop.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]} +appc.ClosedLoop.client.name=APPC-TEST-CLIENT-EVT-LST-MAIN +appc.ClosedLoop.client.name.id=0 + +# KEY AND SECRET BELOW NEED TO BE MODIFIED TO APPROPRIATE VALUES WHEN THE TOPIC IS API-KEY-BASED AUTH +#dmaap.client.key=random +#dmaap.client.secret=random + +appc.ClosedLoop.threads.queuesize.min=1 +appc.ClosedLoop.threads.queuesize.max=1000 +appc.ClosedLoop.threads.poolsize.min=1 +appc.ClosedLoop.threads.poolsize.max=2 +appc.ClosedLoop.provider.url=http://localhost:8181/restconf/operations/appc-provider +appc.ClosedLoop.provider.url.user=ODL_USER +appc.ClosedLoop.provider.url.pass=ODL_PASS + + + + + +### ### +###Closed Loop - 1607 properties ### +### ### +appc.ClosedLoop1607.poolMembers=192.168.1.2:3904 +appc.ClosedLoop1607.topic.read=MY_DMAAP_TOPIC +appc.ClosedLoop1607.topic.write=MY_DMAAP_TOPIC +appc.ClosedLoop1607.topic.read.filter={"class":"Unassigned","field":"Status"} +appc.ClosedLoop1607.client.name=MY_DMAAP_CLIENT_NAME +appc.ClosedLoop1607.client.name.id=0 +#dmaap.client.key=random +#dmaap.client.secret=random +appc.ClosedLoop1607.threads.queuesize.min=1 +appc.ClosedLoop1607.threads.queuesize.max=1000 +appc.ClosedLoop1607.threads.poolsize.min=1 +appc.ClosedLoop1607.threads.poolsize.max=2 +appc.ClosedLoop.provider.user=ODL_USER +appc.ClosedLoop.provider.pass=ODL_PASS +appc.ClosedLoop1607.provider.url=http://localhost:8181/restconf/operations/appc-provider + + + + + +### ### +### This needs to be changed so that the action can be appended to the end of the URL path ### +### ### +appc.LCM.provider.url=http://localhost:8181/restconf/operations/appc-provider +appc.LCM.poolMembers=192.168.1.2:3904 +appc.LCM.topic.read=DMAAP_TOPIC +appc.LCM.topic.write=DMAAP_TOPIC +appc.LCM.client.name=DMAAP_CLIENT_NAME +appc.LCM.provider.user=ODL_USER +appc.LCM.provider.pass=ODL_URL diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/impl/TestListenerImpl.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/impl/TestListenerImpl.java new file mode 100644 index 000000000..63c98458a --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/impl/TestListenerImpl.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL.impl; + +import java.util.Properties; + +import org.junit.Before; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.listener.ListenerProperties; +import org.openecomp.appc.listener.CL.impl.ListenerImpl; + +public class TestListenerImpl { + + ListenerImpl listener; + + @Before + public void setup() { + Properties props = ConfigurationFactory.getConfiguration().getProperties(); + ListenerProperties lProps = new ListenerProperties((String) props.get("test.prefix"), props); + lProps.getProperties().setProperty("topic.read.timeout", "5"); // Just for this test + listener = new ListenerImpl(lProps); + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/impl/TestProviderOperations.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/impl/TestProviderOperations.java new file mode 100644 index 000000000..3d7a7182f --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/impl/TestProviderOperations.java @@ -0,0 +1,122 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.util.Properties; + +import org.eclipse.osgi.internal.signedcontent.Base64; +import org.junit.Before; +import org.junit.Test; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.listener.CL.impl.ProviderOperations; +import org.openecomp.appc.listener.CL.model.IncomingMessage; + +public class TestProviderOperations { + + private String ACTIVE_ENDPOINT; + + @Before + public void setup() { + Properties props = ConfigurationFactory.getConfiguration().getProperties(); + ACTIVE_ENDPOINT = props.getProperty("appc.ClosedLoop.provider.url"); + assertNotNull(ACTIVE_ENDPOINT); + ProviderOperations.setUrl(ACTIVE_ENDPOINT); + + props.getProperty("test.vm_url"); + assertNotNull("VM_URL"); + } + + @Test + public void testTopologyOperation() { + IncomingMessage msg = new IncomingMessage(); + // Client and Time are for ID + msg.setRequestClient("APPC"); + msg.setRequestTime("TEST"); + msg.setRequest("Restart"); + + // Null Input + try { + ProviderOperations.topologyDG(null); + fail("Topology Operation with null input should fail"); + } catch (APPCException e) { + assertNotNull(e.getMessage()); + } + + // Bad URL + msg.setUrl("some bad url here"); + try { + ProviderOperations.topologyDG(msg); + // Could also be issue in IaaS Adapter + fail("Topology Operation with bad url should fail"); + } catch (APPCException e) { + assertNotNull(e.getMessage()); + } + + // Will be tested in worker + // msg.setUrl(VM_URL); + // System.out.println("Rebooting real VM. Test can take up to 90s"); + // try { + // assertTrue(ProviderOperations.topologyDG(msg)); + // } catch (APPCException e) { + // fail("Topology Operation with good url should succeed. Check url in gui first"); + // } + + } + + @Test + public void testConfigurationOperation() { + try { + ProviderOperations.topologyDG(null); + fail("Configuration Operation should throw execption. Not yet supported"); + } catch (APPCException e) { + assertNotNull(e.getMessage()); + } + } + + @Test + public void testBasicAuthFormating() { + String user = "user"; + String pass = "pass"; + + String result = ProviderOperations.setAuthentication(user, pass); + + assertNotNull(result); + String decode = new String(Base64.decode(result.getBytes())); + assertEquals(user + ":" + pass, decode); + } + + @Test + public void testGetSet() { + // Every test URL will get reset + assertEquals(ACTIVE_ENDPOINT, ProviderOperations.getUrl()); + + String newUrl = "http://example.com"; + ProviderOperations.setUrl(newUrl); + assertEquals(newUrl, ProviderOperations.getUrl()); + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/impl/TestWorker.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/impl/TestWorker.java new file mode 100644 index 000000000..1cd9cdc44 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/impl/TestWorker.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL.impl; + +import static org.junit.Assert.assertNotNull; + +import java.util.Properties; + +import org.junit.Before; +import org.junit.Test; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.listener.EventHandler; +import org.openecomp.appc.listener.ListenerProperties; +import org.openecomp.appc.listener.CL.impl.ProviderOperations; +import org.openecomp.appc.listener.CL.impl.WorkerImpl; +import org.openecomp.appc.listener.CL.model.IncomingMessage; +import org.openecomp.appc.listener.impl.EventHandlerImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TestWorker { + + private static final Logger LOG = LoggerFactory.getLogger(WorkerImpl.class); + + private IncomingMessage msg; + private EventHandler dmaap; + + @Before + public void setup() { + Properties props = ConfigurationFactory.getConfiguration().getProperties(); + String activeEndpoint = props.getProperty("appc.ClosedLoop.provider.url"); + assertNotNull(activeEndpoint); + ProviderOperations.setUrl(activeEndpoint); + + String vmUrl = props.getProperty("test.vm_url"); + assertNotNull(vmUrl); + msg = new IncomingMessage(); + // Client and Time are for ID + msg.setRequestClient("APPC"); + msg.setRequestTime("TEST"); + msg.setRequest("Restart"); + msg.setUrl(vmUrl); + + dmaap = new EventHandlerImpl(new ListenerProperties("appc.ClosedLoop", props)); + } + + @Test + public void testWorker() { + WorkerImpl w = new WorkerImpl(msg, dmaap); + w.run(); + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/model/TestEnums.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/model/TestEnums.java new file mode 100644 index 000000000..a934cb432 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/model/TestEnums.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL.model; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; +import org.openecomp.appc.listener.CL.model.Action; +import org.openecomp.appc.listener.CL1607.model.Status; + +public class TestEnums { + + @Test + public void testAction() { + assertEquals(Action.Rebuild, Action.toAction("Rebuild")); + assertEquals(Action.Restart, Action.toAction("restart")); + assertEquals(Action.Migrate, Action.toAction("MIGRATE")); + assertEquals(Action.Evacuate, Action.toAction("Evacuate")); + assertNull(Action.toAction("Unknown")); + assertNull(Action.toAction(null)); + + assertEquals(4, Action.values().length); + } + + @Test + public void testStatus() { + + assertEquals(Status.ACCEPTED, Status.toStatus("ACCEPTED")); + assertEquals(Status.SUCCESS, Status.toStatus("SuCcEsS")); + assertEquals(Status.FAILURE, Status.toStatus("Failure")); + assertNull(Status.toStatus("Unknown")); + assertNull(Status.toStatus(null)); + + assertEquals(3, Status.values().length); + + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/model/TestMessages.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/model/TestMessages.java new file mode 100644 index 000000000..e9fa1ace8 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/model/TestMessages.java @@ -0,0 +1,151 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL.model; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.apache.commons.io.IOUtils; +import org.json.JSONObject; +import org.junit.Before; +import org.junit.Test; +import org.openecomp.appc.listener.CL.model.IncomingMessage; +import org.openecomp.appc.listener.CL.model.OutgoingMessage; +import org.openecomp.appc.listener.CL.model.Status; +import org.openecomp.appc.listener.util.Mapper; + +public class TestMessages { + private IncomingMessage in; + private OutgoingMessage out; + + private String incomingStr; + private String outgoingStr; + + @Before + public void setup() { + try { + incomingStr = IOUtils.toString(getClass().getResourceAsStream("/IncomingMessage.txt"), "UTF-8"); + outgoingStr = IOUtils.toString(getClass().getResourceAsStream("/OutgoingMessage.txt"), "UTF-8"); + assertNotNull(incomingStr); + assertNotNull(outgoingStr); + + in = Mapper.mapOne(incomingStr, IncomingMessage.class); + + out = Mapper.mapOne(in.toOutgoing(Status.PENDING), OutgoingMessage.class); + out.updateResponseTime(); + + assertNotNull(in); + assertNotNull(out); + } catch (Exception e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } + + // NOTE Test Mapper will be used to test an event from dmaap. + @Test + public void testGetterSetter() { + assertNotNull(in); + assertNotNull(in.getRequestClient()); + assertNotNull(in.getRequestTime()); + assertNotNull(in.getMessage()); + assertNotNull(in.getTenantId()); + assertNotNull(in.getVmId()); + assertNotNull(in.getVmName()); + assertNotNull(in.getAction()); + assertNotNull(in.getId()); + assertNotNull(in.getPolicyName()); + assertNotNull(in.getPolicyVersion()); + assertNotNull(in.getRequest()); + + out = Mapper.mapOne(in.toOutgoing(null), OutgoingMessage.class); + assertNotNull(out.getRequestClient()); + assertEquals(in.getRequestClient(), out.getRequestClient()); + assertNotNull(out.getRequestTime()); + assertEquals(in.getRequestTime(), out.getRequestTime()); + assertNotNull(out.getMessage()); + assertEquals(in.getMessage(), out.getMessage()); + assertNotNull(out.getVmName()); + assertEquals(in.getVmName(), out.getVmName()); + assertNotNull(out.getPolicyName()); + assertEquals(in.getPolicyName(), out.getPolicyName()); + assertNotNull(out.getPolicyVersion()); + assertEquals(in.getPolicyVersion(), out.getPolicyVersion()); + assertNotNull(out.getOriginalRequest()); + assertNotNull(in.getRequest(), out.getOriginalRequest()); + } + + @Test + public void testToString() { + in = new IncomingMessage(); + assertNotNull(in.toString()); + String id = "test"; + in.setId(id); + assertNotNull(in.toString()); + assertTrue(in.toString().contains(id)); + } + + @Test + public void testOutgoingUpdateTime() { + String old = out.getResponseTime(); + out.updateResponseTime(); + assertFalse(old.equals(out.getResponseTime())); + } + + // Testing for 1510 + @Test + public void testOutgoingToJson() { + // Message Set + String message = "MSG"; + out.setMessage(message); + JSONObject json = out.toResponse(); + assertNotNull(json); + String respStr = json.getString("response"); + assertTrue(respStr.contains(out.getResponse().getValue())); + + String msgStr = json.getString("message"); + assertNotNull(msgStr); + assertFalse(msgStr.contains(out.getOriginalRequest())); // False for 1602 + assertTrue(msgStr.contains(out.getMessage())); + + // Null Message + out.setMessage(null); + json = out.toResponse(); + assertNotNull(json); + msgStr = json.getString("message"); + assertNotNull(msgStr); + assertFalse(msgStr.contains(out.getOriginalRequest())); // False for 1602 + assertTrue(msgStr.contains(out.getResponse().getValue())); + + // Echoing request + assertNotNull(out.getOriginalRequest()); + } + + @Test + public void testOutgoingToString() { + String s = out.toString(); + assertTrue(s.contains(out.getId())); + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL1607/model/TestEnums.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL1607/model/TestEnums.java new file mode 100644 index 000000000..73e38aa4f --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL1607/model/TestEnums.java @@ -0,0 +1,59 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL1607.model; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; +import org.openecomp.appc.listener.CL.model.Action; +import org.openecomp.appc.listener.CL.model.Status; + +public class TestEnums { + + @Test + public void testAction() { + assertEquals(Action.Rebuild, Action.toAction("Rebuild")); + assertEquals(Action.Restart, Action.toAction("restart")); + assertEquals(Action.Migrate, Action.toAction("MIGRATE")); + assertEquals(Action.Evacuate, Action.toAction("Evacuate")); + assertNull(Action.toAction("Unknown")); + assertNull(Action.toAction(null)); + + assertEquals(4, Action.values().length); + } + + @Test + public void testStatus() { + + assertEquals(Status.PENDING, Status.toStatus("Pending")); + assertEquals(Status.ACTIVE, Status.toStatus("active")); + assertEquals(Status.SUCCESS, Status.toStatus("SuCcEsS")); + assertEquals(Status.FAILURE, Status.toStatus("Failure")); + assertNull(Status.toStatus("Unknown")); + assertNull(Status.toStatus(null)); + + assertEquals(4, Status.values().length); + + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL1607/model/TestMessages.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL1607/model/TestMessages.java new file mode 100644 index 000000000..c7bc86300 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL1607/model/TestMessages.java @@ -0,0 +1,160 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.CL1607.model; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.apache.commons.io.IOUtils; +import org.json.JSONObject; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.openecomp.appc.listener.CL1607.model.IncomingMessage; +import org.openecomp.appc.listener.CL1607.model.OutgoingMessage; +import org.openecomp.appc.listener.CL1607.model.Status; +import org.openecomp.appc.listener.util.Mapper; + +public class TestMessages { + private IncomingMessage in; + private OutgoingMessage out; + + private String incomingStr; + private String outgoingStr; + + @Before + public void setup() { + try { + incomingStr = IOUtils.toString(getClass().getResourceAsStream("/IncomingMessage1607.txt"), "UTF-8"); + outgoingStr = IOUtils.toString(getClass().getResourceAsStream("/OutgoingMessage1607.txt"), "UTF-8"); + assertNotNull(incomingStr); + assertNotNull(outgoingStr); + + in = Mapper.mapOne(incomingStr, IncomingMessage.class); + + out = Mapper.mapOne(outgoingStr, OutgoingMessage.class); + + assertNotNull(in); + assertNotNull(out); + } catch (Exception e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } + + // NOTE Test Mapper will be used to test an event from dmaap. + @Test + public void testGetterSetter() { + assertNotNull(in); + assertNotNull(in.getAction()); + assertNotNull(in.getHeader().getApiVer()); + assertNotNull(in.getHeader().getOriginatorId()); + assertNotNull(in.getHeader().getRequestID()); + assertNotNull(in.getHeader().getSubRequestId()); + assertNotNull(in.getHeader().getTimeStamp()); + + assertNotNull(out); + assertNotNull(out.getHeader().getApiVer()); + assertNotNull(out.getHeader().getOriginatorId()); + assertNotNull(out.getHeader().getRequestID()); + assertNotNull(out.getHeader().getSubRequestId()); + assertNotNull(out.getHeader().getTimeStamp()); + assertNotNull(out.getStatus().getCode()); + assertNotNull(out.getStatus().getValue()); + + } + + @Test + @Ignore + public void testIncommingToOutgoing(){ + OutgoingMessage newOut; + newOut = Mapper.mapOne(in.toOutgoing(Status.ACCEPTED), OutgoingMessage.class); + assertNotNull(newOut); + assertNotNull(newOut.getHeader().getApiVer()); + assertNotNull(newOut.getHeader().getOriginatorId()); + assertNotNull(newOut.getHeader().getRequestID()); + assertNotNull(newOut.getHeader().getSubRequestId()); + assertNotNull(newOut.getHeader().getTimeStamp()); + assertNotNull(newOut.getStatus().getCode()); + assertNotNull(newOut.getStatus().getValue()); + } + + @Test + @Ignore + public void testToString() { + in = new IncomingMessage(); + assertNotNull(in.toString()); + String id = "test"; + //in.setId(id); + assertNotNull(in.toString()); + assertTrue(in.toString().contains(id)); + } + + + @Test + @Ignore + public void testOutgoingUpdateTime() { + //String old = out.getResponseTime(); + out.updateResponseTime(); + //assertFalse(old.equals(out.getResponseTime())); + } + + // Testing for 1510 + @Test + @Ignore + public void testOutgoingToJson() { + // Message Set + String message = "MSG"; + //out.setMessage(message); + JSONObject json = out.toResponse(); + assertNotNull(json); + String respStr = json.getString("response"); + //assertTrue(respStr.contains(out.getResponse().getValue())); + + String msgStr = json.getString("message"); + assertNotNull(msgStr); + //assertFalse(msgStr.contains(out.getOriginalRequest())); // False for 1602 + //assertTrue(msgStr.contains(out.getMessage())); + + // Null Message + //out.setMessage(null); + json = out.toResponse(); + assertNotNull(json); + msgStr = json.getString("message"); + assertNotNull(msgStr); + //assertFalse(msgStr.contains(out.getOriginalRequest())); // False for 1602 + //assertTrue(msgStr.contains(out.getResponse().getValue())); + + // Echoing request + //assertNotNull(out.getOriginalRequest()); + } + + @Test + @Ignore + public void testOutgoingToString() { + String s = out.toString(); + //assertTrue(s.contains(out.getId())); + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/LCM/TestConverter.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/LCM/TestConverter.java new file mode 100644 index 000000000..2062e80d8 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/LCM/TestConverter.java @@ -0,0 +1,91 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.LCM; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import org.junit.Assert; +import org.junit.Test; +import org.openecomp.appc.listener.LCM.conv.Converter; +import org.openecomp.appc.listener.LCM.model.DmaapIncomingMessage; +import org.openecomp.appc.listener.LCM.model.DmaapOutgoingMessage; +import org.openecomp.appc.listener.util.Mapper; + +public class TestConverter { + + private String jsonInputBodyStr ="{\"input\":{ \"common-header\": { \"timestamp\": \"2016-08-03T08:50:18.97Z\", \"api-ver\": \"1\", \"originator-id\": \"1\", \"request-id\": \"123\", \"sub-request-id\": \"1\", \"flags\": { \"force\":\"TRUE\", \"ttl\":\"9900\" } }, \"action\": \"Stop\", \"action-identifiers\": { \"vnf-id\": \"TEST\" } }}"; + private String jsonOutputBodyStr ="{\"output\":{\"common-header\":{\"timestamp\":\"2016-08-03T08:50:18.97Z\",\"api-ver\":\"1\",\"flags\":{\"force\":\"TRUE\",\"ttl\":\"9900\"},\"sub-request-id\":\"1\",\"request-id\":\"123\",\"originator-id\":\"1\"},\"status\":{\"value\":\"TestException\",\"code\":200}}}"; + + @Test + public void buildDmaapOutgoingMessageWithUnexpectedErrorTest() throws JsonProcessingException { + DmaapIncomingMessage dmaapIncomingMessage = buildDmaapIncomingMessage(); + String errMsg = "TestException"; + DmaapOutgoingMessage dmaapOutgoingMessage = Converter.buildDmaapOutgoingMessageWithUnexpectedError(dmaapIncomingMessage.getBody(), "test", new Exception(errMsg)); + int code = dmaapOutgoingMessage.getBody().get("output").get("status").get("code").asInt(); + String value = dmaapOutgoingMessage.getBody().get("output").get("status").get("value").asText(); + Assert.assertEquals(200,code); + Assert.assertEquals(errMsg,value); + } + + private static String expectedDmaapOutgoingMessageAsJsonString = "{\"body\":{\"output\":{\"common-header\":{\"timestamp\":\"2016-08-03T08:50:18.97Z\",\"api-ver\":\"1\",\"flags\":{\"force\":\"TRUE\",\"ttl\":\"9900\"},\"sub-request-id\":\"1\",\"request-id\":\"123\",\"originator-id\":\"1\"},\"status\":{\"value\":\"TestException\",\"code\":200}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"test\"}"; + @Test + public void convDmaapOutgoingMessageToJsonStringTest() throws JsonProcessingException { + DmaapOutgoingMessage dmaapOutgoingMessage = buildDmaapOutgoingMessage(); + String dmaapOutgoingMessageAsJsonString = Converter.convDmaapOutgoingMessageToJsonString(dmaapOutgoingMessage); +// Assert.assertEquals(dmaapOutgoingMessageAsJsonString,dmaapOutgoingMessageAsJsonString); + Assert.assertEquals(expectedDmaapOutgoingMessageAsJsonString,dmaapOutgoingMessageAsJsonString); + } + + private DmaapIncomingMessage buildDmaapIncomingMessage() { + DmaapIncomingMessage dmaapIncomingMessage = new DmaapIncomingMessage(); + dmaapIncomingMessage.setRpcName("test"); + JsonNode jsonNode = Mapper.toJsonNodeFromJsonString(jsonInputBodyStr); + dmaapIncomingMessage.setBody(jsonNode); + return dmaapIncomingMessage; + + } + + private DmaapOutgoingMessage buildDmaapOutgoingMessage() { + DmaapOutgoingMessage dmaapOutgoingMessage = new DmaapOutgoingMessage(); + dmaapOutgoingMessage.setRpcName("test"); + JsonNode jsonNode = Mapper.toJsonNodeFromJsonString(jsonOutputBodyStr); + dmaapOutgoingMessage.setBody(jsonNode); + return dmaapOutgoingMessage; + + } + + + @Test + public void extractRequestIdWithSubIdTest() { + DmaapIncomingMessage dmaapIncomingMessage = buildDmaapIncomingMessage(); + String equestIdWithSubId = Converter.extractRequestIdWithSubId(dmaapIncomingMessage.getBody()); + Assert.assertEquals("123-1",equestIdWithSubId); + } + + @Test + public void extractStatusCodeTest() { + DmaapOutgoingMessage dmaapOutgoingMessage = buildDmaapOutgoingMessage(); + Integer statusCode = Converter.extractStatusCode(dmaapOutgoingMessage.getBody()); + Assert.assertEquals(200L,statusCode.longValue()); + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/LCM1607/model/TestJsonGenericMessages.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/LCM1607/model/TestJsonGenericMessages.java new file mode 100644 index 000000000..203a13dce --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/LCM1607/model/TestJsonGenericMessages.java @@ -0,0 +1,99 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.LCM1607.model; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Assert; +import org.junit.Test; +import org.openecomp.appc.listener.util.Mapper; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + + +public class TestJsonGenericMessages {/* + + @Test + public void serializeIncomingMessage() { + + final String expectedJson = "{\"CommonHeader\":{\"TimeStamp\":\"2016-05-02 19:50:37.09\",\"TransactionID\":\"1\",\"APIver\":\"1.01\",\"RequestTrack\":[\"1\",\"4\",\"12\",\"3\"],\"Flags\":null,\"SubrequestID\":null,\"OriginatorID\":\"2\"},\"Payload\":\"{ \\\"command\\\": \\\"start\\\", \\\"target-id\\\": \\\"111\\\", \\\"flag10\\\": {\\\"object-1\\\": {\\\"key-1\\\": \\\"key\\\", \\\"value-1\\\": \\\"value\\\" }} }\",\"Action\":\"CONFIGURE\",\"ObjectID\":\"200\",\"TargetID\":\"100\"}"; + InputBody msg = createIncomingMessage(); + + String json = Mapper.toJsonObject(msg).toString(); + //System.out.println(json); + Assert.assertEquals(expectedJson, json); + } + + @Test + public void deserializeIncomingMessage() throws IOException { + final String originalJson = "{\"CommonHeader\":{\"TimeStamp\":\"2016-05-02 19:50:37.09\",\"TransactionID\":\"1\",\"Flags\":{\"FORCE\":\"Y\",\"TTL\":\"12\"},\"SubrequestID\":\"2345\",\"OriginatorID\":\"2\",\"APIver\":\"1.01\"}, \"Payload\": \" \\\"Graceful\\\" : \\\"Yes\\\" \",\"Action\":\"CONFIGURE\",\"ObjectID\":\"200\",\"TargetID\":\"100\"}"; + + ObjectMapper mapper = new ObjectMapper(); + InputBody msg = mapper.readValue(originalJson, InputBody.class); + + Assert.assertNotNull(msg); + Assert.assertEquals("2016-05-02 19:50:37.09", msg.getCommonHeader().getTimeStamp()); + Assert.assertEquals("1", msg.getCommonHeader().getRequestID()); + Assert.assertEquals("1.01", msg.getCommonHeader().getApiVer()); + Assert.assertEquals("200", msg.getObjectId()); + Assert.assertEquals("100", msg.getTargetId()); + Assert.assertEquals(" \"Graceful\" : \"Yes\" ", msg.getPayload()); + Assert.assertEquals("CONFIGURE", msg.getAction()); + + } + + @Test + public void serializeResponseMessage() { + InputBody imsg = createIncomingMessage(); + OutputBody omsg = new OutputBody(imsg); + omsg.setStatus(new ResponseStatus("200", "OK")); + + String json = Mapper.toJsonObject(omsg).toString(); + System.out.println(json); + //Assert.assertEquals(expectedJson, json); + Assert.assertNotEquals("", json); + + } + + private InputBody createIncomingMessage() { + InputBody msg = new InputBody(); + CommonHeader rh = new CommonHeader(); + rh.setTimeStamp("2016-05-02 19:50:37.09"); + rh.setApiVer("1.01"); + rh.setRequestID("1"); + rh.setOriginatorId("2"); + + + Map<String, String> flags = new HashMap<>(); + flags.put("FORCE", "Y"); + flags.put("TTL", "12"); + + msg.setCommonHeader(rh); + msg.setAction("CONFIGURE"); + msg.setTargetId("100"); + msg.setObjectId("200"); + msg.setPayloadAsString("{ \"command\": \"start\", \"target-id\": \"111\", \"flag10\": {\"object-1\": {\"key-1\": \"key\", \"value-1\": \"value\" }} }"); + return msg; + } +*/ +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/TestAbstractListener.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/TestAbstractListener.java new file mode 100644 index 000000000..c193f7c2d --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/TestAbstractListener.java @@ -0,0 +1,98 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.Properties; +import java.util.concurrent.ThreadPoolExecutor; + +import org.junit.Before; +import org.junit.Test; +import org.openecomp.appc.listener.AbstractListener; +import org.openecomp.appc.listener.ListenerProperties; + +public class TestAbstractListener { + + private class DummyListener extends AbstractListener { + public DummyListener(ListenerProperties props) { + super(props); + } + + public boolean getRun() { + return run.get(); + } + + public ThreadPoolExecutor getExecutor() { + return executor; + } + } + + private DummyListener listener; + private ListenerProperties props; + + @Before + public void setup() throws Exception { + Properties regularProps = new Properties(); + regularProps.load(getClass().getResourceAsStream("/org/openecomp/appc/default.properties")); + props = new ListenerProperties("", regularProps); + listener = new DummyListener(props); + } + + @Test + public void testRun() { + Thread t = new Thread(listener); + t.run(); + assertFalse(t.isAlive()); // Should die immediately + } + + @Test + public void testStop() { + listener.stop(); + assertFalse(listener.getRun()); + assertTrue(listener.getExecutor().isShutdown()); + } + + @Test + public void testStopNow() { + listener.stopNow(); + assertFalse(listener.getRun()); + assertTrue(listener.getExecutor().isShutdown()); + } + + @Test + public void testBenchmark() { + String out = listener.getBenchmark(); + assertNotNull(out); + assertTrue(out.contains(listener.getListenerId())); + } + + @Test + public void testListenerId() { + assertEquals(props.getPrefix(), listener.getListenerId()); + listener.setListenerId("newId"); + assertEquals("newId", listener.getListenerId()); + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/TestAppcDmaapListenerActivator.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/TestAppcDmaapListenerActivator.java new file mode 100644 index 000000000..a5348d145 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/TestAppcDmaapListenerActivator.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import org.junit.Test; +import org.openecomp.appc.listener.AppcEventListenerActivator; + +public class TestAppcDmaapListenerActivator { + + @Test + public void testStartStop() { + // TODO - How do we tests activators + AppcEventListenerActivator appc = new AppcEventListenerActivator(); + try { + appc.start(null); + Thread.sleep(2000); + appc.stop(null); + } catch (Exception e) { + e.printStackTrace(); + fail(e.getMessage()); + } + assertNotNull(appc.getName()); + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/TestListenerProperties.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/TestListenerProperties.java new file mode 100644 index 000000000..9a70a8427 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/TestListenerProperties.java @@ -0,0 +1,154 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Properties; + +import org.junit.Before; +import org.junit.Test; +import org.openecomp.appc.listener.AbstractListener; +import org.openecomp.appc.listener.ListenerProperties; +import org.openecomp.appc.listener.ListenerProperties.KEYS; + +public class TestListenerProperties { + + private Properties good, bad, both; + private String prefix; + + private ListenerProperties props; + + @Before + public void setup() { + prefix = "test"; + good = new Properties(); + bad = new Properties(); + both = new Properties(); + + good.setProperty(String.format("%s.%s", prefix, "a"), "1"); + good.setProperty(String.format("%s.%s", prefix, "a.b"), "2"); + good.setProperty(String.format("%s.%s", prefix, "a.b.c"), "3"); + + bad.setProperty(prefix, "NA"); + bad.setProperty(prefix + ".", "NA"); + bad.setProperty(String.format("%s.%s", prefix + "x", "bad"), "NA"); + bad.setProperty(String.format("%s.%s", "x" + prefix, "bad"), "NA"); + + for (String key : good.stringPropertyNames()) { + both.put(key, good.getProperty(key)); + } + for (String key : bad.stringPropertyNames()) { + both.put(key, bad.getProperty(key)); + } + + props = new ListenerProperties(prefix, both); + } + + @Test + public void testConstructor() { + props = new ListenerProperties(prefix, good); + assertEquals(prefix, props.getPrefix()); + assertEquals(good.size(), props.getProperties().size()); + + props = new ListenerProperties(prefix, bad); + assertEquals(prefix, props.getPrefix()); + assertTrue(props.getProperties().isEmpty()); + + props = new ListenerProperties(prefix, both); + assertEquals(prefix, props.getPrefix()); + assertEquals(good.size(), props.getProperties().size()); + + for (Object val : props.getProperties().values()) { + assertFalse("NA".equals(val.toString())); + } + + assertTrue(props.toString().contains(prefix)); + } + + @Test + public void testGetClass() { + assertNull(props.getListenerClass()); + props.setListenerClass(AbstractListener.class); + assertNotNull(props.getListenerClass()); + assertEquals(AbstractListener.class, props.getListenerClass()); + } + + @Test + public void testMessageServices() { + // Hardcode count so tests must be updated when values are added + assertEquals(1, ListenerProperties.MessageService.values().length); + + // Bad Input + ListenerProperties.MessageService def = ListenerProperties.MessageService.DMaaP; + assertEquals(def, ListenerProperties.MessageService.parse(null)); + assertEquals(def, ListenerProperties.MessageService.parse("")); + assertEquals(def, ListenerProperties.MessageService.parse("NotDmaapOrDMaaP")); + + + // DMaaP case sensitivity + assertEquals(ListenerProperties.MessageService.DMaaP, ListenerProperties.MessageService.parse("dmaap")); + assertEquals(ListenerProperties.MessageService.DMaaP, ListenerProperties.MessageService.parse("DMAAP")); + assertEquals(ListenerProperties.MessageService.DMaaP, ListenerProperties.MessageService.parse("DMaaP")); + } + + @Test + public void testKeys() { + // Hardcode count so tests must be updated when values are added + assertEquals(15, ListenerProperties.KEYS.values().length); + + Properties tmp = new Properties(); + try { + tmp.load(getClass().getResourceAsStream("/org/openecomp/appc/default.properties")); + } catch (Exception e) { + fail("Could not load properties to test"); + } + String realPrefix = tmp.getProperty("test.prefix"); + assertNotNull(realPrefix); + props = new ListenerProperties(realPrefix, tmp); + + for (KEYS key : ListenerProperties.KEYS.values()) { + assertNotNull(key.getFullProp(realPrefix)); + assertNotNull(props.getProperty(key)); + assertNotNull(props.getProperty(key.getPropertySuffix())); + } + } + + @Test + public void testDisabled() throws Exception { + assertFalse(props.isDisabled()); + props.getProperties().put(KEYS.DISABLED.getPropertySuffix(), "TRUE"); + assertTrue(props.isDisabled()); + props.getProperties().put(KEYS.DISABLED.getPropertySuffix(), "N/A"); + assertFalse(props.isDisabled()); + props.getProperties().put(KEYS.DISABLED.getPropertySuffix(), "fAlse"); + assertFalse(props.isDisabled()); + props.getProperties().remove(KEYS.DISABLED.getPropertySuffix()); + assertFalse(props.isDisabled()); + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/impl/TestController.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/impl/TestController.java new file mode 100644 index 000000000..a67b94647 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/impl/TestController.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.impl; + +public class TestController { + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/impl/TestEventHandler.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/impl/TestEventHandler.java new file mode 100644 index 000000000..788aa961a --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/impl/TestEventHandler.java @@ -0,0 +1,171 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.Serializable; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.openecomp.appc.listener.EventHandler; +import org.openecomp.appc.listener.ListenerProperties; +import org.openecomp.appc.listener.impl.EventHandlerImpl; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +/** + * Test the ProviderAdapter implementation. + * + */ + +public class TestEventHandler { + + private ListenerProperties prop; + + private EventHandler adapter; + + private static final String PROP_FILE = "/org/openecomp/appc/default.properties"; + + private static final String MESSAGE_FILE = "/DCAEResponse.txt"; + + /** + * Setup the test environment. + * + * @throws NoSuchMethodException + * @throws SecurityException + * @throws NoSuchFieldException + */ + @Before + public void setup() { + Properties allProps = new Properties(); + try { + allProps.load(getClass().getResourceAsStream(PROP_FILE)); + allProps.remove("appc.ClosedLoop.topic.read.filter"); + prop = new ListenerProperties("appc.ClosedLoop", allProps); + } catch (IOException e) { + System.out.println("WARNING: Failed to load properties file: " + PROP_FILE); + } + adapter = new EventHandlerImpl(prop); + } + + @Test + public void testInitialProperties() { + assertEquals(prop.getProperty("topic.read"), adapter.getReadTopic()); + assertTrue(adapter.getWriteTopics().contains(prop.getProperty("topic.write"))); + assertEquals(prop.getProperty("client.name"), adapter.getClientName()); + assertEquals(prop.getProperty("client.name.id"), adapter.getClientId()); + + String hostStr = prop.getProperty("poolMembers"); + int hostCount = hostStr.length()>0 ? hostStr.split(",").length : 0; + assertEquals(hostCount, adapter.getPool().size()); + } + + @Test + public void testGettersAndSetters() { + String readTopic = "read"; + Set<String> writeTopic = new HashSet<String>(); + writeTopic.add("write"); + String clientName = "APPC-TEST"; + String clientId = "00"; + String newHost = "google.com"; + + adapter.setReadTopic(readTopic); + assertEquals(readTopic, adapter.getReadTopic()); + + adapter.setWriteTopics(writeTopic); + assertEquals(writeTopic, adapter.getWriteTopics()); + + adapter.setClientName(clientName); + assertEquals(clientName, adapter.getClientName()); + + adapter.setClientId(clientId); + assertEquals(clientId, adapter.getClientId()); + + adapter.setCredentials("fake", "secret"); + adapter.clearCredentials(); + + int oldSize = adapter.getPool().size(); + adapter.addToPool(newHost); + assertEquals(oldSize + 1, adapter.getPool().size()); + assertTrue(adapter.getPool().contains(newHost)); + + adapter.removeFromPool(newHost); + assertEquals(oldSize, adapter.getPool().size()); + assertFalse(adapter.getPool().contains(newHost)); + + } + + @Test + @Ignore + public void testRun() { + // Runoff any old data + List<String> result1 = adapter.getIncomingEvents(); + assertNotNull(result1); + + // Post new data + DummyObj data = new DummyObj(); + data.key = "value"; + adapter.postStatus(data.toJson()); + + // Wait to account for network delay + sleep(2000); + + // Get data back + List<DummyObj> result2 = adapter.getIncomingEvents(DummyObj.class); + assertNotNull(result2); + assertEquals(1, result2.size()); + assertEquals(data.toJson(), result2.get(0).toJson()); + } + + @JsonSerialize + public static class DummyObj implements Serializable { + @JsonProperty("request") // Call request for default filter + public String key; + + public DummyObj() { + } + + public String toJson() { + return String.format("{\"request\": \"%s\"}", key); + } + } + + private void sleep(long ms) { + try { + Thread.sleep(ms); + } catch (Exception e) { + return; + } + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/impl/TestListener.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/impl/TestListener.java new file mode 100644 index 000000000..a1c7917f9 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/impl/TestListener.java @@ -0,0 +1,112 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.util.Properties; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.openecomp.appc.listener.Listener; +import org.openecomp.appc.listener.ListenerProperties; +import org.openecomp.appc.listener.CL.impl.ListenerImpl; + +@Ignore +public class TestListener { + + private static final String PROP_FILE = "/org/openecomp/appc/default.properties"; + + private Listener listener; + + private Properties props; + + @Before + public void setup() { + props = new Properties(); + try { + props.load(getClass().getResourceAsStream(PROP_FILE)); + props.setProperty("topic.read", "DCAE-CLOSED-LOOP-EVENTS-DEV1510SIM"); + } catch (Exception e) { + e.printStackTrace(); + fail("Failed to setup test: " + e.getMessage()); + } + listener = new ListenerImpl(new ListenerProperties("appc.ClosedLoop", props)); + } + + @Test + public void testListenerId() { + String originalId = listener.getListenerId(); + String newId = originalId + "-new"; + + listener.setListenerId(newId); + assertEquals(newId, listener.getListenerId()); + } + + @Test + public void testRun() { + try { + Thread t = new Thread(listener); + t.start(); + + Thread.sleep(5000); + + listener.stopNow(); + + System.out.println(listener.getBenchmark()); + + } catch (Exception e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } + + @Test + public void testUpdateProperties() { + + } + + @Test + public void printSampleData() { + try { + props.setProperty("threads.queuesize.min", "1"); + props.setProperty("threads.queuesize.max", "1"); + props.setProperty("threads.poolsize.min", "1"); + props.setProperty("threads.poolsize.max", "1"); + + Thread t = new Thread(listener); + t.start(); + + Thread.sleep(2000); + + listener.stop(); + + System.out.println(listener.getBenchmark()); + + } catch (Exception e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/util/TestMapper.java b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/util/TestMapper.java new file mode 100644 index 000000000..430b28e61 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/util/TestMapper.java @@ -0,0 +1,104 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.listener.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import org.json.JSONObject; +import org.junit.Before; +import org.junit.Test; +import org.openecomp.appc.listener.util.Mapper; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +public class TestMapper { + + private String dummyJson = "{\"a\":\"%s\"}"; + private DummyObj dummyObj = new DummyObj(); + + @JsonSerialize + public static class DummyObj implements Serializable { + @JsonProperty("a") + public String a; + + public DummyObj() { + } + } + + @Before + public void setup() { + } + + @Test + public void testGetMapper() { + assertNotNull(Mapper.getMapper()); + } + + @Test + public void testToJsonObject() { + JSONObject out; + out = Mapper.toJsonObject("."); + assertNull(out); + + String value = "b"; + out = Mapper.toJsonObject(String.format(dummyJson, value)); + assertNotNull(out); + assertEquals(value, out.get("a")); + } + + @Test + public void testConstructor() { + // Only here for code coverage + Mapper m = new Mapper(); + assertNotNull(m); + } + + @Test + public void testMap() { + List<String> in = new ArrayList<String>(); + in.add(""); + in.add(null); + + List<DummyObj> out = Mapper.mapList(in, DummyObj.class); + assertNotNull(out); + assertTrue(out.isEmpty()); + + in.add(String.format(dummyJson, "1")); + in.add("{\"invalid\":\"yes\"}"); + in.add(String.format(dummyJson, "2")); + + out = Mapper.mapList(in, DummyObj.class); + assertNotNull(out); + assertEquals(2, out.size()); + assertEquals("1", out.get(0).a); + assertEquals("2", out.get(1).a); + } + +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/resources/IncomingMessage.txt b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/resources/IncomingMessage.txt new file mode 100644 index 000000000..0771a790a --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/resources/IncomingMessage.txt @@ -0,0 +1,24 @@ +{ +"eventID": "SomeEventID-TBD", + +"APPCVDCName": "Delete this field not needed by App-C", +"requestTime": "0000-00-00 00:00:00.000000", +"policyVersion": "1", +"VMName": "123", +"from": "test", +"msgOid": ".1.3.6.1.4.1.193.183.4.1.3.5.1.4", +"VMID": "abc12345-1234-5678-890a-abcdefg12345", +"trapID": "1234567", +"requestClient": "test", +"message": "Abnormal condition detected", +"time": "123567890", +"policyName": "RESTART", +"trapIDOID": ".1.3.6.1.4.1.193.183.4.1.3.5.1.3", +"request": "Restart", +"OPS_CL_timer": "15", +"nOID": ".1.3.6.1.4.1.193.183.4.2.0.4", +"AgentAddress": "192.168.1.2", +"vmOID": ".1.3.6.1.4.1.193.183.4.1.2.1", +"TenantID": "abcde12345fghijk6789lmnopq123rst", +"VServerSelfLink": "http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345" +}
\ No newline at end of file diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/resources/IncomingMessage1607.txt b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/resources/IncomingMessage1607.txt new file mode 100644 index 000000000..667cfae8c --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/resources/IncomingMessage1607.txt @@ -0,0 +1,24 @@ +{ + "CommonHeader": { + "TimeStamp": "0000-00-00T00:00:00.000Z", + "APIver": "1.01", + "OriginatorID": "policy.pdp01", + "RequestID": "b74d13c5-bb26-4b04-992c-4679dfc8280e", + "SubrequestID": "1" + }, + "Action": "RESTART", + "Payload": { + "VServerSelfLink": "http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345", + "VNF_NAME": "test", + "VMID": "abc12345-1234-5678-890a-abcdefg12345", + "TenantID": "abcde12345fghijk6789lmnopq123rst", + "LOC_ID": "Test", + "in-maint": "false", + "Identity": "http://example.com:5000/v2.0", + "Prov_status": "ACTIVE", + "OAM_IPV4": "192.168.1.2", + "is-closed-loop-disabled": "false", + "VM_NAME": "test", + "OAM_IPV6": "0000::0000:0000:0000:0000/64" + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/resources/OutgoingMessage.txt b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/resources/OutgoingMessage.txt new file mode 100644 index 000000000..c5d6c5b56 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/resources/OutgoingMessage.txt @@ -0,0 +1,14 @@ +{ +"eventID": "SomeEventID-TBD", + +"VMName": "test", +"from": "appc@test", +"message": "Some Text Here", +"requestClient": "test", +"requestTime": "0000-00-00 00:00:00.000000", +"response": "PENDING", +"responseTime": "0000-00-00 00:00:00.000000", + +"policyName": "RESTART", +"policyVersion": "1" +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/resources/OutgoingMessage1607.txt b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/resources/OutgoingMessage1607.txt new file mode 100644 index 000000000..898eb622e --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/resources/OutgoingMessage1607.txt @@ -0,0 +1,27 @@ +{ + "CommonHeader": { + "TimeStamp": "0000-00-00T00:00:00.000Z", + "APIver": "1.01", + "OriginatorID": "policy.pdp01", + "RequestID": "b74d13c5-bb26-4b04-992c-4679dfc8280e", + "SubrequestID": "1" + }, + "Status": { + "Code": 100, + "Value": "ACCEPT" + }, + "Payload": { + "VServerSelfLink": "http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345", + "VNF_NAME": "test", + "VMID": "abc12345-1234-5678-890a-abcdefg12345", + "TenantID": "abcde12345fghijk6789lmnopq123rst", + "LOC_ID": "Test", + "in-maint": "false", + "Identity": "http://example.com:5000/v2.0", + "Prov_status": "ACTIVE", + "OAM_IPV4": "192.168.1.2", + "is-closed-loop-disabled": "false", + "VM_NAME": "test", + "OAM_IPV6": "0000::0000:0000:0000:0000/64" + } +} diff --git a/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..7a65b7195 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-bundle/src/test/resources/org/openecomp/appc/default.properties @@ -0,0 +1,89 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + + + + + +### ### +### ### +###Properties below are default values to be provided with real valuesin appc.properties### +### ### +### ### + + + + + +### ### +###Closed Loop - properties ### +### ### +test.prefix=appc.ClosedLoop +appc.ClosedLoop.disabled=false +appc.ClosedLoop.service=UEB +appc.ClosedLoop.poolMembers=192.168.1.2:3904 +appc.ClosedLoop.topic.read=APPC-TEST1 +appc.ClosedLoop.topic.read.timeout=5 +appc.ClosedLoop.topic.write=APPC-TEST1 +appc.ClosedLoop.topic.read.filter={"class":"Assigned","field":"request"} +appc.ClosedLoop.client.name=APPC-TEST1-CLOSED-LOOP +appc.ClosedLoop.client.name.id=0 + +# KEY AND SECRET BELOW NEED TO BE MODIFIED TO APPROPRIATE VALUES WHEN THE TOPIC IS API-KEY-BASED AUTH +appc.ClosedLoop.client.key=MY_API_KEY +appc.ClosedLoop.client.secret=MY_API_SECRET + +appc.ClosedLoop.threads.queuesize.min=1 +appc.ClosedLoop.threads.queuesize.max=1000 +appc.ClosedLoop.threads.poolsize.min=1 +appc.ClosedLoop.threads.poolsize.max=2 +appc.ClosedLoop.provider.url=https://admin:password@localhost:8443/restconf/operations/appc-provider:topology-operation + + + + + +### ### +###Closed Loop - 1607 properties ### +### ### +appc.ClosedLoop1607.poolMembers=192.168.1.2:3904 +appc.ClosedLoop1607.topic.read=MY_DMAAP_TOPIC +appc.ClosedLoop1607.topic.write=MY_DMAAP_TOPIC +appc.ClosedLoop1607.topic.read.filter={"class":"Unassigned","field":"Status"} +appc.ClosedLoop1607.client.name=DMAAP-CLIENT-NAME +appc.ClosedLoop1607.client.name.id=0 +#dmaap.client.key=random +#dmaap.client.secret=random +appc.ClosedLoop1607.threads.queuesize.min=1 +appc.ClosedLoop1607.threads.queuesize.max=1000 +appc.ClosedLoop1607.threads.poolsize.min=1 +appc.ClosedLoop1607.threads.poolsize.max=2 +appc.ClosedLoop1607.provider.url=https://admin:password@localhost:8443/restconf/operations/appc-provider:topology-operation + + + + + +### ### +### POINT TO AN ACTIVE TEST VM IN OPENSTACK INSTANCE ### +### ### +test.vm_url=https://example.com/v2/123/servers/123-345 + diff --git a/app-c/appc/appc-event-listener/appc-event-listener-features/.gitignore b/app-c/appc/appc-event-listener/appc-event-listener-features/.gitignore new file mode 100644 index 000000000..2992ae832 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-features/.gitignore @@ -0,0 +1,3 @@ +/target/ +/bin/ +/.settings/ diff --git a/app-c/appc/appc-event-listener/appc-event-listener-features/pom.xml b/app-c/appc/appc-event-listener/appc-event-listener-features/pom.xml new file mode 100644 index 000000000..ddc01180c --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-features/pom.xml @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-event-listener</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>appc-event-listener-features</artifactId> + <name>Event Listener - Features</name> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-event-listener-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>features-mdsal</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </dependency> + + <!-- dependency for opendaylight-karaf-empty for use by testing --> +<!-- <dependency> --> +<!-- <groupId>org.opendaylight.controller</groupId> --> +<!-- <artifactId>opendaylight-karaf-empty</artifactId> --> +<!-- <type>zip</type> --> +<!-- </dependency> --> + + + <!-- Required for launching the feature tests --> +<!-- <dependency> --> +<!-- <groupId>org.opendaylight.yangtools</groupId> --> +<!-- <artifactId>features-test</artifactId> --> +<!-- <scope>test</scope> --> +<!-- </dependency> --> + + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>features-yangtools</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <!-- launches the feature test, which validates that your karaf feature + can be installed inside of a karaf container. It doesn't validate that your + functionality works correctly, just that you have all of the dependent bundles + defined correctly. --> + <!-- <plugin> --> + <!-- <groupId>org.apache.maven.plugins</groupId> --> + <!-- <artifactId>maven-surefire-plugin</artifactId> --> + <!-- <version>2.16</version> --> + <!-- <configuration> --> + <!-- <systemPropertyVariables> --> + <!-- <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId> --> + <!-- <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId> --> + <!-- <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version> --> + <!-- </systemPropertyVariables> --> + <!-- <dependenciesToScan> --> + <!-- <dependency>org.opendaylight.yangtools:features-test</dependency> --> + <!-- </dependenciesToScan> --> + <!-- </configuration> --> + <!-- </plugin> --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-event-listener/appc-event-listener-features/src/main/resources/features.xml b/app-c/appc/appc-event-listener/appc-event-listener-features/src/main/resources/features.xml new file mode 100644 index 000000000..31e2d8f0a --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-features/src/main/resources/features.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="appc-event-listener-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + +<!-- <repository>mvn:org.opendaylight.mdsal/features-mdsal/${odl.mdsal.version}/xml/features</repository> --> + <repository>mvn:org.opendaylight.mdsal/features-mdsal/${features-mdsal.version}/xml/features</repository> + + <feature name='appc-event-listener' description="event listener" version='${project.version}'> + <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> +<!-- <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> --> + <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> + <bundle>mvn:org.openecomp.appc/appc-event-listener-bundle/${project.version}</bundle> + + </feature> + +</features> diff --git a/app-c/appc/appc-event-listener/appc-event-listener-installer/.gitignore b/app-c/appc/appc-event-listener/appc-event-listener-installer/.gitignore new file mode 100644 index 000000000..731eb433c --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-installer/.gitignore @@ -0,0 +1,2 @@ +/target/ +/.settings/ diff --git a/app-c/appc/appc-event-listener/appc-event-listener-installer/pom.xml b/app-c/appc/appc-event-listener/appc-event-listener-installer/pom.xml new file mode 100644 index 000000000..b18d0341a --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-installer/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-event-listener</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>appc-event-listener-installer</artifactId> + <name>APPC Event Listener - Karaf Installer</name> + <packaging>pom</packaging> + + <properties> + <application.name>appc-event-listener</application.name> + <features.boot>appc-event-listener</features.boot> + <features.repositories>mvn:org.openecomp.appc/appc-event-listener-features/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-event-listener-features</artifactId> + <version>${project.version}</version> + <classifier>features</classifier> + <type>xml</type> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-event-listener-bundle</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>false</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>true</attach> + <finalName>${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <excludeGroupIds>org.opendaylight</excludeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals> + <!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-event-listener/appc-event-listener-installer/src/assembly/assemble_installer_zip.xml b/app-c/appc/appc-event-listener/appc-event-listener-installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..8948a3302 --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>controller</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/app-c/appc/appc-event-listener/appc-event-listener-installer/src/assembly/assemble_mvnrepo_zip.xml b/app-c/appc/appc-event-listener/appc-event-listener-installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..a18efd00b --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,47 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>controller</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + +</assembly> diff --git a/app-c/appc/appc-event-listener/appc-event-listener-installer/src/main/resources/scripts/install-feature.sh b/app-c/appc/appc-event-listener/appc-event-listener-installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..1d769fada --- /dev/null +++ b/app-c/appc/appc-event-listener/appc-event-listener-installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,40 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +#!/bin/bash + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -n -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot} diff --git a/app-c/appc/appc-event-listener/pom.xml b/app-c/appc/appc-event-listener/pom.xml new file mode 100644 index 000000000..ad785fc55 --- /dev/null +++ b/app-c/appc/appc-event-listener/pom.xml @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc</artifactId> + <version>1.0.0</version> + </parent> + + <artifactId>appc-event-listener</artifactId> + <name>Event Listener</name> + <description>Listener to read and write events from DMaaP (Cambria) or DMaaP.</description> + <packaging>pom</packaging> + + <reporting> + <plugins> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <additionalDependencies> + <additionalDependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4</artifactId> + <version>${antlr.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4-runtime</artifactId> + <version>4.3</version> + </additionalDependency> + </additionalDependencies> + </configuration> + <reportSets> + <reportSet> + <reports> + <report>javadoc-no-fork</report> + <report>test-javadoc-no-fork</report> + </reports> + </reportSet> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jxr-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-changelog-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>dual-report</id> + <configuration> + <type>range</type> + <range>30</range> + </configuration> + <reports> + <report>changelog</report> + <report>file-activity</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>taglist-maven-plugin</artifactId> + <version>2.4</version> + </plugin> + </plugins> + </reporting> + + <modules> + <module>appc-event-listener-bundle</module> + <module>appc-event-listener-features</module> + <module>appc-event-listener-installer</module> + </modules> +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-metric/.gitignore b/app-c/appc/appc-metric/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-metric/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-metric/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-metric/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-metric/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-metric/appc-metric-bundle/.gitignore b/app-c/appc/appc-metric/appc-metric-bundle/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-metric/appc-metric-bundle/.settings/org.eclipse.wst.common.project.facet.core.xml b/app-c/appc/appc-metric/appc-metric-bundle/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/app-c/appc/appc-metric/appc-metric-bundle/pom.xml b/app-c/appc/appc-metric/appc-metric-bundle/pom.xml new file mode 100644 index 000000000..79ec32e3a --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/pom.xml @@ -0,0 +1,111 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + + <!-- + + 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. + --> + + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-metric</artifactId> + <version>1.0.0</version> + </parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-metric-bundle</artifactId> + <packaging>bundle</packaging> + + <name>appc-metric-bundle Bundle</name> + <description>appc-metric-bundle OSGi bundle project.</description> + + <dependencies> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <version>4.2.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.11</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <version>1.10.19</version> + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-mockito</artifactId> + <version>1.6.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-core</artifactId> + <version>1.3</version> + </dependency> + <dependency> + <groupId>org.objenesis</groupId> + <artifactId>objenesis</artifactId> + <version>2.2</version> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-all</artifactId> + <version>1.8.4</version> + </dependency> + + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-junit4</artifactId> + <version>1.6.2</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <version>2.3.7</version> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Bundle-Activator>org.openecomp.appc.MetricActivator</Bundle-Activator> + <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic,appc-data-lib;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Export-Service>org.openecomp.appc.metricservice.impl.MetricServiceImpl,org.openecomp.appc.metricservice.MetricService,org.openecomp.appc.metricservice.policy.*,org.openecomp.appc.metricservice.metric.*</Export-Service> + <Export-Package>org.openecomp.appc.metricservice,org.openecomp.appc.metricservice.impl,org.openecomp.appc.metricservice.policy,org.openecomp.appc.metricservice.publisher,org.openecomp.appc.metricservice.metric</Export-Package> + <Import-Package>!groovy.lang,!javax.*,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.apache.commons.lang3,!org.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/MetricActivator.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/MetricActivator.java new file mode 100644 index 000000000..8da102670 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/MetricActivator.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc; + +import org.openecomp.appc.metricservice.MetricService; +import org.openecomp.appc.metricservice.impl.MetricServiceImpl; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + + +public class MetricActivator implements BundleActivator { + + private ServiceRegistration registration = null; + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(MetricActivator.class); + + @Override + public void start(BundleContext bundleContext) throws Exception { + logger.debug("Starting Metric service " ); + MetricService impl = new MetricServiceImpl(); + String regName = MetricService.class.getName(); + logger.debug("Registering Metric service " + regName); + registration = bundleContext.registerService(regName, impl, null); + logger.debug("Registered Metric service " + regName); + } + + @Override + public void stop(BundleContext bundleContext) throws Exception { + + } +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/MetricRegistry.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/MetricRegistry.java new file mode 100644 index 000000000..f2f6e1bb2 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/MetricRegistry.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice; + +import org.openecomp.appc.metricservice.metric.Counter; +import org.openecomp.appc.metricservice.metric.Metric; +import org.openecomp.appc.metricservice.metric.MetricBuilderFactory; +import org.openecomp.appc.metricservice.policy.PolicyBuilderFactory; +import org.openecomp.appc.metricservice.policy.PublishingPolicy; + +/** + * + * A named group of metrics which might be related to a specific domain. The service doesn't limit number of metric registries per instance. + * It's up to application to decide on domain scope. The registry instances are independent. + * + */ +public interface MetricRegistry { + boolean register(Metric metric); + void attach (PublishingPolicy publishPolicy); + MetricBuilderFactory metricBuilderFactory(); + PolicyBuilderFactory policyBuilderFactory(); + Counter counter(String value); + Counter[] counters(); + Metric[] metrics(); + Metric metric(String metricName); + void dispose(); +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/MetricService.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/MetricService.java new file mode 100644 index 000000000..b75ca2a30 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/MetricService.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice; + + +public interface MetricService { + MetricRegistry registry(String name); + MetricRegistry createRegistry(String name); + void dispose(); +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/Publisher.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/Publisher.java new file mode 100644 index 000000000..09815d07d --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/Publisher.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice; + +import org.openecomp.appc.metricservice.metric.Metric; + +/** + * Low-level logic of exposing metric values in certain way. There might be plenty of options such as logging, JMX, etc. + * API to be supported by any logic that is going to be plugged into metric service. + * The publisher is considered as low-level technical unit which, potentially, can be reused to expose metrics from different registries + * + */ +public interface Publisher { + void publish(MetricRegistry metricRegistry,Metric[] metrics); +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/impl/MetricRegistryImpl.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/impl/MetricRegistryImpl.java new file mode 100644 index 000000000..a36ccb37b --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/impl/MetricRegistryImpl.java @@ -0,0 +1,98 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.impl; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.openecomp.appc.metricservice.MetricRegistry; +import org.openecomp.appc.metricservice.metric.Counter; +import org.openecomp.appc.metricservice.metric.Metric; +import org.openecomp.appc.metricservice.metric.MetricBuilderFactory; +import org.openecomp.appc.metricservice.metric.impl.MetricBuilderFactoryImpl; +import org.openecomp.appc.metricservice.policy.PolicyBuilderFactory; +import org.openecomp.appc.metricservice.policy.PublishingPolicy; +import org.openecomp.appc.metricservice.policy.impl.PolicyBuilderFactoryImpl; + + +public class MetricRegistryImpl implements MetricRegistry { + private String name; + private Map<String,Metric> concurrentMetricMap=new ConcurrentHashMap<String,Metric>(); + + public MetricRegistryImpl(String name) { + this.name = name; + } + + @Override + public boolean register(Metric metric) { + if(concurrentMetricMap.get(metric.name())==null){ + concurrentMetricMap.put(metric.name(),metric); + return true; + } + return false; + } + + @Override + public void attach(PublishingPolicy publishPolicy) { +//TODO + } + + @Override + public MetricBuilderFactory metricBuilderFactory() { + return new MetricBuilderFactoryImpl(); + } + + @Override + public PolicyBuilderFactory policyBuilderFactory() { + return new PolicyBuilderFactoryImpl() ; + } + + @Override + public Counter counter(String value) { + if(concurrentMetricMap.get(value)!=null ) + return (Counter)concurrentMetricMap.get(value) ; + else + return null; + + } + + @Override + public Counter[] counters() { + return (Counter[])concurrentMetricMap.values().toArray(); + } + + @Override + public Metric[] metrics() { + java.util.Collection<Metric> var = concurrentMetricMap.values(); + return var.toArray(new Metric[var.size()]); + } + + @Override + public Metric metric(String metricName) { + return concurrentMetricMap.get(metricName); + } + + @Override + public void dispose() { + concurrentMetricMap.clear(); + } +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/impl/MetricServiceImpl.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/impl/MetricServiceImpl.java new file mode 100644 index 000000000..6e5ca9d10 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/impl/MetricServiceImpl.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.impl; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.openecomp.appc.metricservice.MetricRegistry; +import org.openecomp.appc.metricservice.MetricService; + + +public class MetricServiceImpl implements MetricService { + private Map<String,MetricRegistry> concurrentRegistryMap=new ConcurrentHashMap<>(); + @Override + public MetricRegistry registry(String name) { + return concurrentRegistryMap.get(name); + } + + @Override + public MetricRegistry createRegistry(String name) { + if(concurrentRegistryMap.get(name)==null) + concurrentRegistryMap.put(name,new MetricRegistryImpl(name)); + return concurrentRegistryMap.get(name); + } + + @Override + public void dispose() { +//TODO + } +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/Counter.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/Counter.java new file mode 100644 index 000000000..e02b5b8d9 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/Counter.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.metric; + + +public interface Counter extends Metric { + long value(); +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/DispatchingFunctionCounterBuilder.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/DispatchingFunctionCounterBuilder.java new file mode 100644 index 000000000..bb6090c63 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/DispatchingFunctionCounterBuilder.java @@ -0,0 +1,31 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.metric; + + +public interface DispatchingFunctionCounterBuilder { + DispatchingFunctionCounterBuilder withName(String name); + DispatchingFunctionCounterBuilder withAcceptRequestValue(long value); + DispatchingFunctionCounterBuilder withRejectRequestValue(long value); + DispatchingFunctionCounterBuilder withType(MetricType type); + DispatchingFuntionMetric build(); +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/DispatchingFuntionMetric.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/DispatchingFuntionMetric.java new file mode 100644 index 000000000..c4666c8ba --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/DispatchingFuntionMetric.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.metric; + + +public interface DispatchingFuntionMetric extends Metric { + void incrementAcceptedRequest(); + void incrementRejectedRequest(); + String value(); +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/DmaapRequestCounterBuilder.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/DmaapRequestCounterBuilder.java new file mode 100644 index 000000000..553b54db0 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/DmaapRequestCounterBuilder.java @@ -0,0 +1,31 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.metric; + + +public interface DmaapRequestCounterBuilder { + DmaapRequestCounterBuilder withName(String name); + DmaapRequestCounterBuilder withRecievedMessage(long value); + DmaapRequestCounterBuilder withPublishedMessage(long value); + DmaapRequestCounterBuilder withType(MetricType type); + DmaapRequestCounterMetric build(); +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/DmaapRequestCounterMetric.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/DmaapRequestCounterMetric.java new file mode 100644 index 000000000..02fc40520 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/DmaapRequestCounterMetric.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.metric; + + +public interface DmaapRequestCounterMetric extends Metric { + void incrementRecievedMessage(); + void incrementPublishedMessage(); + String value(); +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/Metric.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/Metric.java new file mode 100644 index 000000000..10b8daacf --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/Metric.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.metric; + +/** + * + * a measure of system parameter at the current moment. Each metric is identified by name. + * In general case, a metric just reflects its (almost) real-time value and is not responsible for maintaining its historical data. + * One that needs to build series of a metric values for statistical/analytic purposes should query the value and store it for further processing. + * Metrics can be of different types - counters, timers etc. + * The initial service implementation supports simple (flat) counters only. + * + */ +public interface Metric { + String name(); + void reset(); + MetricType type(); +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/MetricBuilderFactory.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/MetricBuilderFactory.java new file mode 100644 index 000000000..d4a05c300 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/MetricBuilderFactory.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.metric; + + +public interface MetricBuilderFactory { + + PrimitiveCounterBuilder primitiveCounterBuilder(); + DispatchingFunctionCounterBuilder dispatchingFunctionCounterBuilder(); + DmaapRequestCounterBuilder dmaapRequestCounterBuilder(); +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/MetricType.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/MetricType.java new file mode 100644 index 000000000..7ee731a1a --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/MetricType.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.metric; + +/** + * + * Auxiliary enumeration that lists all the supported metric types. + * Can be used for generic processing of metrics rather than using Java reflection mechanisms to determine metric kind. + * + */ +public enum MetricType { +COUNTER +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/PrimitiveCounter.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/PrimitiveCounter.java new file mode 100644 index 000000000..1e0d90ef7 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/PrimitiveCounter.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.metric; + +/** + * + * The simplest metric of type counter which mutable value. + */ +public interface PrimitiveCounter extends Counter{ + void increment(); + void increment(long value); + void decrement(); + void decrement(long value); +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/PrimitiveCounterBuilder.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/PrimitiveCounterBuilder.java new file mode 100644 index 000000000..42b024803 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/PrimitiveCounterBuilder.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.metric; + +/** + * + * Builder interface which can be used to instantiate and initialize a new primitive counter instance. + */ +public interface PrimitiveCounterBuilder { + PrimitiveCounterBuilder withName(String name); + PrimitiveCounterBuilder withValue(long value); + PrimitiveCounterBuilder withType(MetricType type); + PrimitiveCounter build(); +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DefaultPrimitiveCounter.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DefaultPrimitiveCounter.java new file mode 100644 index 000000000..c41def981 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DefaultPrimitiveCounter.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.metric.impl; + +import org.openecomp.appc.metricservice.metric.MetricType; +import org.openecomp.appc.metricservice.metric.PrimitiveCounter; + + +public class DefaultPrimitiveCounter implements PrimitiveCounter{ + private String name; + private MetricType metricType; + private long counter; + + public DefaultPrimitiveCounter(String name, MetricType metricType, long counter) { + this.name = name; + this.metricType = metricType; + this.counter = counter; + } + + public DefaultPrimitiveCounter(String name, MetricType metricType) { + this.counter=0; + this.name = name; + this.metricType = metricType; + } + + @Override + public void increment() { + increment(1); + } + + @Override + public void increment(long value) { + this.counter+=value; + } + + @Override + public void decrement() { + decrement(1); + } + + @Override + public void decrement(long value) { + this.counter-=value; + } + + @Override + public long value() { + return this.counter; + } + + @Override + public String name() { + return this.name; + } + + @Override + public void reset() { + this.counter=0 ; + } + + @Override + public String toString() { + return "DefaultPrimitiveCounter{" + + "name='" + name + '\'' + + ", metricType=" + metricType + + ", counter=" + counter + + '}'; + } + + @Override + public MetricType type() { + return this.metricType; + } +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DispatchingFunctionCounterBuilderImpl.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DispatchingFunctionCounterBuilderImpl.java new file mode 100644 index 000000000..57a4234c4 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DispatchingFunctionCounterBuilderImpl.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.metric.impl; + +import org.openecomp.appc.metricservice.metric.DispatchingFunctionCounterBuilder; +import org.openecomp.appc.metricservice.metric.DispatchingFuntionMetric; +import org.openecomp.appc.metricservice.metric.MetricType; + + +public class DispatchingFunctionCounterBuilderImpl implements DispatchingFunctionCounterBuilder { + private String name; + private MetricType metricType; + private long acceptedRequested; + private long rejectedRequest; + + @Override + public DispatchingFunctionCounterBuilder withName(String name) { + this.name=name; + return this; + } + + @Override + public DispatchingFunctionCounterBuilder withAcceptRequestValue(long value) { + this.acceptedRequested=value; + return this; + } + @Override + public DispatchingFunctionCounterBuilder withRejectRequestValue(long value) { + this.rejectedRequest=value; + return this; + } + @Override + public DispatchingFunctionCounterBuilder withType(MetricType type) { + this.metricType=type; + return this; + } + + @Override + public DispatchingFuntionMetric build() { + return new DispatchingFuntionMetricImpl(this.name,this.metricType,this.acceptedRequested,this.rejectedRequest); + } +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DispatchingFuntionMetricImpl.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DispatchingFuntionMetricImpl.java new file mode 100644 index 000000000..0dd3b97bf --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DispatchingFuntionMetricImpl.java @@ -0,0 +1,97 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.metric.impl; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +import org.openecomp.appc.metricservice.metric.DispatchingFuntionMetric; +import org.openecomp.appc.metricservice.metric.MetricType; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + + +public class DispatchingFuntionMetricImpl implements DispatchingFuntionMetric { + private String name; + private MetricType metricType; + private long acceptedRequested; + private long rejectedRequest; + private static final SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd"); + private static final EELFLogger logger = EELFManager.getInstance().getLogger(DmaapRequestCounterMetricImpl.class); + + public DispatchingFuntionMetricImpl(String name, MetricType metricType, long acceptedRequested, long rejectedRequest) { + this.name = name; + this.metricType = metricType; + this.acceptedRequested = acceptedRequested; + this.rejectedRequest = rejectedRequest; + } + + @Override + public void incrementAcceptedRequest() { + this.acceptedRequested+=1; + } + + @Override + public void incrementRejectedRequest() { + this.rejectedRequest+=1; + } + + @Override + public String value() { + logger.debug("Value is getting calculated for metric :" + this.name); + try{ + Calendar cal = Calendar.getInstance(); + cal.setTimeZone(TimeZone.getTimeZone("UTC")); + String date=dateFormat.format(cal.getTime()); + String value=date+"["+acceptedRequested+","+rejectedRequest+"]"+"@"+(acceptedRequested+rejectedRequest); + logger.debug("Current value of the metric "+this.name+" :"+value); + return value ; + + }catch (Exception e){ + logger.debug("Cant format the date."); + } + return null; + + } + + @Override + public String name() { + return this.name; + } + + @Override + public void reset() { + this.acceptedRequested=0; + this.rejectedRequest=0; + } + + @Override + public MetricType type() { + return this.metricType; + } + @Override + public String toString() { + return this.value(); + } +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DmaapRequestCounterBuilderImpl.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DmaapRequestCounterBuilderImpl.java new file mode 100644 index 000000000..65aefed3e --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DmaapRequestCounterBuilderImpl.java @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.metric.impl; + +import org.openecomp.appc.metricservice.metric.MetricType; +import org.openecomp.appc.metricservice.metric.DmaapRequestCounterBuilder; +import org.openecomp.appc.metricservice.metric.DmaapRequestCounterMetric; + + +public class DmaapRequestCounterBuilderImpl implements DmaapRequestCounterBuilder { + private String name; + private MetricType metricType; + private long recievedMessage; + private long publishedMessage; + + @Override + public DmaapRequestCounterBuilder withName(String name) { + this.name=name; + return this; + } + + @Override + public DmaapRequestCounterBuilder withRecievedMessage(long value) { + + this.recievedMessage=value; + return this; + } + + @Override + public DmaapRequestCounterBuilder withPublishedMessage(long value) { + this.publishedMessage=value; + return this; + } + + @Override + public DmaapRequestCounterBuilder withType(MetricType type) { + this.metricType=type; + return this; + } + + @Override + public DmaapRequestCounterMetric build() { + return new DmaapRequestCounterMetricImpl(this.name,this.metricType,this.recievedMessage,this.publishedMessage); + } +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DmaapRequestCounterMetricImpl.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DmaapRequestCounterMetricImpl.java new file mode 100644 index 000000000..877fa6e31 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DmaapRequestCounterMetricImpl.java @@ -0,0 +1,96 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.metric.impl; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +import org.openecomp.appc.metricservice.metric.MetricType; +import org.openecomp.appc.metricservice.metric.DmaapRequestCounterMetric; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + + +public class DmaapRequestCounterMetricImpl implements DmaapRequestCounterMetric { + + private String name; + private MetricType metricType; + private long recievedMessage; + private long publishedMessage; + private static final SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd"); + private static final EELFLogger logger = EELFManager.getInstance().getLogger(DmaapRequestCounterMetricImpl.class); + public DmaapRequestCounterMetricImpl(String name, MetricType metricType, long recievedMessage, long publishedMessage) { + this.name = name; + this.metricType = metricType; + this.recievedMessage = recievedMessage; + this.publishedMessage=publishedMessage; + } + + @Override + public void incrementRecievedMessage() { + this.recievedMessage+=1; + } + + @Override + public void incrementPublishedMessage() { + this.publishedMessage+=1; + } + + @Override + public String value() { + logger.debug("Value is getting calculated for metric :" + this.name); + try{ + Calendar cal = Calendar.getInstance(); + cal.setTimeZone(TimeZone.getTimeZone("UTC")); + String date=dateFormat.format(cal.getTime()); + String value=date+"["+recievedMessage+"],["+publishedMessage+"]"; + logger.debug("Current value of the metric "+this.name+" :"+value); + return value; + }catch (Exception e){ + logger.debug("Cant format the date."); + } + return null; + } + + @Override + public String name() { + return this.name; + } + + @Override + public void reset() { + this.recievedMessage=0; + this.publishedMessage=0; + } + + @Override + public MetricType type() { + return this.metricType; + } + + @Override + public String toString() { + return this.value(); + } +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/MetricBuilderFactoryImpl.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/MetricBuilderFactoryImpl.java new file mode 100644 index 000000000..f08ffa84d --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/MetricBuilderFactoryImpl.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.metric.impl; + +import org.openecomp.appc.metricservice.metric.DispatchingFunctionCounterBuilder; +import org.openecomp.appc.metricservice.metric.MetricBuilderFactory; +import org.openecomp.appc.metricservice.metric.PrimitiveCounterBuilder; +import org.openecomp.appc.metricservice.metric.DmaapRequestCounterBuilder; + + +public class MetricBuilderFactoryImpl implements MetricBuilderFactory { + @Override + public PrimitiveCounterBuilder primitiveCounterBuilder() { + return new PrimitiveCounterBuilderImpl(); + } + + @Override + public DispatchingFunctionCounterBuilder dispatchingFunctionCounterBuilder() { + return new DispatchingFunctionCounterBuilderImpl() ; + } + + @Override + public DmaapRequestCounterBuilder dmaapRequestCounterBuilder() { + return new DmaapRequestCounterBuilderImpl(); + } +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/PrimitiveCounterBuilderImpl.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/PrimitiveCounterBuilderImpl.java new file mode 100644 index 000000000..ec6a1843b --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/PrimitiveCounterBuilderImpl.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.metric.impl; + +import org.openecomp.appc.metricservice.metric.MetricType; +import org.openecomp.appc.metricservice.metric.PrimitiveCounter; +import org.openecomp.appc.metricservice.metric.PrimitiveCounterBuilder; + + +public class PrimitiveCounterBuilderImpl implements PrimitiveCounterBuilder { + private String name; + private MetricType metricType; + private long counter; + + @Override + public PrimitiveCounterBuilder withName(String name) { + this.name=name; + return this; + } + + @Override + public PrimitiveCounterBuilder withValue(long value) { + this.counter=value; + return this; + } + + @Override + public PrimitiveCounterBuilder withType(MetricType type) { + this.metricType=type; + return this; + } + + @Override + public PrimitiveCounter build() { + return new DefaultPrimitiveCounter(this.name,this.metricType,this.counter); + } +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/PolicyBuilderFactory.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/PolicyBuilderFactory.java new file mode 100644 index 000000000..e38282506 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/PolicyBuilderFactory.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.policy; + + +public interface PolicyBuilderFactory { + ScheduledPolicyBuilder scheduledPolicyBuilder(); +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/PublishingPolicy.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/PublishingPolicy.java new file mode 100644 index 000000000..34eaa52a5 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/PublishingPolicy.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.policy; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.metricservice.metric.Metric; + +/** + * + * A custom logic that determines strategy of exposing metric values. + * Policy is associated with a specific registry and its implementation can very from the simplest options, such as 'real-time' behavior (upon each value change) to more sophisticated approaches such as thresholds or recurrent scheduling rules. + * The policy can also decide whether or not to publish the entire metric registry or just a subset of the it (e.g. changed ones). + * Policy supports execution of one or more Publishers. + * + */ +public interface PublishingPolicy { + void onMetricChange(Metric meric) throws APPCException; + Metric[] metrics(); + + void init(); +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/ScheduledPolicyBuilder.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/ScheduledPolicyBuilder.java new file mode 100644 index 000000000..0eff940fb --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/ScheduledPolicyBuilder.java @@ -0,0 +1,38 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.policy; + +import org.openecomp.appc.metricservice.Publisher; +import org.openecomp.appc.metricservice.metric.Metric; + +/** + * + * An auxiliary class to instantiate scheduler-based policy delivered along with the initial release of the service. + * + */ +public interface ScheduledPolicyBuilder { + ScheduledPolicyBuilder withStartTime(long time); + ScheduledPolicyBuilder withPeriod(long period); + ScheduledPolicyBuilder withPublishers(Publisher[] publishers); + ScheduledPolicyBuilder withMetrics(Metric[] metrics); + PublishingPolicy build(); +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/ScheduledPublishingPolicy.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/ScheduledPublishingPolicy.java new file mode 100644 index 000000000..5f264a661 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/ScheduledPublishingPolicy.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.policy; + +import org.openecomp.appc.metricservice.Publisher; + + +public interface ScheduledPublishingPolicy extends PublishingPolicy{ + + long getStartTime(); + long getPeriod(); + Publisher[] getPublishers(); + void reset(); +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/impl/PolicyBuilderFactoryImpl.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/impl/PolicyBuilderFactoryImpl.java new file mode 100644 index 000000000..01296e10a --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/impl/PolicyBuilderFactoryImpl.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.policy.impl; + +import org.openecomp.appc.metricservice.policy.PolicyBuilderFactory; +import org.openecomp.appc.metricservice.policy.ScheduledPolicyBuilder; + + +public class PolicyBuilderFactoryImpl implements PolicyBuilderFactory { + @Override + public ScheduledPolicyBuilder scheduledPolicyBuilder() { + return new ScheduledPolicyBuilderImpl(); + } +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/impl/ScheduledPolicyBuilderImpl.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/impl/ScheduledPolicyBuilderImpl.java new file mode 100644 index 000000000..aa84e311a --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/impl/ScheduledPolicyBuilderImpl.java @@ -0,0 +1,65 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.policy.impl; + +import org.openecomp.appc.metricservice.Publisher; +import org.openecomp.appc.metricservice.metric.Metric; +import org.openecomp.appc.metricservice.policy.PublishingPolicy; +import org.openecomp.appc.metricservice.policy.ScheduledPolicyBuilder; + + +public class ScheduledPolicyBuilderImpl implements ScheduledPolicyBuilder { + + private long startTime; + private long period; + private Publisher[] publishers; + private Metric[] metrics; + + @Override + public ScheduledPolicyBuilder withStartTime(long time) { + this.startTime=time; + return this; + } + + @Override + public ScheduledPolicyBuilder withPeriod(long period) { + this.period=period; + return this; + } + + @Override + public ScheduledPolicyBuilder withPublishers(Publisher[] publishers) { + this.publishers=publishers; + return this; + } + + @Override + public ScheduledPolicyBuilder withMetrics(Metric[] metrics) { + this.metrics=metrics; + return this; + } + + @Override + public PublishingPolicy build() { + return new ScheduledPublishingPolicyImpl(this.publishers,this.metrics); + } +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/impl/ScheduledPublishingPolicyImpl.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/impl/ScheduledPublishingPolicyImpl.java new file mode 100644 index 000000000..8c3dd49c3 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/policy/impl/ScheduledPublishingPolicyImpl.java @@ -0,0 +1,221 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.policy.impl; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Properties; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; + +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.metricservice.MetricRegistry; +import org.openecomp.appc.metricservice.MetricService; +import org.openecomp.appc.metricservice.Publisher; +import org.openecomp.appc.metricservice.metric.Metric; +import org.openecomp.appc.metricservice.policy.ScheduledPublishingPolicy; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + + +public class ScheduledPublishingPolicyImpl implements ScheduledPublishingPolicy { + private long startTime; + private long period; + private Publisher[] publishers; + private Metric[] metrics; + private MetricRegistry metricRegistry; + private static final EELFLogger logger = EELFManager.getInstance().getLogger(ScheduledPublishingPolicyImpl.class); + private ScheduledExecutorService scheduleExecutor; + private Configuration configuration; + + public ScheduledPublishingPolicyImpl(long startTime, long period, Publisher[] publishers, Metric[] metrics) { + this.startTime = startTime; + this.period = period; + this.publishers = publishers; + this.metrics = metrics; + this.scheduleExecutor= Executors.newSingleThreadScheduledExecutor(getThreadFactory(true)); + } + + public ScheduledPublishingPolicyImpl( Publisher[] publishers, Metric[] metrics) { + configuration = ConfigurationFactory.getConfiguration(); + Properties properties=configuration.getProperties(); + if(properties!=null){ + if(properties.getProperty("schedule.policy.metric.period")!=null && properties.getProperty("schedule.policy.metric.start.time")!=null){ + this.startTime = getConfigStartTime(properties); + this.period = getConfigPeriod(properties); + logger.info("Metric Properties read from configuration Start Time :"+this.startTime+", Period :"+this.period); + }else if(properties.getProperty("schedule.policy.metric.period")!=null){ + this.startTime=1; + this.period=getConfigPeriod(properties); + logger.info("Metric Properties read from configuration Start Time :"+this.startTime+", Period :"+this.period); + + }else if(properties.getProperty("schedule.policy.metric.period")==null && properties.getProperty("schedule.policy.metric.start.time")!=null){ + this.startTime=getConfigStartTime("00:00:00",properties); + this.period=(24*60*60*1000)-1; + logger.info("Metric Properties read from configuration Start Time :"+this.startTime+", Period :"+this.period); + + }else{ + logger.info("Metric Properties coming as null,setting to default Start Time :1 ms,Period : 100000 ms"); + this.startTime = 1; + this.period = 100000; + logger.info("Metric Properties read from configuration Start Time :"+this.startTime+", Period :"+this.period); + + } + } else { + logger.info("Metric Properties coming as null,setting to default Start Time :1 ms,Period : 100000 ms"); + this.startTime = 1; + this.period = 100000; + logger.info("Metric Properties read from configuration Start Time :"+this.startTime+", Period :"+this.period); + } + this.publishers = publishers; + this.metrics = metrics; + this.scheduleExecutor= Executors.newSingleThreadScheduledExecutor(getThreadFactory(true)); + } + + private long getConfigPeriod(Properties properties) { + String period=properties.getProperty("schedule.policy.metric.period"); + logger.info("Metric period : " +period); + long periodInMs=Integer.parseInt(period)*1000; + logger.info("Metric period in long : " +periodInMs); + return periodInMs; + } + + private long getTimeInMs(String time) { + String[] strings=time.split(":"); + if(strings.length==3) { + long hour = Integer.parseInt(strings[0]) * 60 * 60 * 1000; + long min = Integer.parseInt(strings[1]) * 60 * 1000; + long sec = Integer.parseInt(strings[2]) * 1000; + return hour+min+sec; + }else{ + return 0; + } + + } + + + + private long getConfigStartTime(Properties properties) { + String startTime=properties.getProperty("schedule.policy.metric.start.time"); + if(startTime!=null){ + long timeDiff=(getTimeInMs(startTime))-(getTimeInMs((new SimpleDateFormat("HH:mm:ss")).format(new Date()))); + long period=getConfigPeriod(properties); + if(timeDiff>=0){ + return timeDiff; + }else{ + return period-((timeDiff*-1)%period); + } + } + return 0; + } + + private long getConfigStartTime(String startTime,Properties properties) { + if(startTime!=null){ + long timeDiff=(getTimeInMs(startTime))-(getTimeInMs((new SimpleDateFormat("HH:mm:ss")).format(new Date()))); + long period=getConfigPeriod(properties); + if(timeDiff>=0){ + return timeDiff%period; + }else{ + return period-((timeDiff*-1)%period); + } + } + return 0; + } + @Override + public void onMetricChange(Metric metric) throws APPCException { + //TODO + } + + @Override + public Metric[] metrics() { + return metrics; + } + + @Override + public void init() { + Properties properties=configuration.getProperties(); + boolean isMetricEnabled=false; + if(properties!=null){ + String metricProperty=properties.getProperty("metric.enabled"); + if(metricProperty!=null){ + isMetricEnabled=Boolean.valueOf(metricProperty); + } + } + if(isMetricEnabled){ + logger.info("Metric Service is enabled, hence policies getting scheduled"); + for(final Publisher publisher:this.getPublishers()){ + scheduleExecutor.scheduleWithFixedDelay(new Runnable() + { + public void run() { + try { + publisher.publish(metricRegistry, metrics); + reset(); + } catch (RuntimeException ex) { + logger.error("RuntimeException thrown from {}#report. Exception was suppressed.", publisher.getClass().getSimpleName(), ex); + } + } + } + , startTime, period, TimeUnit.MILLISECONDS); + } + }else{ + logger.info("Metric Service is not enabled, hence policies not getting scheduled"); + + } + } + + @Override + public long getStartTime() { + return this.startTime; + } + + @Override + public long getPeriod() { + return this.period; + } + + @Override + public Publisher[] getPublishers() { + return this.publishers; + } + + @Override + public void reset() { + for(Metric metric:this.metrics){ + metric.reset();} + } + + + private ThreadFactory getThreadFactory(final boolean isDaemon){ + return new ThreadFactory() { + public Thread newThread(Runnable r) { + Thread t = Executors.defaultThreadFactory().newThread(r); + t.setDaemon(isDaemon); + return t; + } + }; + } + +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/publisher/LogPublisher.java b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/publisher/LogPublisher.java new file mode 100644 index 000000000..24241abf1 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/publisher/LogPublisher.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice.publisher; + +import org.openecomp.appc.metricservice.MetricRegistry; +import org.openecomp.appc.metricservice.Publisher; +import org.openecomp.appc.metricservice.metric.Metric; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + + +public class LogPublisher implements Publisher { + private static final EELFLogger logger = EELFManager.getInstance().getLogger(LogPublisher.class); + private MetricRegistry metricRegistry; + private Metric[] metrics; + + public LogPublisher(MetricRegistry metricRegistry, Metric[] metrics) { + this.metricRegistry = metricRegistry; + this.metrics = metrics; + } + + @Override + public void publish(MetricRegistry metricRegistry, Metric[] metrics) { + for(Metric metric:metrics){ + logger.debug("LOG PUBLISHER:"+metric.name()+":"+metric.toString()); + } + } + + +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/main/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-metric/appc-metric-bundle/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..944d19010 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,28 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + + + diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/test/java/org/openecomp/appc/metricservice/TestMetricServiceImpl.java b/app-c/appc/appc-metric/appc-metric-bundle/src/test/java/org/openecomp/appc/metricservice/TestMetricServiceImpl.java new file mode 100644 index 000000000..76c871703 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/test/java/org/openecomp/appc/metricservice/TestMetricServiceImpl.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.metricservice; +import org.junit.Assert; +import org.junit.Test; +import org.openecomp.appc.metricservice.MetricRegistry; +import org.openecomp.appc.metricservice.impl.MetricServiceImpl; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + + +public class TestMetricServiceImpl { + @Test + public void createRegistryTest() { + MetricServiceImpl metricServiceImpl = new MetricServiceImpl(); + metricServiceImpl.createRegistry("anyName"); + MetricRegistry metricRegistry = metricServiceImpl.registry("anyName"); + Assert.assertNotNull(metricRegistry); + } +} diff --git a/app-c/appc/appc-metric/appc-metric-bundle/src/test/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-metric/appc-metric-bundle/src/test/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..017291e51 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-bundle/src/test/resources/org/openecomp/appc/default.properties @@ -0,0 +1,26 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded to supply configuration options +#org.openecomp.appc.bootstrap.file=executor-test.properties +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + diff --git a/app-c/appc/appc-metric/appc-metric-features/.gitignore b/app-c/appc/appc-metric/appc-metric-features/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-features/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-metric/appc-metric-features/pom.xml b/app-c/appc/appc-metric/appc-metric-features/pom.xml new file mode 100644 index 000000000..31c58e1c4 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-features/pom.xml @@ -0,0 +1,125 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-metric</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <name>appc-metric-features</name> + <artifactId>appc-metric-features</artifactId> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-metric-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>features-mdsal</artifactId> + <classifier>features</classifier> + <type>xml</type> + + <scope>runtime</scope> + </dependency>--> + + + + <!-- dependency for opendaylight-karaf-empty for use by testing --> +<!-- <dependency> --> +<!-- <groupId>org.opendaylight.controller</groupId> --> +<!-- <artifactId>opendaylight-karaf-empty</artifactId> --> +<!-- <type>zip</type> --> +<!-- </dependency> --> + + + + + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>features-yangtools</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <plugin> + <!-- launches the feature test, which validates that your karaf feature + can be installed inside of a karaf container. It doesn't validate that your + functionality works correctly, just that you have all of the dependent bundles + defined correctly. --> + <!-- Skipping ODL feature test --> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.16</version> + <configuration> + <systemPropertyVariables> + <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId> + <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId> + <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version> + </systemPropertyVariables> + <dependenciesToScan> + <dependency>org.opendaylight.yangtools:features-test</dependency> + </dependenciesToScan> + <classpathDependencyExcludes> + <!-- The dependencies which bring in AbstractDataBrokerTest class + brings in a second PaxExam container which results in the feature tests failing + with a message similar to: "ERROR o.ops4j.pax.exam.spi.PaxExamRuntime - Ambiguous + TestContainer ..." This excludes the container we don't want to use. --> + <classpathDependencyExcludes>org.ops4j.pax.exam:pax-exam-container-native</classpathDependencyExcludes> + </classpathDependencyExcludes> + <skipTests>true</skipTests> + </configuration> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-metric/appc-metric-features/src/main/resources/features.xml b/app-c/appc/appc-metric/appc-metric-features/src/main/resources/features.xml new file mode 100644 index 000000000..c7747dea0 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-features/src/main/resources/features.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="appc-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + +<!-- + <repository>mvn:org.opendaylight.mdsal/features-mdsal/${features-mdsal.version}/xml/features</repository> +--> + + <feature name='appc-metric' description="application executor" version='${project.version}'> + <!--<feature version="${project.version}">appc-aai-adapter</feature>--> + <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> + <bundle>mvn:org.openecomp.appc/appc-metric-bundle/${project.version}</bundle> + </feature> + +</features> diff --git a/app-c/appc/appc-metric/appc-metric-installer/.gitignore b/app-c/appc/appc-metric/appc-metric-installer/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-installer/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/app-c/appc/appc-metric/appc-metric-installer/pom.xml b/app-c/appc/appc-metric/appc-metric-installer/pom.xml new file mode 100644 index 000000000..c9ae60664 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-installer/pom.xml @@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-metric</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>appc-metric-installer</artifactId> + <name>APPC Metric - Karaf Installer</name> + <packaging>pom</packaging> + + <properties> + <application.name>appc-metric</application.name> + <features.boot>appc-metric</features.boot> + <features.repositories>mvn:org.openecomp.appc/appc-metric-features/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-metric-features</artifactId> + <version>${project.version}</version> + <classifier>features</classifier> + <type>xml</type> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-metric-bundle</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>false</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>true</attach> + <finalName>${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <excludeGroupIds>org.opendaylight</excludeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals> + <!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-metric/appc-metric-installer/src/assembly/assemble_installer_zip.xml b/app-c/appc/appc-metric/appc-metric-installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..8948a3302 --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>controller</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/app-c/appc/appc-metric/appc-metric-installer/src/assembly/assemble_mvnrepo_zip.xml b/app-c/appc/appc-metric/appc-metric-installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..a18efd00b --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,47 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>controller</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + +</assembly> diff --git a/app-c/appc/appc-metric/appc-metric-installer/src/main/resources/scripts/install-feature.sh b/app-c/appc/appc-metric/appc-metric-installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..1d769fada --- /dev/null +++ b/app-c/appc/appc-metric/appc-metric-installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,40 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +#!/bin/bash + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -n -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot} diff --git a/app-c/appc/appc-metric/pom.xml b/app-c/appc/appc-metric/pom.xml new file mode 100644 index 000000000..22bf92a46 --- /dev/null +++ b/app-c/appc/appc-metric/pom.xml @@ -0,0 +1,23 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-metric</artifactId> + <packaging>pom</packaging> + <name>APPC Metric</name> + <!--<version>1.1.16-SNAPSHOT</version>--> + <description>APPC Metric</description> + + <!-- ================================================================================== --> + <!-- The modules we build --> + <!-- ================================================================================== --> + <modules> + <module>appc-metric-bundle</module> + <module>appc-metric-features</module> + <module>appc-metric-installer</module> + </modules> + +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-provider/.gitignore b/app-c/appc/appc-provider/.gitignore new file mode 100644 index 000000000..0674a61a3 --- /dev/null +++ b/app-c/appc/appc-provider/.gitignore @@ -0,0 +1,4 @@ +/.settings/ +/target/ + +**/build/
\ No newline at end of file diff --git a/app-c/appc/appc-provider/appc-provider-bundle/.gitignore b/app-c/appc/appc-provider/appc-provider-bundle/.gitignore new file mode 100644 index 000000000..5ef400af7 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/.gitignore @@ -0,0 +1,4 @@ +/target/ +/bin/ +/.settings/ +**/yang-gen-config/ diff --git a/app-c/appc/appc-provider/appc-provider-bundle/pom.xml b/app-c/appc/appc-provider/appc-provider-bundle/pom.xml new file mode 100644 index 000000000..56e90fee1 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/pom.xml @@ -0,0 +1,215 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-provider</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>appc-provider-bundle</artifactId> + <packaging>bundle</packaging> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Export-Package>org.opendaylight.controller.config.yang.config.sample_provider.impl</Export-Package> + <Export-Package>org.openecomp.appc.provider</Export-Package> + <Import-Package>!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.apache.log,*</Import-Package> + <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false,domain-model-lib,appc-command-executor-api,appc-request-handler-api</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + </configuration> + </plugin> + <plugin> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>yang-maven-plugin</artifactId> + <version>${odl.yangtools.version}</version> + <executions> + <execution> + <id>config</id> + <goals> + <goal>generate-sources</goal> + </goals> + <configuration> + <codeGenerators> + <generator> + <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass> + <outputBaseDir>${jmxGeneratorPath}</outputBaseDir> + <additionalConfiguration> + <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1> + </additionalConfiguration> + </generator> + <generator> + <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass> + <outputBaseDir>${salGeneratorPath}</outputBaseDir> + </generator> + </codeGenerators> + <inspectDependencies>true</inspectDependencies> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>maven-sal-api-gen-plugin</artifactId> + <version>${odl.yangtools.version}</version> + <type>jar</type> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>yang-jmx-generator-plugin</artifactId> + <version>${odl.yang.jmx.generator.version}</version> + </dependency> + </dependencies> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/initial/appc-provider.xml</file> + <type>xml</type> + <classifier>config</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + <pluginManagement> + <plugins> + <!--This plugin's configuration is used to store Eclipse m2e settings + only. It has no influence on the Maven build itself. --> + <plugin> + <groupId>org.eclipse.m2e</groupId> + <artifactId>lifecycle-mapping</artifactId> + <version>1.0.0</version> + <configuration> + <lifecycleMappingMetadata> + <pluginExecutions> + <pluginExecution> + <pluginExecutionFilter> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <versionRange>[1.9.1,)</versionRange> + <goals> + <goal>add-source</goal> + </goals> + </pluginExecutionFilter> + <action> + <ignore /> + </action> + </pluginExecution> + </pluginExecutions> + </lifecycleMappingMetadata> + </configuration> + </plugin> + </plugins> + </pluginManagement> + </build> + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-request-handler-api</artifactId> + <version>1.0.0</version> + <type>bundle</type> + <scope>provided</scope> + <exclusions> + <exclusion> + <groupId>org.openecomp.appc</groupId> + <artifactId>domain-model-lib</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + <classifier>jar-with-dependencies</classifier> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-provider-model</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- ADDED THIS ARTIFACT TO BE ABLE TO FIND org.openecomp.appc.domainmodel.lcm --> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>domain-model-lib</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>config-api</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-config</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-api</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-common-util</artifactId> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + </dependency> + <dependency> + <artifactId>sal-test-model</artifactId> + <groupId>org.opendaylight.controller</groupId> + <scope>test</scope> + </dependency> + <dependency> + <artifactId>sal-rest-connector</artifactId> + <groupId>org.opendaylight.netconf</groupId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-broker-impl</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-broker-impl</artifactId> + <classifier>tests</classifier> + <version>${odl.mdsal.version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <!-- TEMP CODE --> + <dependency> + <groupId>org.json</groupId> + <artifactId>json</artifactId> + </dependency> + </dependencies> +</project> diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/provider/impl/rev140523/AppcProviderModule.java b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/provider/impl/rev140523/AppcProviderModule.java new file mode 100644 index 000000000..2b55d192c --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/provider/impl/rev140523/AppcProviderModule.java @@ -0,0 +1,85 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.opendaylight.yang.gen.v1.org.openecomp.appc.provider.impl.rev140523; + +import org.openecomp.appc.provider.AppcProvider; + +/** + * This was generated code. It was generated into the source tree because it has to be manually modified. + * + */ +public class AppcProviderModule extends + org.opendaylight.yang.gen.v1.org.openecomp.appc.provider.impl.rev140523.AbstractAppcProviderModule { + + /** + * @param identifier + * @param dependencyResolver + */ + @SuppressWarnings("javadoc") + public AppcProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, + org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + super(identifier, dependencyResolver); + } + + /** + * @param identifier + * @param dependencyResolver + * @param oldModule + * @param oldInstance + */ + @SuppressWarnings("javadoc") + public AppcProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, + org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, + org.opendaylight.yang.gen.v1.org.openecomp.appc.provider.impl.rev140523.AppcProviderModule oldModule, + java.lang.AutoCloseable oldInstance) { + super(identifier, dependencyResolver, oldModule, oldInstance); + } + + /** + * @see org.opendaylight.yang.gen.v1.org.openecomp.appc.provider.impl.rev140523.AbstractAppcProviderModule#customValidation() + */ + @Override + public void customValidation() { + // add custom validation form module attributes here. + } + + /** + * This method is manually updated to actually invoke the provider implementation + * + * @see org.opendaylight.yang.gen.v1.org.openecomp.appc.provider.impl.rev140523.AbstractAppcProviderModule#createInstance() + */ + @Override + public java.lang.AutoCloseable createInstance() { + + final AppcProvider provider = + new AppcProvider(getDataBrokerDependency(), getNotificationServiceDependency(), getRpcRegistryDependency()); + return new AutoCloseable() { + + @Override + public void close() throws Exception { + provider.close(); + } + }; + + } + +} diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/provider/impl/rev140523/AppcProviderModuleFactory.java b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/provider/impl/rev140523/AppcProviderModuleFactory.java new file mode 100644 index 000000000..d91f057a7 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/provider/impl/rev140523/AppcProviderModuleFactory.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +/** + * Generated file Generated from: yang module name: appc-provider-impl yang module local name: appc-provider-impl + * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator Generated at: Tue Sep 01 + * 13:56:34 CDT 2015 Do not modify this file unless it is present under src/main directory + */ +package org.opendaylight.yang.gen.v1.org.openecomp.appc.provider.impl.rev140523; + +/** + * Generated code + * + */ +public class AppcProviderModuleFactory extends + org.opendaylight.yang.gen.v1.org.openecomp.appc.provider.impl.rev140523.AbstractAppcProviderModuleFactory { + +} diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/provider/lcm/impl/rev160108/AppcProviderLcmModule.java b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/provider/lcm/impl/rev160108/AppcProviderLcmModule.java new file mode 100644 index 000000000..ac98cb894 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/provider/lcm/impl/rev160108/AppcProviderLcmModule.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.opendaylight.yang.gen.v1.org.openecomp.appc.provider.lcm.impl.rev160108; + +import org.openecomp.appc.provider.AppcProviderLcm; + +public class AppcProviderLcmModule extends org.opendaylight.yang.gen.v1.org.openecomp.appc.provider.lcm.impl.rev160108.AbstractAppcProviderLcmModule { + public AppcProviderLcmModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + super(identifier, dependencyResolver); + } + + public AppcProviderLcmModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.org.openecomp.appc.provider.lcm.impl.rev160108.AppcProviderLcmModule oldModule, java.lang.AutoCloseable oldInstance) { + super(identifier, dependencyResolver, oldModule, oldInstance); + } + + @Override + public void customValidation() { + // add custom validation form module attributes here. + } + + @Override + public java.lang.AutoCloseable createInstance() { + final AppcProviderLcm provider = + new AppcProviderLcm(getDataBrokerDependency(), getNotificationServiceDependency(), getRpcRegistryDependency()); + return new AutoCloseable() { + + @Override + public void close() throws Exception { + provider.close(); + } + }; + } + +} diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/provider/lcm/impl/rev160108/AppcProviderLcmModuleFactory.java b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/provider/lcm/impl/rev160108/AppcProviderLcmModuleFactory.java new file mode 100644 index 000000000..5f2c358a1 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/provider/lcm/impl/rev160108/AppcProviderLcmModuleFactory.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +/* +* Generated file +* +* Generated from: yang module name: appc-provider-lcm-impl yang module local name: appc-provider-lcm-impl +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Tue Aug 16 10:40:21 IDT 2016 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.yang.gen.v1.org.openecomp.appc.provider.lcm.impl.rev160108; +public class AppcProviderLcmModuleFactory extends org.opendaylight.yang.gen.v1.org.openecomp.appc.provider.lcm.impl.rev160108.AbstractAppcProviderLcmModuleFactory { + +} diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProvider.java b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProvider.java new file mode 100644 index 000000000..9826a5619 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProvider.java @@ -0,0 +1,266 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.provider; + +import com.google.common.util.concurrent.Futures; +import org.json.JSONObject; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; +import org.opendaylight.controller.sal.binding.api.NotificationProviderService; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.*; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.common.request.header.CommonRequestHeader; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.responseattributes.StatusBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.responseheader.ResponseHeaderBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.vnf.resource.VnfResource; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.config.payload.ConfigPayload; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.openecomp.appc.Constants; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.executor.objects.LCMCommandStatus; +import org.openecomp.appc.executor.objects.Params; +import org.openecomp.appc.i18n.Msg; +import org.openecomp.appc.provider.lcm.util.RequestInputBuilder; +import org.openecomp.appc.provider.lcm.util.ValidationService; +import org.openecomp.appc.provider.topology.TopologyService; +import org.openecomp.appc.requesthandler.RequestHandler; +import org.openecomp.appc.requesthandler.objects.RequestHandlerInput; +import org.openecomp.appc.requesthandler.objects.RequestHandlerOutput; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.status.Status; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.Action; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Iterator; +import java.util.Properties; +import java.util.TimeZone; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +/* ADDED FOR FUSION SERVICE CODE */ + +@SuppressWarnings("JavaDoc") +/** + * Defines the APPC service provider. + * <p> + * The rpc definition in the YANG model is shown below. This model is used to generate code to manage the inputs and + * outputs of the RPC service. For example, the input is defined by a class named {@link ConfigurationOperationInput}, + * which is generated from the name of the RPC and the "input" definition of the RPC. This class encapsulates the + * various objects that are passed to the RPC and is used to obtain values from the input parameters. + * </p> + * <p> + * Likewise, the outputs are defined by a class named {@link ConfigurationOperationOutput}. This class encapsulates the + * defined outputs. To make construction of the outputs easier, there are also generated builder classes that are named + * for the various elements of the output they "build", such as {@link ConfigurationResponseBuilder}. + * </p> + * + * <pre> + * rpc configuration-operation { + * description "An operation to view, change, or audit the configuration of a VM"; + * input { + * uses configuration-request-header; + * uses configuration-request; + * } + * output { + * uses common-response-header; + * uses configuration-response; + * } + * } + * </pre> + * + */ +public class AppcProvider implements AutoCloseable, AppcProviderService { + + // private final Logger logger = LoggerFactory.getLogger(AppcProvider.class); + private final EELFLogger logger = EELFManager.getInstance().getLogger(AppcProviderClient.class); + + private final ExecutorService executor; + + private ListenerRegistration<DataChangeListener> dclServices; + + /** + * The ODL data store broker. Provides access to a conceptual data tree store and also provides the ability to + * subscribe for changes to data under a given branch of the tree. + */ + protected DataBroker dataBroker; + + /** + * ODL Notification Service that provides publish/subscribe capabilities for YANG modeled notifications. + */ + protected NotificationProviderService notificationService; + + /** + * Provides a registry for Remote Procedure Call (RPC) service implementations. The RPCs are defined in YANG models. + */ + protected RpcProviderRegistry rpcRegistry; + + /** + * Represents our RPC implementation registration + */ + protected BindingAwareBroker.RpcRegistration<AppcProviderService> rpcRegistration; + + /** + * The configuration + */ + private Configuration configuration = ConfigurationFactory.getConfiguration(); + + /** + * @param dataBroker2 + * @param notificationProviderService + * @param rpcProviderRegistry + */ + @SuppressWarnings({ + "javadoc", "nls" + }) + public AppcProvider(DataBroker dataBroker2, NotificationProviderService notificationProviderService, + RpcProviderRegistry rpcProviderRegistry) { + + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.COMPONENT_INITIALIZING, appName, "provider"); + + executor = Executors.newFixedThreadPool(1); + dataBroker = dataBroker2; + notificationService = notificationProviderService; + rpcRegistry = rpcProviderRegistry; + + if (rpcRegistry != null) { + rpcRegistration = rpcRegistry.addRpcImplementation(AppcProviderService.class, this); + } + + logger.info(Msg.COMPONENT_INITIALIZED, appName, "provider"); + } + + /** + * Implements the close of the service + * + * @see java.lang.AutoCloseable#close() + */ + @SuppressWarnings("nls") + @Override + public void close() throws Exception { + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.COMPONENT_TERMINATING, appName, "provider"); + executor.shutdown(); + if (rpcRegistration != null) { + rpcRegistration.close(); + } + logger.info(Msg.COMPONENT_TERMINATED, appName, "provider"); + } + + +public Future<RpcResult<ModifyConfigOutput>> modifyConfig(ModifyConfigInput input){ + CommonRequestHeader hdr = input.getCommonRequestHeader(); + ConfigPayload data = input.getConfigPayload(); + TopologyService topology = new TopologyService(this); + RpcResult<ModifyConfigOutput> result = topology.modifyConfig(hdr, data); + return Futures.immediateFuture(result); +} + /** + * Rebuilds a specific VNF + * + * @see org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.AppcProviderService#rebuild(org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.RebuildInput) + */ + @Override + public Future<RpcResult<RebuildOutput>> rebuild(RebuildInput input) { + + CommonRequestHeader hdr = input.getCommonRequestHeader(); + VnfResource vnf = input.getVnfResource(); + + TopologyService topology = new TopologyService(this); + RpcResult<RebuildOutput> result = topology.rebuild(hdr, vnf); + return Futures.immediateFuture(result); + } + + /** + * Restarts a specific VNF + * + * @see org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.AppcProviderService#restart(org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.RestartInput) + */ + @Override + public Future<RpcResult<RestartOutput>> restart(RestartInput input) { + CommonRequestHeader hdr = input.getCommonRequestHeader(); + VnfResource vnf = input.getVnfResource(); + + TopologyService topology = new TopologyService(this); + RpcResult<RestartOutput> result = topology.restart(hdr, vnf); + return Futures.immediateFuture(result); + } + + /** + * Migrates a specific VNF + * + * @see org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.AppcProviderService#migrate(org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.MigrateInput) + */ + @Override + public Future<RpcResult<MigrateOutput>> migrate(MigrateInput input) { + CommonRequestHeader hdr = input.getCommonRequestHeader(); + VnfResource vnf = input.getVnfResource(); + + TopologyService topology = new TopologyService(this); + RpcResult<MigrateOutput> result = topology.migrate(hdr, vnf); + return Futures.immediateFuture(result); + } + + /** + * Evacuates a specific VNF + * + * @see org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.AppcProviderService#evacuate(org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.EvacuateInput) + */ + @Override + public Future<RpcResult<EvacuateOutput>> evacuate(EvacuateInput input) { + CommonRequestHeader hdr = input.getCommonRequestHeader(); + VnfResource vnf = input.getVnfResource(); + + TopologyService topology = new TopologyService(this); + // RpcResult<RestartOutput> result = topology.restart(hdr, vnf); + return null;// Futures.immediateFuture(result); + } + + /** + * Evacuates a specific VNF + * + * @see org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.AppcProviderService#evacuate(org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.EvacuateInput) + */ + @Override + public Future<RpcResult<SnapshotOutput>> snapshot(SnapshotInput input) { + CommonRequestHeader hdr = input.getCommonRequestHeader(); + VnfResource vnf = input.getVnfResource(); + + TopologyService topology = new TopologyService(this); + RpcResult<SnapshotOutput> result = topology.snapshot(hdr, vnf); + return Futures.immediateFuture(result); + } + +} diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProviderClient.java b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProviderClient.java new file mode 100644 index 000000000..f294fd98f --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProviderClient.java @@ -0,0 +1,81 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.provider; + +import org.openecomp.appc.util.StringHelper; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; +import org.openecomp.sdnc.sli.SvcLogicException; +import org.openecomp.sdnc.sli.provider.SvcLogicService; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +import static com.att.eelf.configuration.Configuration.*; + +import java.util.Properties; + +public class AppcProviderClient { + + //private static final Logger LOG = LoggerFactory.getLogger(AppcProviderClient.class); + private static EELFLogger LOG = EELFManager.getInstance().getApplicationLogger(); + private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger(); + + private SvcLogicService svcLogic = null; + + public AppcProviderClient() { + BundleContext bctx = FrameworkUtil.getBundle(SvcLogicService.class).getBundleContext(); + + // Get SvcLogicService reference + ServiceReference sref = bctx.getServiceReference(SvcLogicService.NAME); + if (sref != null) { + svcLogic = (SvcLogicService) bctx.getService(sref); + + } else { + LOG.warn("Cannot find service reference for " + SvcLogicService.NAME); + + } + } + + public boolean hasGraph(String module, String rpc, String version, String mode) throws SvcLogicException { + LOG.debug(String.format("Checking for graph. %s %s %s %s", module, rpc, version, mode)); + return (svcLogic.hasGraph(module, rpc, version, mode)); + } + + public Properties execute(String module, String rpc, String version, String mode, Properties parms) + throws SvcLogicException { + + LOG.debug("Parameters passed to SLI: " + StringHelper.propertiesToString(parms)); + metricsLogger.info("Parameters passed to SLI: " + StringHelper.propertiesToString(parms)); + + Properties respProps = svcLogic.execute(module, rpc, version, mode, parms); + + LOG.debug("Parameters returned by SLI: " + StringHelper.propertiesToString(respProps)); + metricsLogger.info("Parameters returned by SLI: " + StringHelper.propertiesToString(respProps)); + + // No impact on flow. Not sure why it is here + // if ("failure".equalsIgnoreCase(respProps.getProperty("SvcLogic.status"))) { return (respProps); } + + return respProps; + } +} diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProviderLcm.java b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProviderLcm.java new file mode 100644 index 000000000..5fe174e55 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProviderLcm.java @@ -0,0 +1,828 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.provider; + +import java.text.ParseException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; +import org.opendaylight.controller.sal.binding.api.NotificationProviderService; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.Action; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.AppcProviderLcmService; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.AuditInput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.AuditOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.AuditOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.CheckLockInput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.CheckLockOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.CheckLockOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.EvacuateInput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.EvacuateOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.EvacuateOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.HealthCheckInput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.HealthCheckOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.HealthCheckOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.LiveUpgradeInput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.LiveUpgradeOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.LiveUpgradeOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.LockInput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.LockOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.LockOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.MigrateInput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.MigrateOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.MigrateOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.ModifyConfigInput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.ModifyConfigOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.ModifyConfigOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RebuildInput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RebuildOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RebuildOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RestartInput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RestartOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RestartOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RollbackInput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RollbackOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RollbackOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SnapshotInput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SnapshotOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SnapshotOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SoftwareUploadInput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SoftwareUploadOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SoftwareUploadOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.StopInput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.StopOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.StopOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SyncInput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SyncOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SyncOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.TerminateInput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.TerminateOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.TerminateOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.TestInput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.TestOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.TestOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.UnlockInput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.UnlockOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.UnlockOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.status.Status; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.status.StatusBuilder; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.openecomp.appc.Constants; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.domainmodel.lcm.ResponseContext; +import org.openecomp.appc.domainmodel.lcm.RuntimeContext; +import org.openecomp.appc.executor.objects.LCMCommandStatus; +import org.openecomp.appc.executor.objects.Params; +import org.openecomp.appc.i18n.Msg; +import org.openecomp.appc.logging.LoggingConstants; +import org.openecomp.appc.logging.LoggingUtils; +import org.openecomp.appc.provider.lcm.util.RequestInputBuilder; +import org.openecomp.appc.provider.lcm.util.ValidationService; +import org.openecomp.appc.requesthandler.RequestHandler; +import org.openecomp.appc.requesthandler.objects.RequestHandlerInput; +import org.openecomp.appc.requesthandler.objects.RequestHandlerOutput; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +import com.google.common.util.concurrent.Futures; +import org.slf4j.MDC; + + +public class AppcProviderLcm implements AutoCloseable, AppcProviderLcmService { + + private Configuration configuration = ConfigurationFactory.getConfiguration(); + private final EELFLogger logger = EELFManager.getInstance().getLogger(AppcProviderLcm.class); + + private final ExecutorService executor; + + private final String COMMON_ERROR_MESSAGE_TEMPLATE = "Error processing %s input : %s"; + + /** + * The ODL data store broker. Provides access to a conceptual data tree store and also provides the ability to + * subscribe for changes to data under a given branch of the tree. + */ + protected DataBroker dataBroker; + + /** + * ODL Notification Service that provides publish/subscribe capabilities for YANG modeled notifications. + */ + protected NotificationProviderService notificationService; + + /** + * Provides a registry for Remote Procedure Call (RPC) service implementations. The RPCs are defined in YANG models. + */ + protected RpcProviderRegistry rpcRegistry; + + /** + * Represents our RPC implementation registration + */ + protected BindingAwareBroker.RpcRegistration<AppcProviderLcmService> rpcRegistration; + + + /** + * @param dataBroker + * @param notificationProviderService + * @param rpcProviderRegistry + */ + @SuppressWarnings({ + "javadoc", "nls" + }) + public AppcProviderLcm(DataBroker dataBroker, NotificationProviderService notificationProviderService, + RpcProviderRegistry rpcProviderRegistry) { + + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.COMPONENT_INITIALIZING, appName, "provider"); + + executor = Executors.newFixedThreadPool(1); + this.dataBroker = dataBroker; + this.notificationService = notificationProviderService; + this.rpcRegistry = rpcProviderRegistry; + + if (this.rpcRegistry != null) { + rpcRegistration = rpcRegistry.addRpcImplementation(AppcProviderLcmService.class, this); + } + + logger.info(Msg.COMPONENT_INITIALIZED, appName, "provider"); + } + + /** + * Implements the close of the service + * + * @see java.lang.AutoCloseable#close() + */ + @SuppressWarnings("nls") + @Override + public void close() throws Exception { + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.COMPONENT_TERMINATING, appName, "provider"); + executor.shutdown(); + if (rpcRegistration != null) { + rpcRegistration.close(); + } + logger.info(Msg.COMPONENT_TERMINATED, appName, "provider"); + } + + + /** + * Rebuilds a specific VNF + * + * @see org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.AppcProviderLcmService#rebuild(RebuildInput) + */ + @Override + public Future<RpcResult<RebuildOutput>> rebuild(RebuildInput input) { + logger.debug("Input received : " + input.toString()); + + RebuildOutputBuilder outputBuilder = new RebuildOutputBuilder(); + String action = Action.Rebuild.toString() ; + String rpcName = Action.Rebuild.name().toLowerCase(); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<RebuildOutput> result = RpcResultBuilder.<RebuildOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + + } + + + /** + * Restarts a specific VNF + * + * @see org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.AppcProviderLcmService#restart(RestartInput) + */ + @Override + public Future<RpcResult<RestartOutput>> restart(RestartInput input) { + logger.debug("Input received : " + input.toString()); + + RestartOutputBuilder outputBuilder = new RestartOutputBuilder(); + String action = Action.Restart.toString() ; + String rpcName = Action.Restart.name().toLowerCase(); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<RestartOutput> result = RpcResultBuilder.<RestartOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + + /** + * Migrates a specific VNF + * + * @see org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.AppcProviderLcmService#migrate(MigrateInput) + */ + @Override + public Future<RpcResult<MigrateOutput>> migrate(MigrateInput input) { + logger.debug("Input received : " + input.toString()); + + MigrateOutputBuilder outputBuilder = new MigrateOutputBuilder(); + String action = Action.Migrate.toString() ; + String rpcName = Action.Migrate.name().toLowerCase(); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<MigrateOutput> result = RpcResultBuilder.<MigrateOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + + /** + * Evacuates a specific VNF + * + * @see org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.AppcProviderLcmService#evacuate(EvacuateInput) + */ + @Override + public Future<RpcResult<EvacuateOutput>> evacuate(EvacuateInput input) { + logger.debug("Input received : " + input.toString()); + + EvacuateOutputBuilder outputBuilder = new EvacuateOutputBuilder(); + String action = Action.Evacuate.toString() ; + String rpcName = Action.Evacuate.name().toLowerCase(); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<EvacuateOutput> result = RpcResultBuilder.<EvacuateOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + + /** + * Evacuates a specific VNF + * + * @see org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.AppcProviderLcmService#snapshot(SnapshotInput) + */ + @Override + public Future<RpcResult<SnapshotOutput>> snapshot(SnapshotInput input) { + logger.debug("Input received : " + input.toString()); + + SnapshotOutputBuilder outputBuilder = new SnapshotOutputBuilder(); + String action = Action.Snapshot.toString() ; + String rpcName = Action.Snapshot.name().toLowerCase(); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + String identityUrl = input.getIdentityUrl(); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).additionalContext("identity-url", identityUrl).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<SnapshotOutput> result = RpcResultBuilder.<SnapshotOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + @Override + public Future<RpcResult<RollbackOutput>> rollback(RollbackInput input) { + logger.debug("Input received : " + input.toString()); + + RollbackOutputBuilder outputBuilder = new RollbackOutputBuilder(); + String rpcName = Action.Rollback.toString() ; + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), rpcName); + String identityUrl = input.getIdentityUrl(); + String snapshotId = input.getSnapshotId(); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).additionalContext("identity-url", identityUrl).additionalContext("snapshot-id", snapshotId).action(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, rpcName, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<RollbackOutput> result = RpcResultBuilder.<RollbackOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + @Override + public Future<RpcResult<SyncOutput>> sync(SyncInput input) { + logger.debug("Input received : " + input.toString()); + SyncOutputBuilder outputBuilder = new SyncOutputBuilder(); + String action = Action.Sync.toString() ; + String rpcName = Action.Sync.name().toLowerCase(); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<SyncOutput> result = RpcResultBuilder.<SyncOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + private Status buildParsingErrorStatus(ParseException e){ + LCMCommandStatus requestParsingFailure = LCMCommandStatus.REQUEST_PARSING_FAILED; + String errorMessage = e.getMessage() != null ? e.getMessage() : e.toString(); + Params params = new Params().addParam("errorMsg", errorMessage); + return buildStatus(requestParsingFailure.getResponseCode(), requestParsingFailure.getFormattedMessage(params)); + } + + private Status buildStatus(Integer code,String message){ + StatusBuilder status = new StatusBuilder(); + status.setCode(code); + status.setMessage(message); + return status.build(); + } + + private Status buildStatusWithDispatcherOutput(RequestHandlerOutput requestHandlerOutput){ + Integer statusCode = requestHandlerOutput.getResponseContext().getStatus().getCode(); + String statusMessage = requestHandlerOutput.getResponseContext().getStatus().getMessage(); + return buildStatus(statusCode, statusMessage); + } + + private RequestHandlerOutput executeRequest(RequestHandlerInput request){ + + RequestHandler handler = getRequestHandler(); + RequestHandlerOutput requestHandlerOutput=null; + try { + requestHandlerOutput = handler.handleRequest(request); + } catch (Exception e) { + + final String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + final String reason = EELFResourceManager.format(Msg.EXCEPTION_CALLING_DG, e, appName, e.getClass().getSimpleName(), "", e.getMessage()); + + logger.info("UNEXPECTED FAILURE while executing " + request.getRequestContext().getAction().name()); + + + final ResponseContext responseContext = new ResponseContext(); + requestHandlerOutput = new RequestHandlerOutput(); + requestHandlerOutput.setResponseContext(responseContext); + responseContext.setCommonHeader(request.getRequestContext().getCommonHeader()); + final org.openecomp.appc.domainmodel.lcm.Status status = new org.openecomp.appc.domainmodel.lcm.Status(); + + responseContext.setStatus(status); + + String errorMessage = e.getMessage() != null ? e.getMessage() : e.toString(); + Params params = new Params().addParam("errorMsg", errorMessage); + status.setCode(LCMCommandStatus.UNEXPECTED_ERROR.getResponseCode()); + status.setMessage(LCMCommandStatus.UNEXPECTED_ERROR.getFormattedMessage(params)); + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + reason, + this.getClass().getName()); + + + } + return requestHandlerOutput; + } + + private RequestHandler getRequestHandler(){ + RequestHandler handler ; + final BundleContext context = FrameworkUtil.getBundle(RequestHandler.class).getBundleContext(); + final ServiceReference reference = context.getServiceReference(RequestHandler.class.getName()); + + if (reference != null) { + handler = (RequestHandler) context.getService(reference); + } else { + logger.error("Cannot find service reference for " + RequestHandler.class.getName()); + throw new RuntimeException(); + } + return handler ; + } + + + @Override + public Future<RpcResult<TerminateOutput>> terminate(TerminateInput input) { + logger.debug("Input received : " + input.toString()); + TerminateOutputBuilder outputBuilder = new TerminateOutputBuilder(); + String action = Action.Terminate.toString() ; + String rpcName = Action.Terminate.name().toLowerCase(); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<TerminateOutput> result = RpcResultBuilder.<TerminateOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + + + @Override + public Future<RpcResult<ModifyConfigOutput>> modifyConfig(ModifyConfigInput input) { + logger.debug("Input received : " + input.toString()); + ModifyConfigOutputBuilder outputBuilder = new ModifyConfigOutputBuilder(); + String action = Action.ModifyConfig.toString() ; + String rpcName = "modify-config"; + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<ModifyConfigOutput> result = RpcResultBuilder.<ModifyConfigOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + @Override + public Future<RpcResult<TestOutput>> test(TestInput input) { + logger.debug("Input received : " + input.toString()); + TestOutputBuilder outputBuilder = new TestOutputBuilder(); + String action = Action.Test.toString() ; + String rpcName = Action.Test.name().toLowerCase(); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<TestOutput> result = RpcResultBuilder.<TestOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + + @Override + public Future<RpcResult<StopOutput>> stop(StopInput input) { + logger.debug("Input received : " + input.toString()); + StopOutputBuilder outputBuilder = new StopOutputBuilder(); + String action = Action.Stop.toString() ; + String rpcName = Action.Stop.name().toLowerCase(); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<StopOutput> result = RpcResultBuilder.<StopOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + @Override + public Future<RpcResult<AuditOutput>> audit(AuditInput input) { + logger.debug("Input received : " + input.toString()); + AuditOutputBuilder outputBuilder = new AuditOutputBuilder(); + String action = Action.Audit.toString(); + String rpcName = Action.Audit.name().toLowerCase(); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<AuditOutput> result = RpcResultBuilder.<AuditOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + @Override + public Future<RpcResult<SoftwareUploadOutput>> softwareUpload(SoftwareUploadInput input) { + logger.debug("Input received : " + input.toString()); + SoftwareUploadOutputBuilder outputBuilder = new SoftwareUploadOutputBuilder(); + String action = Action.SoftwareUpload.toString() ; + String rpcName = convertActionNameToUrl(action); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder(). + requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<SoftwareUploadOutput> result = RpcResultBuilder.<SoftwareUploadOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + @Override + public Future<RpcResult<HealthCheckOutput>> healthCheck(HealthCheckInput input) { + logger.debug("Input received : " + input.toString()); + HealthCheckOutputBuilder outputBuilder = new HealthCheckOutputBuilder(); + String action = Action.HealthCheck.toString() ; + String rpcName = convertActionNameToUrl(action); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<HealthCheckOutput> result = RpcResultBuilder.<HealthCheckOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + @Override + public Future<RpcResult<LiveUpgradeOutput>> liveUpgrade(LiveUpgradeInput input) { + logger.debug("Input received : " + input.toString()); + LiveUpgradeOutputBuilder outputBuilder = new LiveUpgradeOutputBuilder(); + String action = Action.LiveUpgrade.toString() ; + String rpcName = convertActionNameToUrl(action); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<LiveUpgradeOutput> result = RpcResultBuilder.<LiveUpgradeOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + + @Override + public Future<RpcResult<LockOutput>> lock(LockInput input) { + logger.debug("Input received : " + input.toString()); + LockOutputBuilder outputBuilder = new LockOutputBuilder(); + String action = Action.Lock.toString() ; + String rpcName = Action.Lock.name().toLowerCase(); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<LockOutput> result = RpcResultBuilder.<LockOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + + @Override + public Future<RpcResult<UnlockOutput>> unlock(UnlockInput input) { + logger.debug("Input received : " + input.toString()); + UnlockOutputBuilder outputBuilder = new UnlockOutputBuilder(); + String action = Action.Unlock.toString() ; + String rpcName = Action.Unlock.name().toLowerCase(); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<UnlockOutput> result = RpcResultBuilder.<UnlockOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + @Override + public Future<RpcResult<CheckLockOutput>> checkLock(CheckLockInput input) { + logger.debug("Input received : " + input.toString()); + CheckLockOutputBuilder outputBuilder = new CheckLockOutputBuilder(); + String action = Action.CheckLock.toString() ; + String rpcName = Action.CheckLock.name().toLowerCase(); + RequestHandlerOutput requestHandlerOutput=null; + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).action(action).rpcName(rpcName).build(); + requestHandlerOutput=executeRequest(request); + + status = buildStatusWithDispatcherOutput(requestHandlerOutput); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + if(requestHandlerOutput.getResponseContext().getStatus().getCode() == 400) { + outputBuilder.setLocked(CheckLockOutput.Locked.valueOf(requestHandlerOutput.getResponseContext().getAdditionalContext().get("locked").toUpperCase())); + } + RpcResult<CheckLockOutput> result = RpcResultBuilder.<CheckLockOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + private String convertActionNameToUrl(String action) { + String regex = "([a-z])([A-Z]+)"; + String replacement = "$1-$2"; + return action.replaceAll(regex, replacement) + .toLowerCase(); + } + + +} diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/ResponseHeaderBuilder.java b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/ResponseHeaderBuilder.java new file mode 100644 index 000000000..ea03074bd --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/ResponseHeaderBuilder.java @@ -0,0 +1,88 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.provider; + +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.TIMESTAMP; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.common.response.header.CommonResponseHeader; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.common.response.header.CommonResponseHeaderBuilder; +import org.openecomp.appc.util.Time; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; + + +/** + * Builds the responses from the APP-C services according to the YANG domainmodel + * + * @since Nov 16, 2015 + * @version $Id$ + */ +public class ResponseHeaderBuilder { + + /** + * The date/time formatter to format timestamps. + */ + @SuppressWarnings("nls") + public static final DateFormat FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS"); + public static final DateFormat ZULU_FORMATTER = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SS'Z'"); + + /** + * Private default constructor prevents instantiation + */ + private ResponseHeaderBuilder() { + } + + /** + * This method builds the common response header and returns it to the caller for integration into the response + * + * @param success + * True or false indicating the outcome of the operation. True indicates that the operation was + * successful, false indicates it failed. + * @param requestId + * The original request id for the service + * @param reason + * The reason for the failure if the success flag is false. If success is true, the reason is not used. + * @param duration + * The duration of the request processing + * @return The common response header to be returned to the caller. + */ + @SuppressWarnings("nls") + public static CommonResponseHeader buildHeader(Boolean success, String requestId, String reason, long duration) { + CommonResponseHeaderBuilder builder = new CommonResponseHeaderBuilder(); + + TIMESTAMP timestamp = new TIMESTAMP(FORMATTER.format(Time.utcDate())); + builder.setServiceRequestId(requestId); + builder.setCompleted(timestamp); + builder.setDuration(duration); + builder.setSuccess(success); + + if (success.equals(Boolean.TRUE)) { + builder.setReason("Success"); + } else { + builder.setReason(reason); + } + + return builder.build(); + } + + +} diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/lcm/util/LCMConstants.java b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/lcm/util/LCMConstants.java new file mode 100644 index 000000000..bcb55bc75 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/lcm/util/LCMConstants.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.provider.lcm.util; + +public final class LCMConstants { + private LCMConstants() { + } + + public static final String CODE = "Status"; + public static final String VALUE = "Value"; + //flags + public static final String FORCE = "FORCE"; + public static final String MODE = "MODE"; + public static final String TTL = "TTL"; + +} diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/lcm/util/RequestInputBuilder.java b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/lcm/util/RequestInputBuilder.java new file mode 100644 index 000000000..7af5f073d --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/lcm/util/RequestInputBuilder.java @@ -0,0 +1,141 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.provider.lcm.util; + +import java.text.ParseException; +import java.text.SimpleDateFormat; + +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.Payload; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.action.identifiers.ActionIdentifiers; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.CommonHeader; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags; +import org.openecomp.appc.domainmodel.lcm.RequestContext; +import org.openecomp.appc.domainmodel.lcm.VNFOperation; +import org.openecomp.appc.requesthandler.objects.RequestHandlerInput; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + + + +public class RequestInputBuilder { + private static EELFLogger logger = EELFManager.getInstance().getApplicationLogger(); + + private static final String FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; + + private RequestContext requestContext; + private String rpcName; + + public RequestInputBuilder() { + } + + + public RequestInputBuilder requestContext() { + this.requestContext = new RequestContext(); + return this; + } + + public RequestInputBuilder action(String action) { + this.requestContext.setAction(VNFOperation.findByString(action)); + return this; + } + + + public RequestInputBuilder additionalContext(String key, String value) { + this.requestContext.addKeyValueToAdditionalContext(key, value); + return this; + } + + public RequestInputBuilder payload(Payload payload) { + if (payload != null) { + this.requestContext.setPayload(payload.getValue()); + } + return this; + } + + public RequestHandlerInput build (){ + RequestHandlerInput request = new RequestHandlerInput(); + request.setRequestContext(this.requestContext); + request.setRpcName(rpcName); + return request; + } + + public RequestInputBuilder rpcName(String rpcName) { + this.rpcName = rpcName; + return this; + } + + public RequestInputBuilder commonHeader(CommonHeader commonHeader) throws ParseException { + org.openecomp.appc.domainmodel.lcm.CommonHeader header = new org.openecomp.appc.domainmodel.lcm.CommonHeader(); + this.requestContext.setCommonHeader(header); + + try { + if(null != commonHeader.getTimestamp()) { + SimpleDateFormat format = new SimpleDateFormat(FORMAT); + format.setLenient(false); + header.setTimestamp(format.parse(commonHeader.getTimestamp().getValue())); + }else{ + throw new ParseException("Missing mandatory parameter : timestamp " , 0); + } + } catch (ParseException e) { + logger.error(String.format("DATE format is incorrect: %s", e.getMessage())); + throw e; + } + header.setApiVer(commonHeader.getApiVer()); + header.setRequestId(commonHeader.getRequestId()); + header.setOriginatorId(commonHeader.getOriginatorId()); + header.setSubRequestId(commonHeader.getSubRequestId()); + + Flags inFlags = commonHeader.getFlags(); + org.openecomp.appc.domainmodel.lcm.Flags flags = new org.openecomp.appc.domainmodel.lcm.Flags(); + if (inFlags != null) { + + if(null != inFlags.getForce()) { + flags.setForce(Boolean.parseBoolean(inFlags.getForce().toString().toLowerCase())); + } + if(null!=inFlags.getMode()) { + flags.setMode(inFlags.getMode().name()); + } + if(null!= inFlags.getTtl()) { + flags.setTtl(inFlags.getTtl()); + } + + } + this.requestContext.getCommonHeader().setFlags(flags); + return this; + } + + public RequestInputBuilder actionIdentifiers(ActionIdentifiers actionIdentifiers) throws ParseException { + if(null!= actionIdentifiers) { + org.openecomp.appc.domainmodel.lcm.ActionIdentifiers actionIds = new org.openecomp.appc.domainmodel.lcm.ActionIdentifiers(); + actionIds.setServiceInstanceId(actionIdentifiers.getServiceInstanceId()); + actionIds.setVnfcName(actionIdentifiers.getVnfcName()); + actionIds.setvServerId(actionIdentifiers.getVserverId()); + actionIds.setVnfId(actionIdentifiers.getVnfId()); + this.requestContext.setActionIdentifiers(actionIds); + return this; + }else{ + throw new ParseException("Missing action identifier" , 0); + } + } + + +} diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/lcm/util/ValidationService.java b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/lcm/util/ValidationService.java new file mode 100644 index 000000000..fe2fdc142 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/lcm/util/ValidationService.java @@ -0,0 +1,91 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.provider.lcm.util; + +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.Action; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.CommonHeader; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.status.Status; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.status.StatusBuilder; +import org.openecomp.appc.Constants; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.executor.objects.LCMCommandStatus; +import org.openecomp.appc.executor.objects.Params; +import org.openecomp.appc.i18n.Msg; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; + +import javax.swing.*; + + + +public class ValidationService { + + private static class ValidationServiceHolder { + private static final ValidationService INSTANCE = new ValidationService(); + } + + private final EELFLogger logger = EELFManager.getInstance().getLogger(ValidationService.class); + + private Configuration configuration = ConfigurationFactory.getConfiguration(); + + public static ValidationService getInstance(){ + return ValidationServiceHolder.INSTANCE; + } + + public Status validateInput (CommonHeader commonHeader, Action action , String rpcName) { + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + String reason ; + StringBuilder paramName = new StringBuilder(""); + if (!isEmpty(commonHeader) && !isEmpty(commonHeader.getApiVer())&& !isEmpty(commonHeader.getTimestamp()) && !isEmpty(commonHeader.getRequestId()) && !isEmpty(action) && !isEmpty(commonHeader.getOriginatorId())){ + if(!action.toString().equalsIgnoreCase(rpcName)) logger.warn("action in input request '" + action.toString() + "' is different from endpoint '" + rpcName + "'"); + return null; + } else{ + if(isEmpty(commonHeader)){ + paramName.append("common-header"); + }else{ + if (isEmpty(commonHeader.getApiVer())) paramName.append("api-ver"); + if (isEmpty(commonHeader.getTimestamp())) paramName.append(isEmpty(paramName) ? "timestamp" : " , timestamp" ); + if (isEmpty(commonHeader.getRequestId())) paramName.append(isEmpty(paramName) ? "request-id" : " , request-id" ); + if (isEmpty(commonHeader.getOriginatorId())) paramName.append(isEmpty(paramName) ? "originator-id" : " , originator-id" ); + } + if (isEmpty(action)) paramName.append(isEmpty(paramName) ? "action" : " , action" ); + } + + + + reason = EELFResourceManager.format(Msg.NULL_OR_INVALID_ARGUMENT, appName, rpcName, paramName.toString() , ""); + logger.info("Mandatory parameter/s" + paramName.toString() + " is/are missing"); + logger.error(reason); + LCMCommandStatus lcmCommandStatus = LCMCommandStatus.MISSING_MANDATORY_PARAMETER; + Params params = new Params().addParam("paramName", paramName.toString()); + StatusBuilder status = new StatusBuilder(); + status.setCode(lcmCommandStatus.getResponseCode()); + status.setMessage(lcmCommandStatus.getFormattedMessage(params)); + return status.build(); + } + + private boolean isEmpty (Object object){ + return (null == object || "".equalsIgnoreCase(object.toString())); + } +} diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/topology/TopologyService.java b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/topology/TopologyService.java new file mode 100644 index 000000000..ea88982c1 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/topology/TopologyService.java @@ -0,0 +1,718 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc.provider.topology; + +import static com.att.eelf.configuration.Configuration.MDC_ALERT_SEVERITY; +import static com.att.eelf.configuration.Configuration.MDC_INSTANCE_UUID; +import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID; +import static com.att.eelf.configuration.Configuration.MDC_REMOTE_HOST; +import static com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN; +import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS; +import static com.att.eelf.configuration.Configuration.MDC_SERVICE_INSTANCE_ID; +import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME; + +import java.net.InetAddress; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Properties; +import java.util.TimeZone; + +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.MigrateOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.ModifyConfigOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.ModifyConfigOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.MigrateOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.RebuildOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.RebuildOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.RestartOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.RestartOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.SnapshotOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.SnapshotOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.UUID; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.common.request.header.CommonRequestHeader; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.vnf.resource.VnfResource; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.config.payload.ConfigPayload; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.openecomp.appc.Constants; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.i18n.Msg; +import org.openecomp.appc.provider.AppcProvider; +import org.openecomp.appc.provider.AppcProviderClient; +import org.openecomp.appc.provider.ResponseHeaderBuilder; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; +import org.slf4j.MDC; + +/** + * This class is used to implement the topology services API and invoke the appropriate directed graphs based on the + * service being requested. + * + */ +public class TopologyService { + + /** + * The loggers we are using + */ + // private static EELFLogger logger = LoggerFactory.getLogger(TopologyService.class); + private static EELFLogger logger = EELFManager.getInstance().getApplicationLogger(); + private static EELFLogger securityLogger = EELFManager.getInstance().getSecurityLogger(); + private static EELFLogger auditLogger = EELFManager.getInstance().getAuditLogger(); + private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger(); + private static EELFLogger performanceLogger = EELFManager.getInstance().getPerformanceLogger(); + + /** + * The provider we are servicing + */ + private AppcProvider provider; + + /** + * The reason associated with the last DG call + */ + private String reason; + + /** + * The APPC configuration properties + */ + private Configuration configuration = ConfigurationFactory.getConfiguration(); + + /** + * Create the topology services implementation for the specific appc provider (api) implementation + * + * @param provider + * The provider we are servicing + */ + public TopologyService(AppcProvider provider) { + this.provider = provider; + } + + // /** + // * Processes the topology request + // * + // * @param input + // * The request to be processed + // * @return The result of processing + // */ + // public RpcResult<TopologyOperationOutput> process(TopologyOperationInput input) { + // RpcResult<TopologyOperationOutput> response; + // + // String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + // logger.info(String.format("%s:topology operations called...", appName)); + // + // /* + // * Properties used to pass information to the DG + // */ + // Properties properties = new Properties(); + // + // if (input == null || input.getTopologyRequest().getVmId() == null) { + // String msg = + // String.format("%s: topology operation failed, invalid input. Null or empty argument '%s'", appName, + // "vm_id"); + // logger.debug(msg); + // response = generateTopologyOperationResponse(Boolean.FALSE, "UNKNOWN", msg, "UNDEFINED"); + // } else { + // // CommonRequestHeader crh = input.getCommonRequestHeader(); + // TopologyHeader hdr = input.getTopologyHeader(); + // TopologyRequest req = input.getTopologyRequest(); + // + // // String requestId = crh.getServiceRequestId(); + // String requestId = hdr.getSvcRequestId(); + // properties.put(Constants.CONTEXT_REQID, requestId); + // + // String infomsg = String.format("Topology request '%s' (%s) received.", requestId, hdr.getSvcAction()); + // + // // switch (req.getSvcAction()) { + // switch (hdr.getSvcAction()) { + // case Restart: + // properties.put(Constants.CONTEXT_SERVICE, Constants.SERVICE_RESTART); + // response = restart(input, properties); + // logger.info(infomsg); + // break; + // + // case Rebuild: + // properties.put(Constants.CONTEXT_SERVICE, Constants.SERVICE_REBUILD); + // response = rebuild(input, properties); + // logger.info(infomsg); + // break; + // + // default: + // String msg = String.format("Invalid request type [%s] for request id [%s]", req, requestId); + // response = generateTopologyOperationResponse(Boolean.FALSE, requestId, msg, "N/A"); + // } + // } + // + // return response; + // } + + /** + * Restart a VM + * + * @param hdr + * The common request header + * @param vnf + * The identification of the VNF resource to be operated upon + * @return The rpc result of the restart operation + */ + public RpcResult<ModifyConfigOutput> modifyConfig(CommonRequestHeader hdr, ConfigPayload data) { + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX"); + df.setTimeZone(tz); + // String startTimeStr = String.valueOf(startTime); + String startTimeStr = df.format(new Date()); + String requestId = hdr.getServiceRequestId(); + + //MDC.clear(); + MDC.put(MDC_REMOTE_HOST, ""); + MDC.put(MDC_KEY_REQUEST_ID, requestId); + MDC.put(MDC_SERVICE_NAME, "App-C Provider:Restart"); + MDC.put(MDC_SERVICE_INSTANCE_ID, ""); + try { + MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName()); + MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress()); + } catch (Exception e) { + e.printStackTrace(); + } + MDC.put(MDC_INSTANCE_UUID, java.util.UUID.randomUUID().toString()); + MDC.put(MDC_ALERT_SEVERITY, "0"); + MDC.put("startTime", Long.toString(startTime)); + MDC.put("target", "appc"); + logger.info(String.format("Starting RESTART for request with id [%s]", requestId)); + metricsLogger.info(String.format("Metrics Logger: App-C Restart initiated. Start Time: [%s]. Request ID: [%s]", + startTime, requestId)); + + /* + * Copy any needed inputs or other values into the properties to be passed to the DG model + */ + //UUID vmId = vnf.getVmId(); + Properties properties = new Properties(); + properties.put(Constants.CONTEXT_ACTION, "modifyConfig"); + properties.put(Constants.CONTEXT_REQID, requestId); + //properties.put(Constants.CONTEXT_VMID, vmId.getValue()); + String url = configuration.getProperty("appc.provider.vfodl.url"); + try{ + if(url.contains("NODE_NAME")){ + url = url.replace("NODE_NAME", data.getConfigUrl()); + } + }catch(Exception e){ + url = configuration.getProperty("appc.provider.vfodl.url"); + } + logger.trace("Final URL to VF ODL: "+url); + properties.put("org.openecomp.appc.configURL", url); + properties.put("org.openecomp.appc.configJson", data.getConfigJson()); + + //UUID identityUrl = vnf.getIdentityUrl(); + //if (identityUrl != null) { + // properties.put(Constants.CONTEXT_IDENTITY_URL, identityUrl.getValue()); + //} + /* + * Attempt to call the DG with the appropriate properties + */ + boolean success = callGraph(properties); + + + MDC.put("target", "appc"); + String statusStr = success ? "SUCCESS" : "FAILURE"; + String infomsg = + String.format("APPC0119I ModifyConfig '%s' finished with status %s. Reason: %s", requestId, statusStr, reason); + logger.info(infomsg); + + ModifyConfigOutputBuilder rob = new ModifyConfigOutputBuilder(); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + MDC.put("endTime", endTimeStr); + MDC.put("duration", durationStr); + rob.setCommonResponseHeader(ResponseHeaderBuilder.buildHeader(success, requestId, reason, duration)); + //rob.setVmId(new UUID(vmId)); + + auditLogger.info(String.format( + "Audit Logger: APPC0119I Restart '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s", + requestId, statusStr, startTime, endTime, duration, requestId, reason)); + metricsLogger.info(String.format( + "Metrics Logger: APPC0119I Restart '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s", + requestId, statusStr, startTime, endTime, duration, requestId, reason)); + + // Status must be set to true to indicate that our return is expected + RpcResult<ModifyConfigOutput> rpcResult = + RpcResultBuilder.<ModifyConfigOutput> status(true).withResult(rob.build()).build(); + return rpcResult; + + } + + + + + /** + * Restart a VM + * + * @param hdr + * The common request header + * @param vnf + * The identification of the VNF resource to be operated upon + * @return The rpc result of the restart operation + */ + public RpcResult<MigrateOutput> migrate(CommonRequestHeader hdr, VnfResource vnf) { + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX"); + df.setTimeZone(tz); + // String startTimeStr = String.valueOf(startTime); + String startTimeStr = df.format(new Date()); + String requestId = hdr.getServiceRequestId(); + + //MDC.clear(); + MDC.put(MDC_REMOTE_HOST, ""); + MDC.put(MDC_KEY_REQUEST_ID, requestId); + MDC.put(MDC_SERVICE_NAME, "App-C Provider:Migrate"); + MDC.put(MDC_SERVICE_INSTANCE_ID, ""); + try { + MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName()); + MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress()); + } catch (Exception e) { + e.printStackTrace(); + } + MDC.put(MDC_INSTANCE_UUID, java.util.UUID.randomUUID().toString()); + MDC.put(MDC_ALERT_SEVERITY, "0"); + MDC.put("startTime", startTimeStr); + MDC.put("target", "appc"); + logger.info(String.format("Starting ANY for request with id [%s]", requestId)); + metricsLogger.info(String.format("Metrics Logger: App-C Restart initiated. Start Time: [%s]. Request ID: [%s]", + startTime, requestId)); + + /* + * Copy any needed inputs or other values into the properties to be passed to the DG model + */ + UUID vmId = vnf.getVmId(); + Properties properties = new Properties(); + properties.put(Constants.CONTEXT_ACTION, "migrate"); + properties.put(Constants.CONTEXT_REQID, requestId); + properties.put(Constants.CONTEXT_VMID, vmId.getValue()); + + UUID identityUrl = vnf.getIdentityUrl(); + if (identityUrl != null) { + properties.put(Constants.CONTEXT_IDENTITY_URL, identityUrl.getValue()); + } + + /* + * Attempt to call the DG with the appropriate properties + */ + boolean success = callGraph(properties); + + /* + * Generate the appropriate response + */ + MDC.put("target", "appc"); + String statusStr = success ? "SUCCESS" : "FAILURE"; + String infomsg = + String.format("APPC0118I Migrate '%s' finished with status %s. Reason: %s", requestId, statusStr, reason); + logger.info(infomsg); + + MigrateOutputBuilder mob = new MigrateOutputBuilder(); + + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + MDC.put("endTime", endTimeStr); + MDC.put("duration", durationStr); + mob.setCommonResponseHeader(ResponseHeaderBuilder.buildHeader(success, requestId, reason, duration)); + mob.setVmId(new UUID(vmId)); + + auditLogger.info(String.format( + "Audit Logger: APPC0118I Migrate '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s", + requestId, statusStr, startTime, endTime, duration, requestId, reason)); + metricsLogger.info(String.format( + "Metrics Logger: APPC0118I Migrate '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s", + requestId, statusStr, startTime, endTime, duration, requestId, reason)); + + // Status must be set to true to indicate that our return is expected + RpcResult<MigrateOutput> rpcResult = + RpcResultBuilder.<MigrateOutput> status(true).withResult(mob.build()).build(); + return rpcResult; + } + + /** + * Restart a VM + * + * @param hdr + * The common request header + * @param vnf + * The identification of the VNF resource to be operated upon + * @return The rpc result of the restart operation + */ + public RpcResult<RestartOutput> restart(CommonRequestHeader hdr, VnfResource vnf) { + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX"); + df.setTimeZone(tz); + // String startTimeStr = String.valueOf(startTime); + String startTimeStr = df.format(new Date()); + String requestId = hdr.getServiceRequestId(); + + //MDC.clear(); + MDC.put(MDC_REMOTE_HOST, ""); + MDC.put(MDC_KEY_REQUEST_ID, requestId); + MDC.put(MDC_SERVICE_NAME, "App-C Provider:Restart"); + MDC.put(MDC_SERVICE_INSTANCE_ID, ""); + try { + MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName()); + MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress()); + } catch (Exception e) { + e.printStackTrace(); + } + MDC.put(MDC_INSTANCE_UUID, java.util.UUID.randomUUID().toString()); + MDC.put(MDC_ALERT_SEVERITY, "0"); + MDC.put("startTime", Long.toString(startTime)); + MDC.put("target", "appc"); + logger.info(String.format("Starting RESTART for request with id [%s]", requestId)); + metricsLogger.info(String.format("Metrics Logger: App-C Restart initiated. Start Time: [%s]. Request ID: [%s]", + startTime, requestId)); + + /* + * Copy any needed inputs or other values into the properties to be passed to the DG model + */ + UUID vmId = vnf.getVmId(); + Properties properties = new Properties(); + properties.put(Constants.CONTEXT_ACTION, "restart"); + properties.put(Constants.CONTEXT_REQID, requestId); + properties.put(Constants.CONTEXT_VMID, vmId.getValue()); + + UUID identityUrl = vnf.getIdentityUrl(); + if (identityUrl != null) { + properties.put(Constants.CONTEXT_IDENTITY_URL, identityUrl.getValue()); + } + /* + * Attempt to call the DG with the appropriate properties + */ + boolean success = callGraph(properties); + + /* + * Generate the appropriate response + */ + MDC.put("target", "appc"); + String statusStr = success ? "SUCCESS" : "FAILURE"; + String infomsg = + String.format("APPC0119I Restart '%s' finished with status %s. Reason: %s", requestId, statusStr, reason); + logger.info(infomsg); + + RestartOutputBuilder rob = new RestartOutputBuilder(); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + MDC.put("endTime", endTimeStr); + MDC.put("duration", durationStr); + rob.setCommonResponseHeader(ResponseHeaderBuilder.buildHeader(success, requestId, reason, duration)); + rob.setVmId(new UUID(vmId)); + + auditLogger.info(String.format( + "Audit Logger: APPC0119I Restart '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s", + requestId, statusStr, startTime, endTime, duration, requestId, reason)); + metricsLogger.info(String.format( + "Metrics Logger: APPC0119I Restart '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s", + requestId, statusStr, startTime, endTime, duration, requestId, reason)); + + // Status must be set to true to indicate that our return is expected + RpcResult<RestartOutput> rpcResult = + RpcResultBuilder.<RestartOutput> status(true).withResult(rob.build()).build(); + return rpcResult; + } + + /** + * Rebuild a VM + * + * @param hdr + * The common request header + * @param vnf + * The identification of the VNF resource to be operated upon + * @return The rpc result of the rebuild operation + */ + public RpcResult<RebuildOutput> rebuild(CommonRequestHeader hdr, VnfResource vnf) { + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX"); + df.setTimeZone(tz); + // String startTimeStr = String.valueOf(startTime); + String startTimeStr = df.format(new Date()); + String requestId = hdr.getServiceRequestId(); + + //MDC.clear(); + MDC.put(MDC_REMOTE_HOST, ""); + MDC.put(MDC_KEY_REQUEST_ID, requestId); + MDC.put(MDC_SERVICE_NAME, "App-C Provider:Rebuild"); + MDC.put(MDC_SERVICE_INSTANCE_ID, ""); + try { + MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName()); + MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress()); + } catch (Exception e) { + e.printStackTrace(); + } + MDC.put(MDC_INSTANCE_UUID, java.util.UUID.randomUUID().toString()); + MDC.put(MDC_ALERT_SEVERITY, "0"); + MDC.put("startTime", startTimeStr); + MDC.put("target", "appc"); + logger.info(String.format("Starting REBUILD for request with id [%s]", requestId)); + metricsLogger.info(String.format("Metrics Logger: App-C Restart initiated. Start Time: [%s]. Request ID: [%s]", + startTime, requestId)); + + /* + * Copy any needed inputs or other values into the properties to be passed to the DG model + */ + UUID vmId = vnf.getVmId(); + Properties properties = new Properties(); + properties.put(Constants.CONTEXT_ACTION, "rebuild"); + properties.put(Constants.CONTEXT_REQID, requestId); + properties.put(Constants.CONTEXT_VMID, vmId.getValue()); + + UUID identityUrl = vnf.getIdentityUrl(); + if (identityUrl != null) { + properties.put(Constants.CONTEXT_IDENTITY_URL, identityUrl.getValue()); + } + + /* + * Attempt to call the DG with the appropriate properties + */ + boolean success = callGraph(properties); + + /* + * Generate the appropriate response + */ + MDC.put("target", "appc"); + String statusStr = success ? "SUCCESS" : "FAILURE"; + String infomsg = + String.format("APPC0120I Rebuild '%s' finished with status %s. Reason: %s", requestId, statusStr, reason); + logger.info(infomsg); + + RebuildOutputBuilder rob = new RebuildOutputBuilder(); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + MDC.put("endTime", endTimeStr); + MDC.put("duration", durationStr); + rob.setCommonResponseHeader(ResponseHeaderBuilder.buildHeader(success, requestId, reason, duration)); + rob.setOriginalVmId(new UUID(vmId)); + rob.setNewVmId(new UUID(vmId)); + + auditLogger.info(String.format( + "Audit Logger: APPC0120I Rebuild '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s", + requestId, statusStr, startTime, endTime, duration, requestId, reason)); + metricsLogger.info(String.format( + "Metrics Logger: APPC0120I Rebuild '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s", + requestId, statusStr, startTime, endTime, duration, requestId, reason)); + + // Status must be set to true to indicate that our return is expected + RpcResult<RebuildOutput> rpcResult = + RpcResultBuilder.<RebuildOutput> status(true).withResult(rob.build()).build(); + return rpcResult; + } + + /** + * Snapshot a VM + * + * @param hdr + * The common request header + * @param vnf + * The identification of the VNF resource to be operated upon + * @return The rpc result of the restart operation + */ + public RpcResult<SnapshotOutput> snapshot(CommonRequestHeader hdr, VnfResource vnf) { + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX"); + df.setTimeZone(tz); + // String startTimeStr = String.valueOf(startTime); + String startTimeStr = df.format(new Date()); + String requestId = hdr.getServiceRequestId(); + + //MDC.clear(); + MDC.put(MDC_REMOTE_HOST, ""); + MDC.put(MDC_KEY_REQUEST_ID, requestId); + MDC.put(MDC_SERVICE_NAME, "App-C Provider:Snapshot"); + MDC.put(MDC_SERVICE_INSTANCE_ID, ""); + try { + MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName()); + MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress()); + } catch (Exception e) { + e.printStackTrace(); + } + MDC.put(MDC_INSTANCE_UUID, java.util.UUID.randomUUID().toString()); + MDC.put(MDC_ALERT_SEVERITY, "0"); + MDC.put("startTime", Long.toString(startTime)); + MDC.put("target", "appc"); + logger.info(String.format("Starting SNAPSHOT for request with id [%s]", requestId)); + metricsLogger.info(String.format("Metrics Logger: App-C Snapshot initiated. Start Time: [%s]. Request ID: [%s]", + startTime, requestId)); + + /* + * Copy any needed inputs or other values into the properties to be passed to the DG model + */ + UUID vmId = vnf.getVmId(); + Properties properties = new Properties(); + properties.put(Constants.CONTEXT_ACTION, "snapshot"); + properties.put(Constants.CONTEXT_REQID, requestId); + properties.put(Constants.CONTEXT_VMID, vmId.getValue()); + + UUID identityUrl = vnf.getIdentityUrl(); + if (identityUrl != null) { + properties.put(Constants.CONTEXT_IDENTITY_URL, identityUrl.getValue()); + } + /* + * Attempt to call the DG with the appropriate properties + */ + boolean success = callGraph(properties); + + /* + * Generate the appropriate response + */ + MDC.put("target", "appc"); + String statusStr = success ? "SUCCESS" : "FAILURE"; + String infomsg = + String.format("APPC0119I Snapshot '%s' finished with status %s. Reason: %s", requestId, statusStr, reason); + logger.info(infomsg); + + SnapshotOutputBuilder sob = new SnapshotOutputBuilder(); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + MDC.put("endTime", endTimeStr); + MDC.put("duration", durationStr); + sob.setCommonResponseHeader(ResponseHeaderBuilder.buildHeader(success, requestId, reason, duration)); + sob.setVmId(new UUID(vmId)); + + auditLogger.info(String.format( + "Audit Logger: APPC0119I Snapshot '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s", + requestId, statusStr, startTime, endTime, duration, requestId, reason)); + metricsLogger.info(String.format( + "Metrics Logger: APPC0119I Snapshot '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Duration: [%s]. Request ID: [%s]. Reason:%s", + requestId, statusStr, startTime, endTime, duration, requestId, reason)); + + // Status must be set to true to indicate that our return is expected + RpcResult<SnapshotOutput> rpcResult = + RpcResultBuilder.<SnapshotOutput> status(true).withResult(sob.build()).build(); + return rpcResult; + } + + private boolean callGraph(Properties props) { + String moduleName = configuration.getProperty(Constants.PROPERTY_MODULE_NAME); + String methodName = configuration.getProperty(Constants.PROPERTY_TOPOLOGY_METHOD); + String version = configuration.getProperty(Constants.PROPERTY_TOPOLOGY_VERSION); + String mode = Constants.SYNC_MODE; + return callGraph(moduleName, methodName, version, mode, props); + } + + /** + * Calls a specified directed graph with the specified properties and returns the response + * + * @param module + * The module name to be used to locate the graph + * @param method + * The method name to be executed (rpc) + * @param version + * The version of the graph to be used, or null for the latest + * @param mode + * the execution mode of the graph, sync or async + * @param props + * A set of name-value properties to be passed to the graph for context variables. + */ + private boolean callGraph(String module, String method, String version, String mode, Properties props) { + String graphName = String.format(("%s:%s:%s"), module, method, version); + logger.debug(String.format("Calling Graph %s", graphName)); + metricsLogger.info(String.format("Calling Graph %s", graphName)); + + boolean success = false; + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + AppcProviderClient svcLogicClient = new AppcProviderClient(); + try { + if (svcLogicClient.hasGraph(module, method, version, mode)) { + try { + Properties respProps = svcLogicClient.execute(module, method, version, mode, props); + success = false; // Assume it failed unless proven otherwise + reason = "Failed"; // Assume it failed unless proven otherwise + + logger.debug(EELFResourceManager.format(Msg.DEBUG_GRAPH_RESPONSE_HEADER, appName, graphName, + Integer.toString(respProps.size()))); + for (String key : respProps.stringPropertyNames()) { + logger.debug(EELFResourceManager.format(Msg.DEBUG_GRAPH_RESPONSE_DETAIL, appName, graphName, + key, (String) respProps.get(key))); + } + + // TODO - Find docs and see if there is a better way to handle this + // Bad requests have errors + if (respProps.containsKey(Constants.ATTRIBUTE_ERROR_CODE)) { + // || respProps.containsKey(Constants.ATTRIBUTE_ERROR_MESSAGE)) { + String errorCodeProperty = respProps.getProperty(Constants.ATTRIBUTE_ERROR_CODE).trim(); + int errorCode = 200; + try { + errorCode = Integer.parseInt(errorCodeProperty); + if (errorCode >= 300) { + reason = EELFResourceManager.format(Msg.DG_FAILED_RESPONSE, appName, graphName, + errorCodeProperty, respProps.getProperty(Constants.ATTRIBUTE_ERROR_MESSAGE)); + logger.error(reason); + success = false; + } else { + success = true; + reason = "Success"; + } + } catch (NumberFormatException e) { + reason = EELFResourceManager.format(Msg.PARAMETER_NOT_NUMERIC, appName, graphName, + Constants.ATTRIBUTE_ERROR_CODE, errorCodeProperty); + logger.error(reason); + success = false; + } + } else { + /* + * Added code that requires error code to now be defined in ALL cases. If not, it is an error + * and the response will be set to failed regardless if the DG worked or not. + */ + reason = EELFResourceManager.format(Msg.PARAMETER_IS_MISSING, appName, graphName, + Constants.ATTRIBUTE_ERROR_CODE); + logger.error(reason); + success = false; + } + } catch (Exception e) { + success = false; + reason = EELFResourceManager.format(Msg.EXCEPTION_CALLING_DG, e, appName, + e.getClass().getSimpleName(), graphName, e.getMessage()); + logger.error(reason); + } + } else { + success = false; + reason = EELFResourceManager.format(Msg.GRAPH_NOT_FOUND, appName, graphName); + logger.error(reason); + } + } catch (Exception e) { + success = false; + reason = EELFResourceManager.format(Msg.EXCEPTION_CALLING_DG, e, appName, e.getClass().getSimpleName(), + graphName, e.getMessage()); + logger.error(reason); + } + + return success; + } + +} diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/app-c/appc/appc-provider/appc-provider-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..f98d23c0f --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- + Starter Blueprint Camel Definition appc-aai-adapter-blueprint +--> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> +<!--<bean id="requestDispatcher" class="org.openecomp.appc.requesthandler.impl.RequestHandlerImpl" scope="singleton" > +</bean> + +<service id="requestDispatcherService" interface="org.openecomp.appc.requesthandler.RequestHandler" ref="requestDispatcher"/> + +<reference id="aaiAdapter" availability="mandatory" activation="eager" interface="org.openecomp.appc.adapter.aai.AAIAdapter"/>--> + +</blueprint> diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/resources/initial/appc-provider.xml b/app-c/appc/appc-provider/appc-provider-bundle/src/main/resources/initial/appc-provider.xml new file mode 100644 index 000000000..524993b4c --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/resources/initial/appc-provider.xml @@ -0,0 +1,118 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- vi: set et smarttab sw=4 tabstop=4: --> +<snapshot> + <configuration> + <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> + <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config"> + <module> + + <!-- This xmlns:prefix should match the namespace in the *-provider-impl.yang + file The prefix: inside type should match the prefix of the yang file. --> + <type xmlns:prefix="org:openecomp:appc:provider:impl"> + prefix:appc-provider-impl + </type> + <name>appc-provider-impl</name> + + <!-- The following sections contain bindings to services defined in + the *-provider-impl yang file. For example the rpc-registry is required because + we have a dependency (or augmentation) named "rpc-registry" and which binds + to the md-sa-binding-registry. If you remove those dependencies from the + yang file then you can remove them from here. --> + <rpc-registry> + <type + xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type> + <name>binding-rpc-broker</name> + </rpc-registry> + + <data-broker> + <type + xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type> + <name>binding-data-broker</name> + </data-broker> + + <notification-service> + <type + xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding"> + binding:binding-notification-service + </type> + <name>binding-notification-broker</name> + </notification-service> + </module> + + <module> + + <!-- This xmlns:prefix should match the namespace in the *-provider-impl.yang + file The prefix: inside type should match the prefix of the yang file. --> + <type xmlns:prefix="org:openecomp:appc:provider:lcm:impl"> + prefix:appc-provider-lcm-impl + </type> + <name>appc-provider-lcm-impl</name> + + <!-- The following sections contain bindings to services defined in + the *-provider-impl yang file. For example the rpc-registry is required because + we have a dependency (or augmentation) named "rpc-registry" and which binds + to the md-sa-binding-registry. If you remove those dependencies from the + yang file then you can remove them from here. --> + <rpc-registry> + <type + xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type> + <name>binding-rpc-broker</name> + </rpc-registry> + + <data-broker> + <type + xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type> + <name>binding-data-broker</name> + </data-broker> + + <notification-service> + <type + xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding"> + binding:binding-notification-service + </type> + <name>binding-notification-broker</name> + </notification-service> + </module> + + + </modules> + </data> + + </configuration> + + <!-- Required capabilities are basically a listing of all modules that need + to be imported before our service can be resolved. Capabilities for dependencies + defined above are implied which is why we do not have define a required capability + for the data broker, for example. --> + <!-- <required-capabilities> --> + <!-- <capability>appc:training:sample:provider:impl?module=sample-provider-impl&revision=2014-05-23</capability> --> + <!-- </required-capabilities> --> + <required-capabilities> + <capability>org:openecomp:appc:provider:impl?module=appc-provider-impl&revision=2014-05-23 + </capability> + <capability>org:openecomp:appc:provider:lcm:impl?module=appc-provider-lcm-impl&revision=2016-01-08 + </capability> + </required-capabilities> + +</snapshot> diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/resources/org/openecomp/appc/default.properties b/app-c/appc/appc-provider/appc-provider-bundle/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..e9ee35ada --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,55 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +# +# This property file supplies the configuration defaults for the APP-C controller +# +# Default values are supplied so that all defined properties have well-known values and are +# valid even if a configuration file is not supplied. This is done to ensure that a runnable, +# stable, and defined configuration exists at all times. The reason the defaults are supplied +# via this property file and not in the code is so that the properties can be changed +# easily if needed in the future. Use of the "getProperty(name, default)" method is +# discouraged because if the default value needs to be changed, everywhere in the code it +# is used would have to be changed. By loading the defaults in this property file, all +# values can be defined in one place and support is easier. This does mean that all +# properties that are defined must have a default value supplied here. Which also means +# this file documents all defined properties (not a bad thing either). +# +#-------------------------------------------------------------------------------------------- +# The path and file used to load user-supplied configuration settings, if any +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + +appc.application.name=APPC + +# +# The path to search for logging configuration document, and the name of the document +# +org.openecomp.appc.logging.path=${user.home},etc,../etc,. +org.openecomp.appc.logging.file=logback.xml + +# +# The DG properties +# +appc.service.logic.module.name=APPC +appc.topology.dg.method=topology-operation-all +appc.topology.dg.version=2.0.0 + diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/resources/org/openecomp/appc/logback.xml b/app-c/appc/appc-provider/appc-provider-bundle/src/main/resources/org/openecomp/appc/logback.xml new file mode 100644 index 000000000..8d47c6cae --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/resources/org/openecomp/appc/logback.xml @@ -0,0 +1,284 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<configuration scan="true" scanPeriod="3 seconds" debug="true"> + <!--<jmxConfigurator /> --> + <property name="logDirectory" value="logs" /> + <property name="debugLogDirectory" value="debug-logs" /> + <!-- Example evaluator filter applied against console appender --> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger - %msg%n</pattern> + </encoder> + </appender> + + <!-- ============================================================================ --> + <!-- CDP Appenders --> + <!-- ============================================================================ --> + + <!-- The CDPAppender is used to record events to the general CDP application + log. This is the log file used by default as the application root log, if + no other log is defined or the application creates specialized loggers of + the form com.att.cdp.x.y.z where the name occupied by the "x" is NOT security, + perf, server, coordinator, gui, or policy. These are defined as specialization + loggers for various business purposes. --> + <appender name="CDP" + class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDirectory}/cdp.log</file> + <rollingPolicy + class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/cdp.%i.log.zip + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy + class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - + %msg%n"</pattern> --> + <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method} + %X{Path}] - %msg%n</pattern> + </encoder> + </appender> + <appender name="asyncCDP" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>256</queueSize> + <appender-ref ref="CDP" /> + </appender> + + <!-- CDP Security Appender. This appender is used to record security events + to the security log file. Security events are separate from other loggers + in CDP so that security log records can be captured and managed in a secure + way separate from the other logs. This appender is set to never discard any + events. --> + <appender name="CDPSecurity" + class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDirectory}/cdp-security.log</file> + <rollingPolicy + class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/cdp-security.%i.log.zip + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy + class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - + %msg%n"</pattern> --> + <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method} + %X{Path}] - %msg%n</pattern> + </encoder> + </appender> + <appender name="asyncCDPSecurity" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>256</queueSize> + <discardingThreshold>0</discardingThreshold> + <appender-ref ref="CDPSecurity" /> + </appender> + + <!-- CDP Performance Appender. This appender is used to record performance + records. --> + <appender name="CDPPerformance" + class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDirectory}/cdp-performance.log</file> + <rollingPolicy + class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/cdp-performance.%i.log.zip + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy + class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <outputPatternAsHeader>true</outputPatternAsHeader> + <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method} + %X{Path}] - %msg%n</pattern> + </encoder> + </appender> + <appender name="asyncCDPPerformance" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>256</queueSize> + <appender-ref ref="CDPPerformance" /> + </appender> + + <!-- CDP Server Appender. This appender is used to record Server related + logging events. The Server logger and appender are specializations of the + CDP application root logger and appender. This can be used to segregate Server + events from other components, or it can be eliminated to record these events + as part of the application root log. --> + <appender name="CDPServer" + class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDirectory}/cdp-server.log</file> + <rollingPolicy + class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/cdp-server.%i.log.zip + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy + class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - + %msg%n"</pattern> --> + <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method} + %X{Path}] - %msg%n</pattern> + </encoder> + </appender> + <appender name="asyncCDPServer" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>256</queueSize> + <appender-ref ref="CDPServer" /> + </appender> + + <!-- CDP Coordinator Appender. This appender is used to record Coordinator + related logging events. The Coordinator logger and appender are specializations + of the CDP application root logger and appender. This can be used to segregate + Coordinator events from other components, or it can be eliminated to record + these events as part of the application root log. --> + <appender name="CDPCoordinator" + class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDirectory}/cdp-coordinator.log</file> + <rollingPolicy + class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/cdp-coordinator.%i.log.zip + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy + class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - + %msg%n"</pattern> --> + <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger - %msg%n</pattern> + </encoder> + </appender> + <appender name="asyncCDPCoordinator" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>256</queueSize> + <appender-ref ref="CDPCoordinator" /> + </appender> + + <!-- CDP Policy Appender. This appender is used to record Policy engine + related logging events. The Policy logger and appender are specializations + of the CDP application root logger and appender. This can be used to segregate + Policy engine events from other components, or it can be eliminated to record + these events as part of the application root log. --> + <appender name="CDPPolicy" + class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDirectory}/cdp-policy.log</file> + <rollingPolicy + class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/cdp-policy.%i.log.zip + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy + class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - + %msg%n"</pattern> --> + <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger - %msg%n</pattern> + </encoder> + </appender> + <appender name="asyncCDPPolicy" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>256</queueSize> + <appender-ref ref="CDPPolicy" /> + </appender> + <appender name="CommandExecutor" + class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${debugLogDirectory}/appc-debug.log</file> + <rollingPolicy + class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/command-executor.%i.log.zip + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy + class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <!--<Pattern> + %d{yyyy-MM-dd'T'HH:mm:ss.SSSZ}|%X{RequestID}|%X{ServiceInstanceID}|%thread|%X{ServerName}|%X{ServiceName}|%X{UUID}|%-5.5p|%X{Severity}|%X{ServerIPAddress}|%X{Server}|%X{IPAddress}|[%c{3}]|%X{Timer}| - %msg%n + </Pattern>--> + <Pattern> + %d{MM/dd-HH:mm:ss.SSS}|%X{RequestId}|%X{ServiceInstanceId}|%t|%X{ServiceName} - %X{bundle.id} - %X{bundle.name} - %X{bundle.version}|%X{InstanceUUID}|%-5.5p|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ServerFQDN}|%X{RemoteHost}|%X{Timer}|[%c{3}]|%m%n + </Pattern> + </encoder> + </appender> + + <logger name="org.openecomp.appc" level="DEBUG" additivity="false"> + <appender-ref ref="CommandExecutor" /> + </logger> + + <!-- ============================================================================ --> + <!-- CDP loggers --> + <!-- ============================================================================ --> + <logger name="com.att.cdp" level="info" additivity="false"> + <appender-ref ref="asyncCDP" /> + </logger> + <logger name="com.att.cdp.security" level="info" additivity="false"> + <appender-ref ref="asyncCDPSecurity" /> + </logger> + <logger name="com.att.cdp.perf" level="info" additivity="false"> + <appender-ref ref="asyncCDPPerformance" /> + </logger> + <logger name="com.att.cdp.server" level="debug" additivity="false"> + <appender-ref ref="asyncCDPServer" /> + </logger> + <logger name="com.att.cdp.coordinator" level="info" additivity="false"> + <appender-ref ref="asyncCDPCoordinator" /> + </logger> + <logger name="com.att.cdp.policy" level="info" additivity="false"> + <appender-ref ref="asyncCDPPolicy" /> + </logger> + + <!-- The OpenStack connector logger --> + <logger name="os" level="debug" additivity="false"> + <appender-ref ref="asyncCDPServer" /> + </logger> + + <root level="WARN"> + <appender-ref ref="STDOUT" /> + </root> + +</configuration> diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/resources/org/openecomp/appc/org.ops4j.pax.logging.cfg b/app-c/appc/appc-provider/appc-provider-bundle/src/main/resources/org/openecomp/appc/org.ops4j.pax.logging.cfg new file mode 100644 index 000000000..be5863291 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/resources/org/openecomp/appc/org.ops4j.pax.logging.cfg @@ -0,0 +1,144 @@ + ################################################################################ + # + # 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, + # WITH WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + # + ################################################################################ + + # Root + #log4j.rootLogger=TRACE, osgi:VmLogAppender + log4j.rootLogger=TRACE, out, sift, osgi:* + log4j.throwableRenderer=org.apache.log4j.OsgiThrowableRenderer + + # CONSOLE appender not used by default + log4j.appender.stdout=org.apache.log4j.ConsoleAppender + log4j.appender.stdout.layout=org.apache.log4j.PatternLayout + log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} | %-5.5p | %-16.16t | %-32.32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n + + # Async appender forwarding to file appender + log4j.appender.async=org.apache.log4j.AsyncAppender + log4j.appender.async.appenders=out + + # Karaf appenders + # File appender + log4j.appender.out=org.apache.log4j.RollingFileAppender + log4j.appender.out.layout=org.apache.log4j.PatternLayout + log4j.appender.out.layout.ConversionPattern=%d{ISO8601} | %-5.5p | %-16.16t | %-32.32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n + log4j.appender.out.file=${karaf.data}/log/karaf.log + log4j.appender.out.append=true + log4j.appender.out.maxFileSize=10MB + log4j.appender.out.maxBackupIndex=100 + + + # Sift appender + log4j.appender.sift=org.apache.log4j.sift.MDCSiftingAppender + log4j.appender.sift.key=bundle.name + log4j.appender.sift.default=karaf + log4j.appender.sift.appender=org.apache.log4j.RollingFileAppender + log4j.appender.sift.appender.layout=org.apache.log4j.PatternLayout + log4j.appender.sift.appender.layout.ConversionPattern=%d{MM/dd-HH:mm:ss.SSS}|%X{RequestId}|%X{ServiceInstanceId}|%t|%X{ServiceName} - %X{bundle.id} - %X{bundle.name} - %X{bundle.version}|%-5.5p|%X{AlertSeverity}|%X{ServerFQDN}|%X{ServerIPAddress}|[%c{3}]|%m%n + log4j.appender.sift.appender.file=${karaf.data}/log/eelf/karaf.log + log4j.appender.sift.appender.append=true + + log4j.category.org.opendaylight.controller.netconf.persist.impl.osgi.ConfigPusherImpl=DEBUG + log4j.category.org.opendaylight.controller.netconf.persist.impl.osgi.ConfigPersisterActivator=DEBUG + + + #ECOMP Debug appender + log4j.appender.debug=org.apache.log4j.RollingFileAppender + log4j.appender.debug.key=bundle.name + log4j.appender.debug.default=karaf + + log4j.appender.debug.appName=EELFDebug + log4j.appender.debug.layout=org.apache.log4j.PatternLayout + log4j.appender.debug.layout.ConversionPattern=%d{yyyy-MM-dd'T'hh:mm:ss.SSSXXX}|%X{RequestId}|%m%n + #log4j.appender.debug.filter.f1=org.apache.log4j.varia.LevelRangeFilter + #log4j.appender.debug.filter.f1.LevelMax=WARN + #log4j.appender.debug.filter.f1.LevelMin=TRACE + + + log4j.appender.debug.file=${karaf.data}/log/APPC/appc-debug.log + log4j.appender.debug.append=true + log4j.appender.debug.maxFileSize=100MB + log4j.appender.debug.maxBackupIndex=10 + + + #Error appender + log4j.appender.error=org.apache.log4j.RollingFileAppender + log4j.appender.error.appName=EELFError + log4j.appender.error.File=${karaf.data}/log/APPC/appc-error.log + log4j.appender.error.Threshold=ERROR + log4j.appender.error.MaxBackupIndex=1 + log4j.appender.error.MaxFileSize=100MB + log4j.appender.error.layout=org.apache.log4j.PatternLayout + log4j.appender.error.layout.ConversionPattern=%d{yyyy-MM-dd'T'hh:mm:ss.SSSXXX}|%X{RequestId}|%t|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%-5.5p|%X{ErrorCode}|%X{ErrorDescription}|%m%n + + #Metrics appender + log4j.appender.metric=org.apache.log4j.RollingFileAppender + log4j.appender.metric.appName=EELFMetrics + log4j.appender.metric.File=${karaf.data}/log/APPC/appc-metric.log + log4j.appender.metric.MaxBackupIndex=1 + log4j.appender.metric.MaxFileSize=100MB + log4j.appender.metric.layout=org.apache.log4j.PatternLayout + log4j.appender.metric.layout.ConversionPattern=%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%t|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%-5.5p|%X{Severity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{ClientIPAddress}|%X{ClassName}||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%m%n + + #Audit appender + log4j.appender.audit=org.apache.log4j.RollingFileAppender + log4j.appender.audit.appName=EELFAudit + log4j.appender.audit.File=${karaf.data}/log/APPC/appc-audit.log + log4j.appender.audit.MaxBackupIndex=1 + log4j.appender.audit.MaxFileSize=100MB + log4j.appender.audit.layout=org.apache.log4j.PatternLayout + log4j.appender.audit.layout.ConversionPattern=%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%t|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%-5.5p|%X{Severity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{ClientIPAddress}|%X{ClassName}||%X{ProcessKey}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%m%n + + #Loggers + #Routing of all messages from root logger + log4j.logger.com.att=TRACE, debug, error + #Store to the same log file messages from upper level appender or not + log4j.additivity.com.att=false + + #EELFManager loggers + #EELF parent logger + log4j.logger.com.att.eelf=TRACE, debug + log4j.additivity.com.att.eelf=false + + #Audit logger routing + log4j.logger.com.att.eelf.audit=DEBUG, audit + log4j.additivity.com.att.eelf.audit=false + + #Metric logger routing + log4j.logger.com.att.eelf.metrics=DEBUG, metric + log4j.additivity.com.att.eelf.metrics=false + + #Performance logger routing + log4j.logger.com.att.eelf.perf=DEBUG, metric + log4j.additivity.com.att.eelf.perf=false + + #Server logger routing + log4j.logger.com.att.eelf.server=DEBUG, debug + log4j.additivity.com.att.eelf.server=false + + #Policy logger routing + log4j.logger.com.att.eelf.policy=DEBUG, debug + log4j.additivity.com.att.eelf.policy=false + + #Error logger routing + log4j.logger.com.att.eelf.error=DEBUG, error + log4j.additivity.com.att.eelf.error=false + + #Debug logger routing + log4j.logger.com.att.eelf.debug=DEBUG, debug + log4j.additivity.com.att.eelf.debug=false + diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/yang/appc-provider-lcm.yang b/app-c/appc/appc-provider/appc-provider-bundle/src/main/yang/appc-provider-lcm.yang new file mode 100644 index 000000000..ea085aba4 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/yang/appc-provider-lcm.yang @@ -0,0 +1,61 @@ +module appc-provider-lcm-impl { + + yang-version 1; + namespace "org:openecomp:appc:provider:lcm:impl"; + prefix "appc-provider-lcm-impl"; + + import config { prefix config; revision-date 2013-04-05; } + import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; } + + description + "This module contains the base YANG definitions for + appc-provider-lcm implementation."; + + revision "2016-01-08" { + description + "Initial revision."; + } + + // This is the definition of the service implementation as a module identity. + identity appc-provider-lcm-impl { + base config:module-type; + + // Specifies the prefix for generated java classes. + config:java-name-prefix AppcProviderLcm; + } + + // Augments the 'configuration' choice node under modules/module. + // We consume the three main services, RPCs, DataStore, and Notifications + augment "/config:modules/config:module/config:configuration" { + case appc-provider-lcm-impl { + when "/config:modules/config:module/config:type = 'appc-provider-lcm-impl'"; + + container rpc-registry { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity mdsal:binding-rpc-registry; + } + } + } + + container notification-service { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity mdsal:binding-notification-service; + } + } + } + + container data-broker { + uses config:service-ref { + refine type { + mandatory false; + config:required-identity mdsal:binding-async-data-broker; + } + } + } + } + } +} diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/main/yang/appc-provider.yang b/app-c/appc/appc-provider/appc-provider-bundle/src/main/yang/appc-provider.yang new file mode 100644 index 000000000..95d90adaf --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/main/yang/appc-provider.yang @@ -0,0 +1,61 @@ +module appc-provider-impl { + + yang-version 1; + namespace "org:openecomp:appc:provider:impl"; + prefix "appc-provider-impl"; + + import config { prefix config; revision-date 2013-04-05; } + import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; } + + description + "This module contains the base YANG definitions for + appc-provider implementation."; + + revision "2014-05-23" { + description + "Initial revision."; + } + + // This is the definition of the service implementation as a module identity. + identity appc-provider-impl { + base config:module-type; + + // Specifies the prefix for generated java classes. + config:java-name-prefix AppcProvider; + } + + // Augments the 'configuration' choice node under modules/module. + // We consume the three main services, RPCs, DataStore, and Notifications + augment "/config:modules/config:module/config:configuration" { + case appc-provider-impl { + when "/config:modules/config:module/config:type = 'appc-provider-impl'"; + + container rpc-registry { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity mdsal:binding-rpc-registry; + } + } + } + + container notification-service { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity mdsal:binding-notification-service; + } + } + } + + container data-broker { + uses config:service-ref { + refine type { + mandatory false; + config:required-identity mdsal:binding-async-data-broker; + } + } + } + } + } +} diff --git a/app-c/appc/appc-provider/appc-provider-bundle/src/test/java/org/openecomp/appc/AppcProviderTest.java b/app-c/appc/appc-provider/appc-provider-bundle/src/test/java/org/openecomp/appc/AppcProviderTest.java new file mode 100644 index 000000000..3915c8da0 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-bundle/src/test/java/org/openecomp/appc/AppcProviderTest.java @@ -0,0 +1,84 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.appc; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import org.junit.After; +import org.junit.Ignore; +import org.junit.Test; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest; +import org.opendaylight.controller.sal.binding.api.NotificationProviderService; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.openecomp.appc.provider.AppcProvider; + +/** + * Defines a unit test class which tests the provider. This class leverages the AbstractDataBrokerTest class which + * starts a real MD-SAL implementation to use inside of your unit tests. This is not an exhaustive test, but rather is + * used to illustrate how one can leverage the AbstractDataBrokerTest to test MD-SAL providers/listeners. + */ +public class AppcProviderTest extends AbstractDataBrokerTest { + + private ExecutorService threadPool = Executors.newSingleThreadExecutor(); + private AppcProvider provider; + private DataBroker dataBroker; + + /** + * The @Before annotation is defined in the AbstractDataBrokerTest class. The method setupWithDataBroker is invoked + * from inside the @Before method and is used to initialize the databroker with objects for a test runs. In our case + * we use this oportunity to create an instance of our provider and initialize it (which registers it as a listener + * etc). This method runs before every @Test method below. + */ + @Override + protected void setupWithDataBroker(DataBroker dataBroker) { + super.setupWithDataBroker(dataBroker); + + this.dataBroker = dataBroker; + NotificationProviderService nps = null; + RpcProviderRegistry registry = null; + + provider = new AppcProvider(dataBroker, nps, registry); + } + + /** + * Shuts down our provider, testing close code. @After runs after every @Test method below. + */ + @After + public void stop() throws Exception { + if (provider != null) { + provider.close(); + } + } + + /** + * This validates that when a task is created, the run count is initialized to 0 + */ + @Ignore + @Test + public void sampleUnitTest() { + // This is where you add your unit testing. You can access "DataBroker" as + // needed to create items etc. + // This a "Real" data broker. + } +} diff --git a/app-c/appc/appc-provider/appc-provider-features/.gitignore b/app-c/appc/appc-provider/appc-provider-features/.gitignore new file mode 100644 index 000000000..2992ae832 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-features/.gitignore @@ -0,0 +1,3 @@ +/target/ +/bin/ +/.settings/ diff --git a/app-c/appc/appc-provider/appc-provider-features/pom.xml b/app-c/appc/appc-provider/appc-provider-features/pom.xml new file mode 100644 index 000000000..49d3e48f0 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-features/pom.xml @@ -0,0 +1,143 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-provider</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <name>appc-provider-features</name> + <artifactId>appc-provider-features</artifactId> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-provider-model</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-provider-bundle</artifactId> + <classifier>config</classifier> + <type>xml</type> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-provider-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>features-mdsal</artifactId> + <classifier>features</classifier> + <type>xml</type> + + <scope>runtime</scope> + </dependency> + + + + <!-- dependency for opendaylight-karaf-empty for use by testing --> +<!-- <dependency> --> +<!-- <groupId>org.opendaylight.controller</groupId> --> +<!-- <artifactId>opendaylight-karaf-empty</artifactId> --> +<!-- <type>zip</type> --> +<!-- </dependency> --> + + +<!-- <dependency> --> +<!-- Required for launching the feature tests --> +<!-- <groupId>org.opendaylight.yangtools</groupId> --> +<!-- <artifactId>features-test</artifactId> --> +<!-- <scope>test</scope> --> +<!-- </dependency> --> + + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>features-yangtools</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <plugin> + <!-- launches the feature test, which validates that your karaf feature + can be installed inside of a karaf container. It doesn't validate that your + functionality works correctly, just that you have all of the dependent bundles + defined correctly. --> + <!-- Skipping ODL feature test --> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <systemPropertyVariables> + <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId> + <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId> + <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version> + </systemPropertyVariables> + <dependenciesToScan> + <dependency>org.opendaylight.yangtools:features-test</dependency> + </dependenciesToScan> + <classpathDependencyExcludes> + <!-- The dependencies which bring in AbstractDataBrokerTest class + brings in a second PaxExam container which results in the feature tests failing + with a message similar to: "ERROR o.ops4j.pax.exam.spi.PaxExamRuntime - Ambiguous + TestContainer ..." This excludes the container we don't want to use. --> + <classpathDependencyExcludes>org.ops4j.pax.exam:pax-exam-container-native</classpathDependencyExcludes> + </classpathDependencyExcludes> + <skipTests>true</skipTests> + </configuration> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + + </plugins> + </build> +</project> diff --git a/app-c/appc/appc-provider/appc-provider-features/src/main/resources/features.xml b/app-c/appc/appc-provider/appc-provider-features/src/main/resources/features.xml new file mode 100644 index 000000000..278fa4285 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-features/src/main/resources/features.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + + +<features name="appc-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + +<!-- <repository>mvn:org.opendaylight.mdsal/features-mdsal/${odl.mdsal.version}/xml/features</repository> --> + <repository>mvn:org.opendaylight.mdsal/features-mdsal/${features-mdsal.version}/xml/features</repository> + + <feature name='appc-provider' description="application controller" version='${project.version}'> + <!--<feature version="${project.version}">appc-aai-adapter</feature>--> + <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> + <!-- <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> --> + <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> + <bundle>mvn:org.openecomp.appc/appc-provider-model/${project.version}</bundle> + <bundle>mvn:org.openecomp.appc/appc-provider-bundle/${project.version}</bundle> + <configfile finalname="etc/opendaylight/karaf/200-appc-provider.xml">mvn:org.openecomp.appc/appc-provider-bundle/${project.version}/xml/config</configfile> + </feature> + +</features> diff --git a/app-c/appc/appc-provider/appc-provider-installer/.gitignore b/app-c/appc/appc-provider/appc-provider-installer/.gitignore new file mode 100644 index 000000000..731eb433c --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-installer/.gitignore @@ -0,0 +1,2 @@ +/target/ +/.settings/ diff --git a/app-c/appc/appc-provider/appc-provider-installer/pom.xml b/app-c/appc/appc-provider/appc-provider-installer/pom.xml new file mode 100644 index 000000000..cb3186fe4 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-installer/pom.xml @@ -0,0 +1,143 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-provider</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + + <artifactId>appc-provider-installer</artifactId> + <name>APPC Provider - Karaf Installer</name> + <packaging>pom</packaging> + + <properties> + <application.name>appc-provider</application.name> + <features.boot>appc-provider</features.boot> + <features.repositories>mvn:org.openecomp.appc/appc-provider-features/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-provider-features</artifactId> + <version>${project.version}</version> + <classifier>features</classifier> + <type>xml</type> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-provider-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-provider-bundle</artifactId> + <version>${project.version}</version> + <classifier>config</classifier> + <type>xml</type> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>false</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>true</attach> + <finalName>${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <excludeGroupIds>org.opendaylight</excludeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals> + <!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> diff --git a/app-c/appc/appc-provider/appc-provider-installer/src/assembly/assemble_installer_zip.xml b/app-c/appc/appc-provider/appc-provider-installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..8948a3302 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>controller</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/app-c/appc/appc-provider/appc-provider-installer/src/assembly/assemble_mvnrepo_zip.xml b/app-c/appc/appc-provider/appc-provider-installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..599ceafb3 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,54 @@ +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>controller</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + + <files> + <file> + <source>../${feature-name}-bundle/src/main/resources/initial/${feature-name}.xml</source> + <destName>./etc/opendaylight/karaf/200-${feature-name}.xml</destName> + </file> + </files> + +</assembly> diff --git a/app-c/appc/appc-provider/appc-provider-installer/src/main/resources/scripts/install-feature.sh b/app-c/appc/appc-provider/appc-provider-installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..1d769fada --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-installer/src/main/resources/scripts/install-feature.sh @@ -0,0 +1,40 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights +# reserved. +# ================================================================================ +# Licensed 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. +# ============LICENSE_END========================================================= +### + +#!/bin/bash + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -n -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot} diff --git a/app-c/appc/appc-provider/appc-provider-model/.gitignore b/app-c/appc/appc-provider/appc-provider-model/.gitignore new file mode 100644 index 000000000..2992ae832 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-model/.gitignore @@ -0,0 +1,3 @@ +/target/ +/bin/ +/.settings/ diff --git a/app-c/appc/appc-provider/appc-provider-model/pom.xml b/app-c/appc/appc-provider/appc-provider-model/pom.xml new file mode 100644 index 000000000..8b4ebdcdb --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-model/pom.xml @@ -0,0 +1,96 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-provider</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <artifactId>appc-provider-model</artifactId> + <packaging>bundle</packaging> + + <build> + + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Import-Package>*</Import-Package> + </instructions> + </configuration> + </plugin> + <plugin> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>yang-maven-plugin</artifactId> + <version>${odl.yangtools.version}</version> + <dependencies> + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>maven-sal-api-gen-plugin</artifactId> + <version>${odl.yangtools.version}</version> + <type>jar</type> + </dependency> + </dependencies> + <executions> + <execution> + <goals> + <goal>generate-sources</goal> + </goals> + <configuration> + <yangFilesRootDir>${yang.file.directory}</yangFilesRootDir> + <codeGenerators> + <generator> + <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass> + <outputBaseDir>${salGeneratorPath}</outputBaseDir> + </generator> + </codeGenerators> + <inspectDependencies>true</inspectDependencies> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <version>1.12</version> + <executions> + <execution> + <id>add-generated-source</id> + <phase>generate-sources</phase> + <goals> + <goal>add-source</goal> + </goals> + <configuration> + <sources> + <!-- project.build.directory defaults to be the "target" folder --> + <source>${project.build.directory}/generated-sources/yang-gen-sal</source> + </sources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>yang-binding</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>yang-common</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.mdsal.model</groupId> + <artifactId>ietf-inet-types</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.mdsal.model</groupId> + <artifactId>ietf-yang-types</artifactId> + </dependency> + </dependencies> +</project> diff --git a/app-c/appc/appc-provider/appc-provider-model/src/main/yang/appc-provider-lcm.yang b/app-c/appc/appc-provider/appc-provider-model/src/main/yang/appc-provider-lcm.yang new file mode 100644 index 000000000..6f2d0b480 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-model/src/main/yang/appc-provider-lcm.yang @@ -0,0 +1,949 @@ +/* + * Yang model for the Application Controller (APP-C) component of ECOMP + * + * This model is used to define the data and services of the Application Controller + * component of ECOMP. The APP-C controller initiates the processing of directed + * graphs, which define the actual process implementations used. The name of the + * directed graph is set by properties and cannot be changed dynamically. + * + * The services exposed by this provider are: + * + * restart-vnf: + * Used to request a restart of a virtual network function (a VM). + * + * rebuild-vnf: + * Used to request a rebuild of a virtual network function (a VM). + * + */ + +module appc-provider-lcm { + + yang-version 1; + namespace "org:openecomp:appc"; + prefix appc-provider-lcm; + organization "Copyright 2017 AT&T Intellectual Property."; + + description + "Defines the services and request/response requirements for the ECOMP APP-C component."; + + /* + * Note, the revision changes the package name of the generated java code. Do not + * change the revision unless you also update all references to the bindings. + */ + revision "2016-01-08" { + description + "APP-C interface version 1.0.48"; + } + + /********************************************************************************** + * Data type definitions + * + * The following data type definitions are used to define common data structures, + * define constraints, or to impart special meanings to data objects related to the + * APP-C controller functions. + **********************************************************************************/ + + /* + * Define a common definition of a UUID + */ + typedef UUID { + type string { + length "1..255"; + } + description "Universally Unique ID"; + } + + /* + * Define the name of the provider region/LCP to connect to + */ + typedef LCP { + type string { + length "1..255"; + } + description "The local control plane name (OpenStack region name) of the provider"; + } + + /* + * Define a common definition of a time stamp (expressed as a formatted string) as follows + * + * yyyy-MM-dd HH:mm:ss.SSSSSSSS + * + * yyyy ...... exactly 4 digit year, e.g., 2015 + * MM ........ 1 or 2 digit month of year, e.g., 7 + * dd ........ 1 or 2 digit day of month, e.g., 29 + * HH ........ 1 or 2 digit hour of day (24-hour clock) in UTC, e.g., 17 + * mm ........ 1 or 2 digit minute of the hour, e.g. 31 + * ss ........ 1 or 2 digit seconds of the minute, e.g., 28 + * SSSSSS .... 1-6 digit microseconds + */ + typedef TIMESTAMP { + type string { + length "16..28"; + pattern "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}.[0-9]{1,6}"; + } + } + + typedef ZULU { + type string { + length "16..28"; + pattern "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}T[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}.[0-9]{1,6}Z"; + } + } + + typedef payload { + type string ; + description "The payload can be any valid JSON string value. Json escape characters need to be added when required to include an inner json within the payload to make it a valid json string value"; + } + + typedef action { + type enumeration { + enum "Restart"; + enum "Rebuild"; + enum "Migrate"; + enum "Evacuate"; + enum "Snapshot"; + enum "Rollback"; + enum "Sync"; + enum "Audit"; + enum "Stop"; + enum "Terminate"; + enum "SoftwareUpload"; + enum "HealthCheck"; + enum "LiveUpgrade"; + enum "ModifyConfig"; + enum "Lock"; + enum "Unlock"; + enum "Test"; + enum "CheckLock"; + } + description "The action to be taken by APP-C, e.g. Restart, Rebuild, Migrate"; + } + + /********************************************************************************** + * All requests will include this standard header + * + * The standard request header is used to define a correlation identification for + * the request that is returned on all responses. This correlation identifier + * (called the service-request-id) is meaningful to the caller and is included on + * all responses from the services. + **********************************************************************************/ + grouping common-request-header { + description "A common header for all requests"; + container common-request-header { + leaf service-request-id { + description "An identifier meaningful to the caller to correlate all responses"; + type string; + mandatory true; + } + + leaf time-to-live { + description "The alloted time to perform the operation, in seconds. If the + operation cannot be completed in this amount of time, the operation is + aborted. If set to zero, no timeout exists and the operation will continue + until it completes or fails. If omitted, the default value of 0 is used."; + type uint32 { + range "0..86400"; + } + mandatory false; + } + } + } + + /********************************************************************************** + * Basic manipulation of a VNF (or VM) will typically include querying the current + * state, restarting, rebuilding, stopping, starting, etc. In all of these basic + * "state"-type operations, the services require the identification of the VNF to + * be operated on, and the region or LCP that contains that resource. This + * information is used across all of these services, so it has been defined as a + * common structure here and is referenced in the appropriate RPC definitions. + **********************************************************************************/ + grouping vnf-resource { + description "The data that uniquely identifies a virtual network function (or vm)"; + container vnf-resource { + leaf vm-id { + description "The UUID of the resource. For backwards compatibility, this can be + the self-link URL of the VM."; + type UUID; + mandatory true; + } + leaf identity-url { + description "The identity url used to access the resource"; + type UUID; + mandatory false; + } + leaf tenant-id { + description "The id of the provider tenant that owns the resource"; + type string; + mandatory false; + } + } + } + + /********************************************************************************** + * All responses will include this standard header + * + * The standard response header includes the time of completion as well as a + * success|failure indication + **********************************************************************************/ + grouping common-response-header { + description "A common header for all responses defining success or failure + and the time stamp when completed"; + container common-response-header { + leaf service-request-id { + description "An identifier meaningful to the caller to correlate all responses"; + type string; + } + leaf success { + description "True indicates the request was successful"; + type boolean; + } + leaf reason { + description "If success=false, the failure reason. Otherwise, undefined."; + type string; + } + leaf completed { + description "The formatted time stamp when the operation was completed."; + type TIMESTAMP; + } + leaf duration { + description "The amount of time used (in seconds) to process the request"; + type uint32; + } + } + } + + + /********************************************************************************** + * All requests/response will include this standard header + * + * The standard common header is used to define a correlation identification for + * the request that is returned on all responses. + **********************************************************************************/ + grouping common-header { + description "A common header for all APP-C requests"; + container common-header { + description "A common header for all APP-C requests"; + leaf timestamp { + description "timestamp is in ISO 8601 timestamp format ZULU offset"; + type ZULU; + mandatory true; + } + + leaf api-ver { + description "api-ver is the API version identifier. A given release of APPC should support all previous versions of APPC API (correlate with general requirements)"; + type string { + pattern "[2]\.\d\d"{ + error-message "API Version 2.XX is supported at this end point"; + } + } + mandatory true; + } + + leaf originator-id { + description "originator-id an identifier of the calling system which can be used addressing purposes, i.e. returning asynchronous response to the proper destination over DMaaP (especially in case of multiple consumers of APP-C APIs)"; + type string; + mandatory true; + } + + leaf request-id { + description "UUID for the request ID. An OSS/BSS identifier for the request that caused the current action. Multiple API calls may be made with the same request-id The request-id shall be recorded throughout the operations on a single request"; + type string; + mandatory true; + } + + leaf sub-request-id { + description "Uniquely identifies a specific LCM action. It is persistent over the life-cycle of a single request"; + type string; + mandatory false; + } + + + /********************************************************************************** + * Flags are generic flags that apply to any and all commands, all are optional + * force = TRUE/FALSE - Execute command even if target is in unstable (i.e. locked, transiting, etc) state. Specific behaviour of forced commands varies, but implies cancellation of previous command and an override by the new command. The FALSE value is used by default. + * ttl = <0....N> - The timeout value for command execution, expressed in seconds + * mode = EXCLUSIVE/NORMAL - defines execution mode as follows: + * - EXCLUSIVE ? on encountering an exclusive command, the APP-C will: + * * Cease accepting additional command requests + * * Complete execution of outstanding commands + * * Execute the exclusive command to completion + * * Optionally report the result of the command + * * Optionally resume command acceptance and processing + * - NORMAL - Obverse of EXCLUSIVE, the default one. + **********************************************************************************/ + container flags { + description "Flags are generic flags that apply to any and all commands, all are optional"; + leaf mode { + type enumeration { + enum "EXCLUSIVE"; + enum "NORMAL"; + } + description "EXCLUSIVE (accept no queued requests on this VNF while processing) or NORMAL (queue other requests until complete)"; + mandatory false; + } + leaf force { + type enumeration { + enum "TRUE"; + enum "FALSE"; + } + description "TRUE/FALSE - Execute action even if target is in unstable (i.e. locked, transiting, etc.) state"; + mandatory false; + } + leaf ttl { + description "<0....N> - The timeout value (expressed in seconds) for action execution, between action being received by APPC and action initiation"; + type uint16; + mandatory false; + } + } + } + } + + + grouping action-identifiers { + description "A block containing the action arguments. These are used to specify the object upon which APP-C LCM command is to operate"; + container action-identifiers { + description "A block containing the action arguments. These are used to specify the object upon which APP-C LCM command is to operate"; + leaf service-instance-id { + description "identifies a specific service the command refers to. When multiple APP-C instances are used and applied to a subset of services, this will become significant . The field is mandatory when the vnf-id is empty"; + type string; + mandatory false; + } + leaf vnf-id { + description "identifies the VNF to which this action is to be applied(vnf-id uniquely identifies the service-instance referred to). Note that some actions are applied to multiple VNFs in the same service. When this is the case, vnf-id may be left out, but service-instance-id must appear. The field is mandatory when service-instance-id is empty"; + type string; + mandatory false; + } + leaf vnfc-name { + description "identifies the VNFC to which this action is to be applied. Some actions apply only to a component within a VNF (e.g. RESTART is sometimes applied to on VM only). In such a case, the name of the VNFC is used to search for the component within the VNF"; + type string; + mandatory false; + } + leaf vserver-id { + description "identifies a specific VM within the given service/vnf to which this action is to be applied"; + type string; + mandatory false; + } + } + } + + grouping status { + description "The specific response codes are to be aligned with ASDC reference doc (main table removed to avoid duplication and digression from main table). See ASDC and ECOMP Distribution Consumer Interface Agreement"; + container status { + description "The specific response codes are to be aligned with ASDC reference doc (main table removed to avoid duplication and digression from main table). See ASDC and ECOMP Distribution Consumer Interface Agreement"; + leaf code { + description "Response code"; + type uint16; + mandatory true; + } + leaf message { + description "Response message"; + type string; + mandatory true; + } + } + } + + + /********************************************************************************** + * NEW API :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + * All requests will include this standard header + * + * The standard request header is used to define a correlation identification for + * the request that is returned on all responses. This correlation identifier + * (called the service-request-id) is meaningful to the caller and is included on + * all responses from the services. + **********************************************************************************/ + grouping RequestHeader { + container RequestHeader { + description "A common header for all APP-C requests"; + leaf TimeStamp { + description "TimeStamp is in ISO 8601 timestamp format ZULU offset"; + type TIMESTAMP; + mandatory true; + } + + leaf APIver { + description "APIver is the API version identifier. A given release of APPC should support all previous versions of APPC API (correlate with general requirements)"; + type string; + mandatory true; + } + + leaf OriginatorID { + description "OriginatorID an identifier of the calling system which can be used addressing purposes, i.e. returning asynchronous response to the proper destination over DMaaP (especially in case of multiple consumers of APP-C APIs)"; + type string; + mandatory true; + } + + leaf TransactionID { + description "Identifiers that may be generated when multiple responses or handling passes are needed for a given request, allowing the request itself to be tracked"; + type string; + mandatory true; + } + + leaf-list RequestTrack { + description "Identifiers that may be generated when multiple responses or handling passes are needed for a given request, allowing the request itself to be tracked"; + type string; + } + + /********************************************************************************** + * Flags are generic flags that apply to any and all commands, all are optional + * FORCE = TRUE/FALSE - Execute command even if target is in unstable (i.e. locked, transiting, etc) state. Specific behaviour of forced commands varies, but implies cancellation of previous command and an override by the new command. The FALSE value is used by default. + * TTL = <0....N> - The timeout value for command execution, expressed in seconds + * MODE = EXCLUSIVE/NORMAL - defines execution mode as follows: + * - EXCLUSIVE � on encountering an exclusive command, the APP-C will: + * * Cease accepting additional command requests + + * Complete execution of outstanding commands + * * Execute the exclusive command to completion + * * Optionally report the result of the command + * * Optionally resume command acceptance and processing + * - NORMAL - Obverse of EXCLUSIVE, the default one. + **********************************************************************************/ + container Flags { + description "Flags are generic flags that apply to any and all commands, all are optional"; + leaf FORCE { + description "TRUE/FALSE - Execute action even if target is in unstable (i.e. locked, transiting, etc) state."; + type string; + mandatory false; + } + leaf TTL { + description "<0....N> - The timeout value for action execution, expressed in seconds"; + type string; + mandatory false; + } + leaf MODE { + description "EXCLUSIVE/NORMAL - defines execution mode"; + type string; + mandatory false; + } + } + } + } + + grouping RequestParameters { + description "The request contains the entry of command-specific and is opaque to the APP-C handler"; + leaf Action { + description "The actual action to be taken"; + type string; + mandatory true; + } + leaf TargetID { + description "The specific VF a component of which is to be affected"; + type string; + mandatory true; + } + leaf ObjectID { + description "The specific VFC within a VF to be affected"; + type string; + mandatory true; + } + leaf Payload { + description "An action-specific value opaque to the APPC handler. + The value can be any valid JSON type (primitive, object, collection of those two). + APPC will pass the value as raw JSON string to the executing LCM action."; + type string; + mandatory true; + } + } + + grouping ResponseHeader { + description "The response to an APP-C command or control is, likewise, encoded in a JSON object. "; + container ResponseHeader { + description "The response to an APP-C command or control is, likewise, encoded in a JSON object. "; + leaf TimeStamp { + description "TimeStamp is in ISO 8601 timestamp format ZULU offset"; + type TIMESTAMP; + mandatory true; + } + + leaf APIver { + description "APIver is the API version identifier. A given release of APPC should support all previous versions of APPC API (correlate with general requirements)"; + type string; + mandatory true; + } + + leaf ResponseID { + description "ResponseID an identifier of the calling system which can be used addressing purposes, i.e. returning asynchronous response to the proper destination over DMaaP (especially in case of multiple consumers of APP-C APIs)"; + type string; + mandatory true; + } + + leaf-list SubResponseID { + description "Identifiers that may be generated when multiple responses or handling passes are needed for a given request, allowing the request itself to be tracked"; + type string; + } + } + } + + grouping ResponseAttributes { + description "The response contains the status of executed functionality"; + container Status { + description "The specific response codes are to be aligned with ASDC reference doc (main table removed to avoid duplication and digression from main table). See ASDC and ECOMP Distribution Consumer Interface Agreement"; + leaf Code { + description "Response code value"; + type uint32; + mandatory true; + } + leaf Value { + description "Response code description"; + type string; + mandatory true; + } + } + leaf Payload { + description "Payload - the entry is command-specific and is opaque to the APP-C handler. + The value can be any valid JSON type (primitive, object, collection of those two). + APP-C will pass the value as raw JSON string to appropriate addressee"; + type string; + mandatory false; + } + } + + + + + + + /********************************************************************************** + * Define the restart service + **********************************************************************************/ + rpc restart { + description "An operation to restart a virtual network function (or VM)"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + } + output { + uses common-header; + uses status; + } + } + + /********************************************************************************** + * Define the rebuild service + **********************************************************************************/ + rpc rebuild { + description "An operation to rebuild a virtual network function (or VM)"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + } + output { + uses common-header; + uses status; + } + } + + /********************************************************************************** + * Define the migrate service + **********************************************************************************/ + rpc migrate { + description "An operation to migrate a virtual network function (or VM)"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + } + output { + uses common-header; + uses status; + } + } + + /********************************************************************************** + * Define the evacuate service + **********************************************************************************/ + rpc evacuate { + description "An operation to evacuate a virtual network function (or VM)"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + } + output { + uses common-header; + uses status; + } + } + + + /********************************************************************************** + * Define the snapshot service + **********************************************************************************/ + rpc snapshot { + description "An operation to create a snapshot of a virtual network function (or VM)"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + leaf identity-url { + type string; + mandatory true; + } + } + output { + uses common-header; + uses status; + leaf snapshot-id { + type string; + } + + } + } + + /********************************************************************************** + * Define the rollback service + **********************************************************************************/ + rpc rollback { + description "An operation to rollback to particular snapshot of a virtual network function (or VM)"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + leaf identity-url { + type string; + mandatory true; + } + leaf snapshot-id { + type string; + mandatory true; + } + } + output { + uses common-header; + uses status; + } + } + + + /********************************************************************************** + * Additional RPCs added here... + **********************************************************************************/ + + + /********************************************************************************** + * Define the sync service + **********************************************************************************/ + rpc sync { + description "An operation to sync the configurations of a virtual network function (or VM)"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + } + output { + uses common-header; + uses status; + } + } + + /********************************************************************************** + * Define the terminate service + **********************************************************************************/ + rpc terminate { + description "An operation to terminate the configurations of a virtual network function (or VM)"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + } + output { + uses common-header; + uses status; + } + } + + /********************************************************************************** + * Define the modify-config service + **********************************************************************************/ + rpc modify-config { + description "An operation to modify-config the configurations of a virtual network function (or VM)"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + } + output { + uses common-header; + uses status; + } + } + + /********************************************************************************** + * Define the test service + **********************************************************************************/ + rpc test { + description "An operation to test the configurations of a virtual network function (or VM)"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + } + output { + uses common-header; + uses status; + } + } + + /********************************************************************************** + * Define the stop service + **********************************************************************************/ + rpc stop { + description "An operation to stop the configurations of a virtual network function (or VM)"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + } + output { + uses common-header; + uses status; + } + } + + /********************************************************************************** + * Define the audit service + **********************************************************************************/ + rpc audit { + description "An operation to audit the configurations of a virtual network function (or VM)"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + } + output { + uses common-header; + uses status; + } + } + + /********************************************************************************** + * Define the SoftwareUpload vSCP service + **********************************************************************************/ + rpc software-upload { + description "An operation to upload a new version of vSCP image to vSCP for updating it"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + } + output { + uses common-header; + uses status; + } + } + + + + /********************************************************************************** + * Define the PreHealthCheck vSCP service + **********************************************************************************/ + rpc health-check { + description "An operation to perform health check of vSCP prior its upgrading"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + } + output { + uses common-header; + uses status; + + } + } + + + /********************************************************************************** + * Define the Upgrade vSCP service + **********************************************************************************/ + rpc live-upgrade { + description "An operation to perform upgrade of vSCP"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + } + output { + uses common-header; + uses status; + } + } + + + /********************************************************************************** + * Define the VNF lock service + **********************************************************************************/ + rpc lock { + description "An operation to perform VNF lock operation"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + } + output { + uses common-header; + uses status; + } + } + + /********************************************************************************** + * Define the VNF unlock service + **********************************************************************************/ + rpc unlock { + description "An operation to perform VNF unlock operation"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + } + output { + uses common-header; + uses status; + } + } + + /********************************************************************************** + * Define the VNF check lock service + **********************************************************************************/ + rpc check-lock { + description "An operation to check VNF lock status"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + } + output { + uses common-header; + uses status; + leaf locked { + type enumeration { + enum "TRUE"; + enum "FALSE"; + } + description "TRUE/FALSE - returns TRUE when the given VNF was locked, otherwise returns FALSE"; + mandatory false; + } + } + } + + + /********************************************************************************** + * Additional RPCs added here... + **********************************************************************************/ +} diff --git a/app-c/appc/appc-provider/appc-provider-model/src/main/yang/appc-provider.yang b/app-c/appc/appc-provider/appc-provider-model/src/main/yang/appc-provider.yang new file mode 100644 index 000000000..6bdccf483 --- /dev/null +++ b/app-c/appc/appc-provider/appc-provider-model/src/main/yang/appc-provider.yang @@ -0,0 +1,620 @@ +/* + * Yang model for the Application Controller (APP-C) component of ECOMP + * + * This model is used to define the data and services of the Application Controller + * component of ECOMP. The APP-C controller initiates the processing of directed + * graphs, which define the actual process implementations used. The name of the + * directed graph is set by properties and cannot be changed dynamically. + * + * The services exposed by this provider are: + * + * restart-vnf: + * Used to request a restart of a virtual network function (a VM). + * + * rebuild-vnf: + * Used to request a rebuild of a virtual network function (a VM). + * + */ + +module appc-provider { + + yang-version 1; + namespace "org:openecomp:appc"; + prefix appc-provider; + organization "Copyright 2017 AT&T Intellectual Property."; + + description + "Defines the services and request/response requirements for the ECOMP APP-C component."; + + /* + * Note, the revision changes the package name of the generated java code. Do not + * change the revision unless you also update all references to the bindings. + */ + revision "2016-01-04" { + description + "APP-C interface version 1.0.48"; + } + + /********************************************************************************** + * Data type definitions + * + * The following data type definitions are used to define common data structures, + * define constraints, or to impart special meanings to data objects related to the + * APP-C controller functions. + **********************************************************************************/ + + /* + * Define a common definition of a UUID + */ + typedef UUID { + type string { + length "1..255"; + } + description "Universally Unique ID"; + } + + /* + * Define the name of the provider region/LCP to connect to + */ + typedef LCP { + type string { + length "1..255"; + } + description "The local control plane name (OpenStack region name) of the provider"; + } + + /* + * Define a common definition of a time stamp (expressed as a formatted string) as follows + * + * yyyy-MM-dd HH:mm:ss.SSSSSSSS + * + * yyyy ...... exactly 4 digit year, e.g., 2015 + * MM ........ 1 or 2 digit month of year, e.g., 7 + * dd ........ 1 or 2 digit day of month, e.g., 29 + * HH ........ 1 or 2 digit hour of day (24-hour clock) in UTC, e.g., 17 + * mm ........ 1 or 2 digit minute of the hour, e.g. 31 + * ss ........ 1 or 2 digit seconds of the minute, e.g., 28 + * SSSSSS .... 1-6 digit microseconds + */ + typedef TIMESTAMP { + type string { + length "16..28"; + pattern "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}.[0-9]{1,6}"; + } + } + + typedef ZULU { + type string { + length "16..28"; + pattern "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}T[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}.[0-9]{1,6}Z"; + } + } + + typedef payload { + type string ; + description "The payload can be any valid JSON string value. Json escape characters need to be added when required to include an inner json within the payload to make it a valid json string value"; + } + + typedef action { + type enumeration { + enum "Restart"; + enum "Rebuild"; + enum "Migrate"; + enum "Evacuate"; + enum "Snapshot"; + enum "ModifyConfig"; + } + description "The action to be taken by APP-C, e.g. Test, Start, Terminate"; + } + + /********************************************************************************** + * All requests will include this standard header + * + * The standard request header is used to define a correlation identification for + * the request that is returned on all responses. This correlation identifier + * (called the service-request-id) is meaningful to the caller and is included on + * all responses from the services. + **********************************************************************************/ + grouping common-request-header { + description "A common header for all requests"; + container common-request-header { + leaf service-request-id { + description "An identifier meaningful to the caller to correlate all responses"; + type string; + mandatory true; + } + + leaf time-to-live { + description "The alloted time to perform the operation, in seconds. If the + operation cannot be completed in this amount of time, the operation is + aborted. If set to zero, no timeout exists and the operation will continue + until it completes or fails. If omitted, the default value of 0 is used."; + type uint32 { + range "0..86400"; + } + mandatory false; + } + } + } + + /********************************************************************************** + * Basic manipulation of a VNF (or VM) will typically include querying the current + * state, restarting, rebuilding, stopping, starting, etc. In all of these basic + * "state"-type operations, the services require the identification of the VNF to + * be operated on, and the region or LCP that contains that resource. This + * information is used across all of these services, so it has been defined as a + * common structure here and is referenced in the appropriate RPC definitions. + **********************************************************************************/ + grouping vnf-resource { + description "The data that uniquely identifies a virtual network function (or vm)"; + container vnf-resource { + leaf vm-id { + description "The UUID of the resource. For backwards compatibility, this can be + the self-link URL of the VM."; + type UUID; + mandatory true; + } + leaf identity-url { + description "The identity url used to access the resource"; + type UUID; + mandatory false; + } + leaf tenant-id { + description "The id of the provider tenant that owns the resource"; + type string; + mandatory false; + } + } + } + + /********************************************************************************** + * All responses will include this standard header + * + * The standard response header includes the time of completion as well as a + * success|failure indication + **********************************************************************************/ + grouping common-response-header { + description "A common header for all responses defining success or failure + and the time stamp when completed"; + container common-response-header { + leaf service-request-id { + description "An identifier meaningful to the caller to correlate all responses"; + type string; + } + leaf success { + description "True indicates the request was successful"; + type boolean; + } + leaf reason { + description "If success=false, the failure reason. Otherwise, undefined."; + type string; + } + leaf completed { + description "The formatted time stamp when the operation was completed."; + type TIMESTAMP; + } + leaf duration { + description "The amount of time used (in seconds) to process the request"; + type uint32; + } + } + } + + + /********************************************************************************** + * All requests/response will include this standard header + * + * The standard common header is used to define a correlation identification for + * the request that is returned on all responses. + **********************************************************************************/ + grouping common-header { + description "A common header for all APP-C requests"; + container common-header { + description "A common header for all APP-C requests"; + leaf timestamp { + description "timestamp is in ISO 8601 timestamp format ZULU offset"; + type ZULU; + mandatory true; + } + + leaf api-ver { + description "api-ver is the API version identifier. A given release of APPC should support all previous versions of APPC API (correlate with general requirements)"; + type string; + mandatory true; + } + + leaf originator-id { + description "originator-id an identifier of the calling system which can be used addressing purposes, i.e. returning asynchronous response to the proper destination over DMaaP (especially in case of multiple consumers of APP-C APIs)"; + type string; + mandatory true; + } + + leaf request-id { + description "UUID for the request ID. An OSS/BSS identifier for the request that caused the current action. Multiple API calls may be made with the same request-id The request-id shall be recorded throughout the operations on a single request"; + type string; + mandatory true; + } + + leaf sub-request-id { + description "Uniquely identifies a specific LCM action. It is persistent over the life-cycle of a single request"; + type string; + mandatory false; + } + + + /********************************************************************************** + * Flags are generic flags that apply to any and all commands, all are optional + * force = TRUE/FALSE - Execute command even if target is in unstable (i.e. locked, transiting, etc) state. Specific behaviour of forced commands varies, but implies cancellation of previous command and an override by the new command. The FALSE value is used by default. + * ttl = <0....N> - The timeout value for command execution, expressed in seconds + * mode = EXCLUSIVE/NORMAL - defines execution mode as follows: + * - EXCLUSIVE ? on encountering an exclusive command, the APP-C will: + * * Cease accepting additional command requests + * * Complete execution of outstanding commands + * * Execute the exclusive command to completion + * * Optionally report the result of the command + * * Optionally resume command acceptance and processing + * - NORMAL - Obverse of EXCLUSIVE, the default one. + **********************************************************************************/ + container flags { + description "Flags are generic flags that apply to any and all commands, all are optional"; + leaf mode { + type enumeration { + enum "EXCLUSIVE"; + enum "NORMAL"; + } + description "EXCLUSIVE (accept no queued requests on this VNF while processing) or NORMAL (queue other requests until complete)"; + mandatory false; + } + leaf force { + type enumeration { + enum "TRUE"; + enum "FALSE"; + } + description "TRUE/FALSE - Execute action even if target is in unstable (i.e. locked, transiting, etc.) state"; + mandatory false; + } + leaf ttl { + description "<0....N> - The timeout value (expressed in seconds) for action execution, between action being received by APPC and action initiation"; + type uint16; + mandatory false; + } + } + } + } + + grouping config-payload { + description "Payload for modify config on traffic generator"; + container config-payload { + description "Payload for modify config on traffic generator"; + leaf config-url { + description "this is the restconf interface for vTrafficGenerator"; + type string; + mandatory true; + } + + leaf config-json { + description "this is the configuration data"; + type string; + mandatory true; + } + } + } + + + grouping action-identifiers { + description "A block containing the action arguments. These are used to specify the object upon which APP-C LCM command is to operate"; + container action-identifiers { + description "A block containing the action arguments. These are used to specify the object upon which APP-C LCM command is to operate"; + leaf service-instance-id { + description "identifies a specific service the command refers to. When multiple APP-C instances are used and applied to a subset of services, this will become significant . The field is mandatory when the vnf-id is empty"; + type string; + mandatory false; + } + leaf vnf-id { + description "identifies the VNF to which this action is to be applied(vnf-id uniquely identifies the service-instance referred to). Note that some actions are applied to multiple VNFs in the same service. When this is the case, vnf-id may be left out, but service-instance-id must appear. The field is mandatory when service-instance-id is empty"; + type string; + mandatory false; + } + leaf vnfc-name { + description "identifies the VNFC to which this action is to be applied. Some actions apply only to a component within a VNF (e.g. RESTART is sometimes applied to on VM only). In such a case, the name of the VNFC is used to search for the component within the VNF"; + type string; + mandatory false; + } + leaf vserver-id { + description "identifies a specific VM within the given service/vnf to which this action is to be applied"; + type string; + mandatory false; + } + } + } + + grouping status { + description "The specific response codes are to be aligned with ASDC reference doc (main table removed to avoid duplication and digression from main table). See ASDC and ECOMP Distribution Consumer Interface Agreement"; + container status { + description "The specific response codes are to be aligned with ASDC reference doc (main table removed to avoid duplication and digression from main table). See ASDC and ECOMP Distribution Consumer Interface Agreement"; + leaf code { + description "Response code"; + type uint16; + mandatory true; + } + leaf message { + description "Response message"; + type string; + mandatory true; + } + } + } + + + /********************************************************************************** + * NEW API :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + * All requests will include this standard header + * + * The standard request header is used to define a correlation identification for + * the request that is returned on all responses. This correlation identifier + * (called the service-request-id) is meaningful to the caller and is included on + * all responses from the services. + **********************************************************************************/ + grouping RequestHeader { + container RequestHeader { + description "A common header for all APP-C requests"; + leaf TimeStamp { + description "TimeStamp is in ISO 8601 timestamp format ZULU offset"; + type TIMESTAMP; + mandatory true; + } + + leaf APIver { + description "APIver is the API version identifier. A given release of APPC should support all previous versions of APPC API (correlate with general requirements)"; + type string; + mandatory true; + } + + leaf OriginatorID { + description "OriginatorID an identifier of the calling system which can be used addressing purposes, i.e. returning asynchronous response to the proper destination over DMaaP (especially in case of multiple consumers of APP-C APIs)"; + type string; + mandatory true; + } + + leaf TransactionID { + description "Identifiers that may be generated when multiple responses or handling passes are needed for a given request, allowing the request itself to be tracked"; + type string; + mandatory true; + } + + leaf-list RequestTrack { + description "Identifiers that may be generated when multiple responses or handling passes are needed for a given request, allowing the request itself to be tracked"; + type string; + } + + /********************************************************************************** + * Flags are generic flags that apply to any and all commands, all are optional + * FORCE = TRUE/FALSE - Execute command even if target is in unstable (i.e. locked, transiting, etc) state. Specific behaviour of forced commands varies, but implies cancellation of previous command and an override by the new command. The FALSE value is used by default. + * TTL = <0....N> - The timeout value for command execution, expressed in seconds + * MODE = EXCLUSIVE/NORMAL - defines execution mode as follows: + * - EXCLUSIVE � on encountering an exclusive command, the APP-C will: + * * Cease accepting additional command requests + + * Complete execution of outstanding commands + * * Execute the exclusive command to completion + * * Optionally report the result of the command + * * Optionally resume command acceptance and processing + * - NORMAL - Obverse of EXCLUSIVE, the default one. + **********************************************************************************/ + container Flags { + description "Flags are generic flags that apply to any and all commands, all are optional"; + leaf FORCE { + description "TRUE/FALSE - Execute action even if target is in unstable (i.e. locked, transiting, etc) state."; + type string; + mandatory false; + } + leaf TTL { + description "<0....N> - The timeout value for action execution, expressed in seconds"; + type string; + mandatory false; + } + leaf MODE { + description "EXCLUSIVE/NORMAL - defines execution mode"; + type string; + mandatory false; + } + } + } + } + + grouping RequestParameters { + description "The request contains the entry of command-specific and is opaque to the APP-C handler"; + leaf Action { + description "The actual action to be taken"; + type string; + mandatory true; + } + leaf TargetID { + description "The specific VF a component of which is to be affected"; + type string; + mandatory true; + } + leaf ObjectID { + description "The specific VFC within a VF to be affected"; + type string; + mandatory true; + } + leaf Payload { + description "An action-specific value opaque to the APPC handler. + The value can be any valid JSON type (primitive, object, collection of those two). + APPC will pass the value as raw JSON string to the executing LCM action."; + type string; + mandatory true; + } + } + + grouping ResponseHeader { + description "The response to an APP-C command or control is, likewise, encoded in a JSON object. "; + container ResponseHeader { + description "The response to an APP-C command or control is, likewise, encoded in a JSON object. "; + leaf TimeStamp { + description "TimeStamp is in ISO 8601 timestamp format ZULU offset"; + type TIMESTAMP; + mandatory true; + } + + leaf APIver { + description "APIver is the API version identifier. A given release of APPC should support all previous versions of APPC API (correlate with general requirements)"; + type string; + mandatory true; + } + + leaf ResponseID { + description "ResponseID an identifier of the calling system which can be used addressing purposes, i.e. returning asynchronous response to the proper destination over DMaaP (especially in case of multiple consumers of APP-C APIs)"; + type string; + mandatory true; + } + + leaf-list SubResponseID { + description "Identifiers that may be generated when multiple responses or handling passes are needed for a given request, allowing the request itself to be tracked"; + type string; + } + } + } + + grouping ResponseAttributes { + description "The response contains the status of executed functionality"; + container Status { + description "The specific response codes are to be aligned with ASDC reference doc (main table removed to avoid duplication and digression from main table). See ASDC and ECOMP Distribution Consumer Interface Agreement"; + leaf Code { + description "Response code value"; + type uint32; + mandatory true; + } + leaf Value { + description "Response code description"; + type string; + mandatory true; + } + } + leaf Payload { + description "Payload - the entry is command-specific and is opaque to the APP-C handler. + The value can be any valid JSON type (primitive, object, collection of those two). + APP-C will pass the value as raw JSON string to appropriate addressee"; + type string; + mandatory false; + } + } + + + + + /********************************************************************************** + * Define the restart service + **********************************************************************************/ + rpc restart { + description "An operation to restart a virtual network function (or VM)"; + input { + uses common-request-header; + uses vnf-resource; + } + output { + uses common-response-header; + leaf vm-id { + description "The UUID of the VM that was restarted"; + type UUID; + } + } + } + + /********************************************************************************** + * Define the rebuild service + **********************************************************************************/ + rpc rebuild { + description "An operation to rebuild a virtual network function (or VM)"; + input { + uses common-request-header; + uses vnf-resource; + } + output { + uses common-response-header; + leaf new-vm-id { + description "The UUID of the VM after rebuild. If the UUID was changed, + this contains the new UUID. If it was not changed, this contains + the original UUID"; + type UUID; + } + leaf original-vm-id { + description "The UUID of the VM before rebuild (i.e., the original UUID)"; + type UUID; + } + } + } + + /********************************************************************************** + * Define the migrate service + **********************************************************************************/ + rpc migrate { + description "An operation to migrate a virtual network function (or VM)"; + input { + uses common-request-header; + uses vnf-resource; + } + output { + uses common-response-header; + leaf vm-id { + description "The UUID of the VM that was migrated."; + type UUID; + } + } + } + + /********************************************************************************** + * Define the evacuate service + **********************************************************************************/ + rpc evacuate { + description "An operation to evacuate a virtual network function (or VM)"; + input { + uses common-request-header; + uses vnf-resource; + } + output { + uses common-response-header; + leaf vm-id { + description "The UUID of the VM that was evacuated"; + type UUID; + } + } + } + + + /********************************************************************************** + * Define the snapshot service + **********************************************************************************/ + rpc snapshot { + description "An operation to create a snapshot of a virtual network function (or VM)"; + input { + uses common-request-header; + uses vnf-resource; + } + output { + uses common-response-header; + leaf vm-id { + description "The UUID of the VM that was snapshot"; + type UUID; + } + } + } + + rpc ModifyConfig { + description "An operation to modify-config the configurations of a virtual network function (or VM)"; + input { + uses common-request-header; + uses config-payload; + leaf action { + type action; + mandatory true; + } + } + output { + uses common-response-header; + } + } + + +} diff --git a/app-c/appc/appc-provider/features/.gitignore b/app-c/appc/appc-provider/features/.gitignore new file mode 100644 index 000000000..ae3c17260 --- /dev/null +++ b/app-c/appc/appc-provider/features/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/app-c/appc/appc-provider/pom.xml b/app-c/appc/appc-provider/pom.xml new file mode 100644 index 000000000..9584aa23b --- /dev/null +++ b/app-c/appc/appc-provider/pom.xml @@ -0,0 +1,24 @@ +<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"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-provider</artifactId> + <packaging>pom</packaging> + <name>APPC Provider</name> + <description>The app-c service provider bundle</description> + <properties> + <feature-name>appc-provider</feature-name> + </properties> + <!-- ================================================================================== --> + <!-- The modules we build --> + <!-- ================================================================================== --> + <modules> + <module>appc-provider-model</module> + <module>appc-provider-features</module> + <module>appc-provider-installer</module> + <module>appc-provider-bundle</module> + </modules> +</project>
\ No newline at end of file diff --git a/app-c/appc/appc-provider/provider/.gitignore b/app-c/appc/appc-provider/provider/.gitignore new file mode 100644 index 000000000..ae3c17260 --- /dev/null +++ b/app-c/appc/appc-provider/provider/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/app-c/appc/design/appc.eap b/app-c/appc/design/appc.eap Binary files differnew file mode 100644 index 000000000..741f78027 --- /dev/null +++ b/app-c/appc/design/appc.eap diff --git a/app-c/appc/jenkins-settings.xml b/app-c/appc/jenkins-settings.xml new file mode 100644 index 000000000..7f8f637a9 --- /dev/null +++ b/app-c/appc/jenkins-settings.xml @@ -0,0 +1,171 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- vi: set et smarttab sw=2 tabstop=2: --> +<!-- + Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved. + + This program and the accompanying materials are made available under the + terms of the Eclipse Public License v1.0 which accompanies this distribution, + and is available at http://www.eclipse.org/legal/epl-v10.html +--> +<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> + <profiles> + <!-- NOTE: The ecomp.nexus.url and port will need to be replaced or + defined as properties in your build enviornment. --> + <profile> + <id>openecomp-release</id> + <repositories> + <repository> + <id>openecomp-release</id> + <name>openecomp-release</name> + <url>https://${ecomp.nexus.url}:${ecomp.nexus.port}/repository/maven-releases/</url> + <releases> + <enabled>true</enabled> + <updatePolicy>never</updatePolicy> + </releases> + <snapshots> + <enabled>false</enabled> + </snapshots> + </repository> + </repositories> + <pluginRepositories> + <pluginRepository> + <id>openecomp-release</id> + <name>openecomp-release</name> + <url>https://${ecomp.nexus.url}:${ecomp.nexus.port}/repository/maven-releases/</url> + <releases> + <enabled>true</enabled> + <updatePolicy>never</updatePolicy> + </releases> + <snapshots> + <enabled>false</enabled> + </snapshots> + </pluginRepository> + </pluginRepositories> + </profile> + <profile> + <id>openecomp-snapshots</id> + <repositories> + <repository> + <id>openecomp-snapshot</id> + <name>openecomp-snapshot</name> + <url>https://${ecomp.nexus.url}:${ecomp.nexus.port}/repository/maven-snapshots/</url> + <releases> + <enabled>false</enabled> + </releases> + <snapshots> + <enabled>true</enabled> + </snapshots> + </repository> + </repositories> + <pluginRepositories> + <pluginRepository> + <id>openecomp-snapshot</id> + <name>openecomp-snapshot</name> + <url>https://${ecomp.nexus.url}:${ecomp.nexus.port}/repository/maven-snapshots/</url> + <releases> + <enabled>false</enabled> + </releases> + <snapshots> + <enabled>true</enabled> + </snapshots> + </pluginRepository> + </pluginRepositories> + </profile> + <profile> + <id>opendaylight-release</id> + <repositories> + <repository> + <id>opendaylight-mirror</id> + <name>opendaylight-mirror</name> + <url>https://nexus.opendaylight.org/content/repositories/public/</url> + <releases> + <enabled>true</enabled> + <updatePolicy>never</updatePolicy> + </releases> + <snapshots> + <enabled>false</enabled> + </snapshots> + </repository> + </repositories> + <pluginRepositories> + <pluginRepository> + <id>opendaylight-mirror</id> + <name>opendaylight-mirror</name> + <url>https://nexus.opendaylight.org/content/repositories/public/</url> + <releases> + <enabled>true</enabled> + <updatePolicy>never</updatePolicy> + </releases> + <snapshots> + <enabled>false</enabled> + </snapshots> + </pluginRepository> + </pluginRepositories> + </profile> + <profile> + <id>opendaylight-snapshots</id> + <repositories> + <repository> + <id>opendaylight-snapshot</id> + <name>opendaylight-snapshot</name> + <url>https://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url> + <releases> + <enabled>false</enabled> + </releases> + <snapshots> + <enabled>true</enabled> + </snapshots> + </repository> + </repositories> + <pluginRepositories> + <pluginRepository> + <id>opendaylight-snapshot</id> + <name>opendaylight-snapshot</name> + <url>https://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url> + <releases> + <enabled>false</enabled> + </releases> + <snapshots> + <enabled>true</enabled> + </snapshots> + </pluginRepository> + </pluginRepositories> + </profile> + </profiles> + <activeProfiles> + <activeProfile>openecomp-release</activeProfile> + <activeProfile>openecomp-snapshots</activeProfile> + <activeProfile>opendaylight-release</activeProfile> + <activeProfile>opendaylight-snapshots</activeProfile> + </activeProfiles> + <servers> + <!-- NOTE: The ecomp.nexus.user and password will need to be replaced or + defined as properties in your build enviornment. --> + <server> + <id>nexus</id> + <username>${ecomp.nexus.user}</username> + <password>${ecomp.nexus.password}</password> + </server> + <server> + <id>openecomp-release</id> + <username>${ecomp.nexus.user}</username> + <password>${ecomp.nexus.password}</password> + </server> + <server> + <id>openecomp-snapshot</id> + <username>${ecomp.nexus.user}</username> + <password>${ecomp.nexus.password}</password> + </server> + <server> + <id>openecomp-public</id> + <username>${ecomp.nexus.user}</username> + <password>${ecomp.nexus.password}</password> + </server> + <!-- Javadocs Server --> + <server> + <id>app-c-javadoc</id> + <username>${ecomp.nexus.user}</username> + <password>${ecomp.nexus.password}</password> + </server> + </servers> +</settings>
\ No newline at end of file diff --git a/app-c/appc/pom.xml b/app-c/appc/pom.xml new file mode 100644 index 000000000..2bb5b69f3 --- /dev/null +++ b/app-c/appc/pom.xml @@ -0,0 +1,743 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>root</artifactId> + <version>1.0.0</version> + </parent> + <packaging>pom</packaging> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc</artifactId> + <version>1.0.0</version> + <name>APP-C</name> + <description>Construct the Application Controller component for the ECOMP project.</description> + <inceptionYear>2015-07-20</inceptionYear> + <organization> + <name>OpenECOMP</name> + </organization> + <!-- ================================================================================== --> + <!-- Configuration properties --> + <!-- ================================================================================== --> + <properties> + <features-mdsal.version>2.0.2-Beryllium-SR2</features-mdsal.version> + <broker-mdsal.version>1.3.2-Beryllium-SR2</broker-mdsal.version> + <!-- Properties from parent pom --> + <!-- <release-tag>R17.01</release-tag> --> + <!-- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> --> + <!-- <bundle.plugin.version>2.5.0</bundle.plugin.version> --> + <!-- <java.version.source>1.7</java.version.source> --> + <!-- <java.version.target>1.7</java.version.target> --> + <!-- <maven.compile.plugin.version>2.5.1</maven.compile.plugin.version> --> + <!-- <equinox.osgi.version>3.8.1.v20120830-144521</equinox.osgi.version> --> + <!-- <jackson-annotations-version>${jackson.version}</jackson-annotations-version> --> + <!-- <jettison.version>1.3.7</jettison.version> --> + <!-- <jvnet.jaxb2.version>0.6.4</jvnet.jaxb2.version> --> + <!-- <apache.httpcomponents.version>4.4</apache.httpcomponents.version> --> + <!-- <antlr.version>4.5.1</antlr.version> --> + <!-- <mysql.connector.version>5.1.39</mysql.connector.version> --> + <!-- <odl.version>1.6.2-Beryllium-SR2</odl.version> --> + <!-- <odl.dlux.version>0.3.2-Beryllium-SR2</odl.dlux.version> --> + <odl.yangtools.version>0.8.2-Beryllium-SR2</odl.yangtools.version> + <!-- <odl.mdsal.version>1.3.2-Beryllium-SR2</odl.mdsal.version> --> + <!-- <odl.mdsal.features.version>2.0.2-Beryllium-SR2</odl.mdsal.features.version> --> + <!-- <odl.mdsal.model.version>0.8.2-Beryllium-SR2</odl.mdsal.model.version> --> + <!-- <odl.restconf.version>1.3.2-Beryllium-SR2</odl.restconf.version> --> + <!-- <odl.yangtools.version>0.8.2-Beryllium-SR2</odl.yangtools.version> --> + <!-- <odl.controller.model.version>${odl.mdsal.model.version}</odl.controller.model.version> --> + <!-- <odl.controller.config.api.version>0.4.2-Beryllium-SR2</odl.controller.config.api.version> --> + <!-- <odl.karaf.empty.distro.version>${odl.version}</odl.karaf.empty.distro.version> --> + <!-- <odl.commons.opendaylight.version>${odl.version}</odl.commons.opendaylight.version> --> + <!-- <odl.ietf-inet-types.version>2010.09.24.8.2-Beryllium-SR2</odl.ietf-inet-types.version> --> + <!-- <odl.ietf-yang-types.version>2010.09.24.8.2-Beryllium-SR2</odl.ietf-yang-types.version> --> + <!-- <odl.yang.jmx.generator.version>0.4.2-Beryllium-SR2</odl.yang.jmx.generator.version> --> + <!-- <odl.yangtools.yang.maven.plugin.version>${odl.yangtools.version}</odl.yangtools.yang.maven.plugin.version> --> + <!-- <features.file>features.xml</features.file> --> + <!-- <h2database.version>1.4.186</h2database.version> --> + <!-- <jmxGeneratorPath>src/main/yang-gen-config</jmxGeneratorPath> --> + <!-- <salGeneratorPath>src/main/yang-gen-sal</salGeneratorPath> --> + <!-- <checkstyle.skip>true</checkstyle.skip> --> + <!--<sdnc.core.version>(0.0.1,1.9.9]</sdnc.core.version> --> + <!-- <sdnc.adaptors.version>(0.0.1,1.9.9]</sdnc.adaptors.version> --> + <!-- <sdnctl.aai.service.version>${sdnc.adaptors.version}</sdnctl.aai.service.version> --> + <!-- <sdnctl.dblib.version>${sdnc.core.version}</sdnctl.dblib.version> --> + <!-- <sdnctl.mdsal.resource.version>${sdnc.adaptors.version}</sdnctl.mdsal.resource.version> --> + <!-- <sdnctl.slipluginutils.version>${sdnc.core.version}</sdnctl.slipluginutils.version> --> + <!-- Sonar Properties --> + <sonar.language>java</sonar.language> + <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin> + <sonar.surefire.reportsPath>${project.build.directory}/surefire-reports</sonar.surefire.reportsPath> + <sonar.jacoco.reportPath>${project.build.directory}/coverage-reports/jacoco.exec</sonar.jacoco.reportPath> + <sonar.jacoco.reportMissing.force.zero>true</sonar.jacoco.reportMissing.force.zero> + <sonar.projectVersion>${project.version}</sonar.projectVersion> + <cdp.pal.version>0.0.1</cdp.pal.version> + <eelf.version>0.0.1</eelf.version> + <eelf.maven.plugin.version>0.0.1</eelf.maven.plugin.version> + <cadi-version>1.3.0</cadi-version> + <inno-version>1.2.11</inno-version> + <dme2-version>3.1.200</dme2-version> + <cambriaClient-version>0.0.1</cambriaClient-version> + <!-- OPENECOMP SDNC versions --> + <sdnctl.sli.version>1.0.0</sdnctl.sli.version> + <!--<sdnctl.sli.version>${sdnc.core.version}</sdnctl.sli.version> --> + <sdnctl.dblib.version>1.0.0</sdnctl.dblib.version> + <sdnctl.aai.service.version>1.0.0</sdnctl.aai.service.version> + <!-- <jmxGeneratorPath>target/generated-sources/yang-gen-config</jmxGeneratorPath> --> + <salGeneratorPath>target/generated-sources/yang-gen-sal</salGeneratorPath> + <!-- <OpenStack-API-version>3.3.4</OpenStack-API-version> --> + <!-- <commons.lang3.version>3.4</commons.lang3.version> --> + <commons.io.version>${commons.lang3.version}</commons.io.version> + <!-- <odl.aaa.version>0.3.2-Beryllium-SR2</odl.aaa.version> --> + <!-- <odl.bgpcep.version>0.5.2-Beryllium-SR2</odl.bgpcep.version> --> + <!-- <odl.branding.version>1.2.2-Beryllium-SR2</odl.branding.version> --> + <!-- <odl.commons.opendaylight.version>1.6.2-Beryllium-SR2</odl.commons.opendaylight.version> --> + <!-- <odl.config.parent.version>0.4.2-Beryllium-SR2</odl.config.parent.version> --> + <!-- <odl.config.version>0.4.2-Beryllium-SR2</odl.config.version> --> + <!-- <odl.controller.model.version>1.3.2-Beryllium-SR2</odl.controller.model.version> --> + <!-- <odl.dlux.version>0.3.2-Beryllium-SR2</odl.dlux.version> --> + <!-- <odl.features.protocol.framework.version>0.7.2-Beryllium-SR2</odl.features.protocol.framework.version> --> + <!-- <odl.ganymed.version>1.3.2-Beryllium-SR2</odl.ganymed.version> --> + <!-- <odl.ietf-inet-types.version>2010.09.24.8.2-Beryllium-SR2</odl.ietf-inet-types.version> --> + <!-- <odl.ietf-ted.version>2013.10.21.8.2-Beryllium-SR2</odl.ietf-ted.version> --> + <!-- <odl.ietf-topology-isis.version>2013.10.21.8.2-Beryllium-SR2</odl.ietf-topology-isis.version> --> + <!-- <odl.ietf-topology.version>2013.10.21.8.2-Beryllium-SR2</odl.ietf-topology.version> --> + <!-- <odl.ietf-yang-types.version>2010.09.24.8.2-Beryllium-SR2</odl.ietf-yang-types.version> --> + <!-- <odl.karaf.distro.empty.version>1.6.2-Beryllium-SR2</odl.karaf.distro.empty.version> --> + <!-- <odl.karaf.empty.distro.version>1.6.2-Beryllium-SR2</odl.karaf.empty.distro.version> --> + <!-- <odl.karaf.resources.version>1.6.2-Beryllium-SR2</odl.karaf.resources.version> --> + <!-- <odl.l2-types.model.version>2013.08.27.8.2-Beryllium-SR2</odl.l2-types.model.version> --> + <!-- <odl.l2switch.version>0.3.2-Beryllium-SR2</odl.l2switch.version> --> + <!-- <odl.controller.mdsal.version>1.3.2-Beryllium-SR2</odl.controller.mdsal.version> --> + <!-- <odl.mdsal.version>2.0.2-Beryllium-SR2</odl.mdsal.version> --> + <!-- <odl.mdsal.apidoc.version>1.3.2-Beryllium-SR2</odl.mdsal.apidoc.version> --> + <!-- <odl.sal.clustering.conf.version>1.3.2-Beryllium-SR2</odl.sal.clustering.conf.version> --> + <!-- <odl.net.sf.jung2.version>2.0.1</odl.net.sf.jung2.version> --> + <!-- <odl.netconf.parent.version>1.0.2-Beryllium-SR2</odl.netconf.parent.version> --> + <!-- <odl.neutron.version>0.6.2-Beryllium-SR2</odl.neutron.version> --> + <!-- <odl.openflowjava.version>0.7.2-Beryllium-SR2</odl.openflowjava.version> --> + <!-- <odl.openflowplugin.version>0.2.2-Beryllium-SR2</odl.openflowplugin.version> --> + <!-- <odl.pax.cdi.version>0.11.0</odl.pax.cdi.version> --> + <!-- <odl.restconf.version>1.3.2-Beryllium-SR2</odl.restconf.version> --> + <!-- <odl.sal.api.version>0.10.2-Beryllium-SR2</odl.sal.api.version> --> + <!-- <odl.sal.connection.api.version>0.3.2-Beryllium-SR2</odl.sal.connection.api.version> --> + <!-- <odl.sal.rest.docgen.version>1.3.2-Beryllium-SR2</odl.sal.rest.docgen.version> --> + <!-- <odl.yang.jmx.generator.version>0.4.2-Beryllium-SR2</odl.yang.jmx.generator.version> --> + <!-- <odl.yangtools.version>0.8.2-Beryllium-SR2</odl.yangtools.version> --> + <maven.javadoc.failOnError>false</maven.javadoc.failOnError> + <!-- ADDING TO SUPPORT APPC-PROVIDER-MODEL yang-gen-sal FOLDER + GENERATION --> + <yang.file.directory>src/main/yang</yang.file.directory> + </properties> + <!-- ================================================================================== --> + <!-- Javadoc Generation Plugin --> + <!-- ================================================================================== --> + <reporting> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>2.10.4</version> + <configuration> + <excludePackageNames>org.openecomp.sdnc</excludePackageNames> + <failOnError>false</failOnError> + <doclet>org.umlgraph.doclet.UmlGraphDoc</doclet> + <docletArtifact> + <groupId>org.umlgraph</groupId> + <artifactId>umlgraph</artifactId> + <version>5.6</version> + </docletArtifact> + <additionalparam>-views</additionalparam> + <useStandardDocletOptions>true</useStandardDocletOptions> + </configuration> + </plugin> + </plugins> + </reporting> + <!-- ================================================================================== --> + <!-- Distribution Management Sites--> + <!-- ================================================================================== --> + <distributionManagement> + <!-- This site is used for Javadocs --> + <site> + <id>app-c-javadoc</id> + <url>dav:https://ecomp-nexus:8443/repository/app-c-javadoc/${project.version}</url> + </site> + </distributionManagement> + <!-- ================================================================================== --> + <!-- The SCM repository we are using --> + <!-- ================================================================================== --> + <!-- <scm> + <connection></connection> + <developerConnection></developerConnection> + <url></url> + <tag></tag> + </scm> --> + <!-- ================================================================================== --> + <!-- Define plugin repositories --> + <!-- ================================================================================== --> + <pluginRepositories> + <pluginRepository> + <id>opendaylight-mirror</id> + <name>opendaylight-mirror</name> + <url>https://nexus.opendaylight.org/content/repositories/public/</url> + <releases> + <enabled>true</enabled> + <updatePolicy>never</updatePolicy> + </releases> + <snapshots> + <enabled>false</enabled> + </snapshots> + </pluginRepository> + <pluginRepository> + <id>opendaylight-snapshot</id> + <name>opendaylight-snapshot</name> + <url>https://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url> + <releases> + <enabled>false</enabled> + </releases> + <snapshots> + <enabled>true</enabled> + </snapshots> + </pluginRepository> + <!-- Black Duck plugin dependencies --> + <pluginRepository> + <id>JCenter</id> + <name>JCenter Repository</name> + <url>http://jcenter.bintray.com</url> + </pluginRepository> + <pluginRepository> + <id>Restlet</id> + <name>Restlet Repository</name> + <url>http://maven.restlet.com</url> + </pluginRepository> + </pluginRepositories> + <!-- ================================================================================== --> + <!-- Define project-wide dependencies --> + <!-- ================================================================================== --> + <dependencyManagement> + <dependencies> + <!-- ODL --> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>config-api</artifactId> + <version>${odl.controller.config.api.version}</version> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-config</artifactId> + <!-- <version>1.3.2-Beryllium-SR2</version> --> + <version>${odl.mdsal.version}</version> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-api</artifactId> + <version>${odl.mdsal.version}</version> + <!-- <version>1.3.2-Beryllium-SR2</version> --> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-test-model</artifactId> + <!-- <version>1.3.2-Beryllium-SR2</version> --> + <version>${odl.mdsal.version}</version> + </dependency> + <dependency> + <groupId>org.opendaylight.netconf</groupId> + <artifactId>sal-rest-connector</artifactId> + <!-- <version>1.3.2-Beryllium-SR2</version> --> + <version>${odl.mdsal.version}</version> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-broker-impl</artifactId> + <!-- <version>1.3.2-Beryllium-SR2</version> --> + <version>${odl.mdsal.version}</version> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-common-util</artifactId> + <version>${odl.mdsal.version}</version> + <!-- <version>1.3.2-Beryllium-SR2</version> --> + </dependency> + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>yang-binding</artifactId> + <version>${odl.yangtools.version}</version> + </dependency> + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>yang-common</artifactId> + <version>${odl.yangtools.version}</version> + </dependency> + <dependency> + <groupId>org.opendaylight.mdsal.model</groupId> + <artifactId>ietf-inet-types</artifactId> + <version>${odl.ietf-inet-types.version}</version> + </dependency> + <dependency> + <groupId>org.opendaylight.mdsal.model</groupId> + <artifactId>ietf-yang-types</artifactId> + <version>${odl.ietf-yang-types.version}</version> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>features-mdsal</artifactId> + <version>1.3.2-Beryllium-SR2</version> + <classifier>features</classifier> + <type>xml</type> + </dependency> + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>features-mdsal</artifactId> + <version>2.0.2-Beryllium-SR2</version> + <classifier>features</classifier> + <type>xml</type> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>opendaylight-karaf-empty</artifactId> + <version>${odl.karaf.empty.distro.version}</version> + <type>zip</type> + </dependency> + <!-- CURRENTLY DOES NOT EXIST IN 3.0. Replacement? --> + <!-- Required for launching the feature tests --> + <!-- <dependency> --> + <!-- <groupId>org.opendaylight.yangtools</groupId> --> + <!-- <artifactId>features-test</artifactId> --> + <!-- <version>${odl.yangtools.version}</version> --> + <!-- <scope>test</scope> --> + <!-- </dependency> --> + <!-- YANG tools --> + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>features-yangtools</artifactId> + <version>${odl.yangtools.version}</version> + <classifier>features</classifier> + <type>xml</type> + </dependency> + <!-- SDNC --> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <version>${sdnctl.sli.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + <version>${sdnctl.sli.version}</version> + </dependency> + <!-- dblib --> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + <version>${sdnctl.dblib.version}</version> + </dependency> + <!-- A&AI service provider dependency override in order to use a stable + version --> + <dependency> + <groupId>org.openecomp.sdnc.adaptors</groupId> + <artifactId>aai-service-provider</artifactId> + <version>${sdnctl.aai.service.version}</version> + </dependency> + <!-- APPC --> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-controller-features</artifactId> + <classifier>features</classifier> + <type>xml</type> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-controller-model</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-controller-bundle</artifactId> + <version>${project.version}</version> + <classifier>config</classifier> + <type>xml</type> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-controller-bundle</artifactId> + <version>${project.version}</version> + </dependency> + <!-- OTHER --> + <dependency> + <groupId>equinoxSDK381</groupId> + <artifactId>org.eclipse.osgi</artifactId> + <version>${equinox.osgi.version}</version> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + <version>${commons.lang3.version}</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-core</artifactId> + <version>1.1.1</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + <version>1.1.1</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>1.7.12</version> + </dependency> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <version>2.6</version> + </dependency> + <dependency> + <groupId>org.apache.sshd</groupId> + <artifactId>sshd-core</artifactId> + <version>0.12.0</version> + </dependency> + <dependency> + <groupId>javax.jms</groupId> + <artifactId>jms</artifactId> + <version>1.1</version> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <version>1.10.19</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.att.nsa</groupId> + <artifactId>cambriaClient</artifactId> + <version>${cambriaClient-version}</version> + </dependency> + <dependency> + <groupId>com.att.nsa</groupId> + <artifactId>saClientLibrary</artifactId> + <version>${cambriaClient-version}</version> + </dependency> + <!-- CDP --> + <dependency> + <groupId>com.att.cdp</groupId> + <artifactId>cdp-pal-common</artifactId> + <version>${cdp.pal.version}</version> + </dependency> + <dependency> + <groupId>com.att.cdp</groupId> + <artifactId>cdp-pal-openstack</artifactId> + <version>${cdp.pal.version}</version> + </dependency> + <!-- <dependency> --> + <!-- <groupId>com.att.cdp</groupId> --> + <!-- <artifactId>cdp-common</artifactId> --> + <!-- <version>${cdp.version}</version> --> + <!-- </dependency> --> + <!-- Cadi --> + <dependency> + <groupId>com.att.cadi</groupId> + <artifactId>cadi-aaf</artifactId> + <version>${cadi-version}</version> + </dependency> + <dependency> + <groupId>com.att.cadi</groupId> + <artifactId>cadi-client</artifactId> + <version>${cadi-version}</version> + </dependency> + <dependency> + <groupId>com.att.cadi</groupId> + <artifactId>cadi-core</artifactId> + <version>${cadi-version}</version> + </dependency> + <dependency> + <groupId>com.att.inno</groupId> + <artifactId>env</artifactId> + <version>${inno-version}</version> + </dependency> + <dependency> + <groupId>com.att.inno</groupId> + <artifactId>rosetta</artifactId> + <version>${inno-version}</version> + </dependency> + <dependency> + <groupId>com.att.aft.discovery</groupId> + <artifactId>discovery-clt</artifactId> + <version>5.1.3-01</version> + </dependency> + <dependency> + <groupId>com.att.aft</groupId> + <artifactId>dme2</artifactId> + <version>${dme2-version}</version> + </dependency> + <dependency> + <groupId>com.att.authz</groupId> + <artifactId>authz-client</artifactId> + <version>2.3</version> + <!-- We need to supply a modified jar WITHOUT Example.class in the jar + root for BND to build --> + <!-- <scope>system</scope> --> + <!-- <systemPath>${basedir}/lib/authz-client-2.3-modified.jar</systemPath> --> + </dependency> + <!-- EELF logging framework --> + <dependency> + <groupId>com.att.eelf</groupId> + <artifactId>eelf-core</artifactId> + <version>${eelf.version}</version> + </dependency> + </dependencies> + </dependencyManagement> + <!-- ================================================================================== --> + <!-- Define common plugins and make them available for all modules --> + <!-- ================================================================================== --> + <build> + <pluginManagement> + <plugins> + <!-- Define the site plugin to generate documentation --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-site-plugin</artifactId> + <version>3.4</version> + <dependencies> + <!-- add support for ssh/scp --> + <dependency> + <groupId>org.apache.maven.wagon</groupId> + <artifactId>wagon-ssh</artifactId> + <version>1.0</version> + </dependency> + </dependencies> + </plugin> + <!-- Define the compiler plugin --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${maven.compile.plugin.version}</version> + <configuration> + <source>${java.version.source}</source> + <target>${java.version.target}</target> + </configuration> + </plugin> + <!-- Define the javadoc plugin --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>2.10</version> + <configuration> + <excludePackageNames>org.opendaylight.*:org.openecomp.sdnc</excludePackageNames> + </configuration> + </plugin> + <!-- Define the source plugin --> + <plugin> + <artifactId>maven-source-plugin</artifactId> + <version>2.1.1</version> + </plugin> + <!-- Resources plugin --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-release-plugin</artifactId> + <version>2.5.2</version> + <configuration> + <goals>-s ${mvn.settings} deploy</goals> + </configuration> + </plugin> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.5.5</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-deploy-plugin</artifactId> + <version>2.8.1</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <version>2.10</version> + </plugin> + <!-- Maven surefire plugin for testing --> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.17</version> + </plugin> + <!-- Maven OSGi bundle plugin used to package OSGi bundles --> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <version>${bundle.plugin.version}</version> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <version>1.9.1</version> + </plugin> + <!-- SonarQube plugin --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>sonar-maven-plugin</artifactId> + <version>3.2</version> + </plugin> + </plugins> + </pluginManagement> + <plugins> + <!-- Javadocs Plugin --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-site-plugin</artifactId> + <version>3.6</version> + <dependencies> + <dependency> + <groupId>org.apache.maven.wagon</groupId> + <artifactId>wagon-webdav-jackrabbit</artifactId> + <version>2.10</version> + </dependency> + </dependencies> + </plugin> + <!-- license plugin --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>license-maven-plugin</artifactId> + <version>1.10</version> + <configuration> + <addJavaLicenseAfterPackage>false</addJavaLicenseAfterPackage> + <processStartTag>============LICENSE_START=======================================================</processStartTag> + <processEndTag>============LICENSE_END=========================================================</processEndTag> + <sectionDelimiter>================================================================================</sectionDelimiter> + <licenseName>apache_v2</licenseName> + <inceptionYear>2017</inceptionYear> + <organizationName>AT&T Intellectual Property. All rights + reserved.</organizationName> + <projectName>openECOMP : APP-C</projectName> + <canUpdateCopyright>true</canUpdateCopyright> + <canUpdateDescription>true</canUpdateDescription> + <canUpdateLicense>true</canUpdateLicense> + <emptyLineAfterHeader>true</emptyLineAfterHeader> + </configuration> + <executions> + <execution> + <id>first</id> + <goals> + <goal>update-file-header</goal> + </goals> + <phase>process-sources</phase> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>properties-maven-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>set-system-properties</goal> + </goals> + <configuration> + <properties> + <property> + <name>maven.wagon.http.ssl.allowall</name> + <value>${ssl.allowall}</value> + </property> + <property> + <name>maven.wagon.http.ssl.insecure</name> + <value>${ssl.insecure}</value> + </property> + </properties> + </configuration> + </execution> + </executions> + </plugin> + <!-- blackduck maven plugin --> + <!-- + <plugin> + <groupId>com.blackducksoftware.integration</groupId> + <artifactId>hub-maven-plugin</artifactId> + <version>1.4.0</version> + <inherited>false</inherited> + <configuration> + <hubProjectName>${project.name}</hubProjectName> + <outputDirectory>${project.basedir}</outputDirectory> + </configuration> + <executions> + <execution> + <id>create-bdio-file</id> + <phase>package</phase> + <goals> + <goal>createHubOutput</goal> + </goals> + </execution> + </executions> + </plugin> + --> + </plugins> + </build> + <!-- ================================================================================== --> + <!-- The modules we build every time --> + <!-- ================================================================================== --> + <modules> + <module>appc-common</module> + </modules> + <!-- Adding profiles for testing --> + <profiles> + <profile> + <id>appc-core</id> + <properties> + <ssl.allowall>true</ssl.allowall> + <ssl.insecure>true</ssl.insecure> + <openecomp.nexus.host>ecomp-nexus</openecomp.nexus.host> + <openecomp.nexus.release-url>https://${openecomp.nexus.host}:8443/repository/maven-releases/</openecomp.nexus.release-url> + <openecomp.nexus.snapshot-url>https://${openecomp.nexus.host}:8443/repository/maven-snapshots/</openecomp.nexus.snapshot-url> + <openecomp.git.port>7999</openecomp.git.port> + <openecomp.git.project>st_osecomp</openecomp.git.project> + <openecomp.git.protocol>http</openecomp.git.protocol> + </properties> + <!-- Core app-c from 1604 --> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + <modules> + <module>appc-common</module> + <module>appc-adapters</module> + <module>appc-provider</module> + <module>appc-event-listener</module> + <module>appc-asdc-listener</module> + </modules> + </profile> + <profile> + <id>request-dispatcher</id> + <properties> + <ssl.allowall>true</ssl.allowall> + <ssl.insecure>true</ssl.insecure> + </properties> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + <modules> + <module>appc-dispatcher</module> + <module>appc-metric</module> + <module>appc-dg</module> + <module>appc-dg-util</module> + </modules> + </profile> + </profiles> +</project>
\ No newline at end of file |