diff --git a/.bsp/sbt.json b/.bsp/sbt.json
new file mode 100644
index 0000000..7c86a39
--- /dev/null
+++ b/.bsp/sbt.json
@@ -0,0 +1 @@
+{"name":"sbt","version":"1.7.1","bspVersion":"2.0.0-M5","languages":["scala"],"argv":["/home/jgall/.jabba/jdk/openjdk@1.17.0/bin/java","-Xms100m","-Xmx100m","-classpath","/home/jgall/bin/sbt-lib/bin/sbt-launch.jar","-Dsbt.script=/home/jgall/bin/sbt","xsbt.boot.Boot","-bsp"]}
\ No newline at end of file
diff --git a/.cproject b/.cproject
new file mode 100644
index 0000000..3b2bb16
--- /dev/null
+++ b/.cproject
@@ -0,0 +1,600 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ make
+
+ all
+ true
+ true
+ false
+
+
+ make
+
+ am--refresh
+ true
+ true
+ false
+
+
+ make
+
+ check
+ true
+ true
+ false
+
+
+ make
+
+ clean
+ true
+ true
+ false
+
+
+ make
+
+ clean-libtool
+ true
+ true
+ false
+
+
+ make
+
+ config.h
+ true
+ true
+ false
+
+
+ make
+
+ ctags
+ true
+ true
+ false
+
+
+ make
+
+ ctags-recursive
+ true
+ true
+ false
+
+
+ make
+
+ dist
+ true
+ true
+ false
+
+
+ make
+
+ dist-all
+ true
+ true
+ false
+
+
+ make
+
+ dist-bzip2
+ true
+ true
+ false
+
+
+ make
+
+ dist-gzip
+ true
+ true
+ false
+
+
+ make
+
+ dist-lzma
+ true
+ true
+ false
+
+
+ make
+
+ dist-shar
+ true
+ true
+ false
+
+
+ make
+
+ dist-tarZ
+ true
+ true
+ false
+
+
+ make
+
+ dist-zip
+ true
+ true
+ false
+
+
+ make
+
+ distcheck
+ true
+ true
+ false
+
+
+ make
+
+ distclean
+ true
+ true
+ false
+
+
+ make
+
+ distclean-hdr
+ true
+ true
+ false
+
+
+ make
+
+ distclean-libtool
+ true
+ true
+ false
+
+
+ make
+
+ distclean-tags
+ true
+ true
+ false
+
+
+ make
+
+ distcleancheck
+ true
+ true
+ false
+
+
+ make
+
+ distdir
+ true
+ true
+ false
+
+
+ make
+
+ distuninstallcheck
+ true
+ true
+ false
+
+
+ make
+
+ dvi
+ true
+ true
+ false
+
+
+ make
+
+ html
+ true
+ true
+ false
+
+
+ make
+
+ info
+ true
+ true
+ false
+
+
+ make
+
+ install
+ true
+ true
+ false
+
+
+ make
+
+ install-data
+ true
+ true
+ false
+
+
+ make
+
+ install-dvi
+ true
+ true
+ false
+
+
+ make
+
+ install-exec
+ true
+ true
+ false
+
+
+ make
+
+ install-exec-hook
+ true
+ true
+ false
+
+
+ make
+
+ install-html
+ true
+ true
+ false
+
+
+ make
+
+ install-info
+ true
+ true
+ false
+
+
+ make
+
+ install-man
+ true
+ true
+ false
+
+
+ make
+
+ install-pdf
+ true
+ true
+ false
+
+
+ make
+
+ install-ps
+ true
+ true
+ false
+
+
+ make
+
+ install-strip
+ true
+ true
+ false
+
+
+ make
+
+ installcheck
+ true
+ true
+ false
+
+
+ make
+
+ installdirs
+ true
+ true
+ false
+
+
+ make
+
+ maintainer-clean
+ true
+ true
+ false
+
+
+ make
+
+ Makefile
+ true
+ true
+ false
+
+
+ make
+
+ mostlyclean
+ true
+ true
+ false
+
+
+ make
+
+ mostlyclean-libtool
+ true
+ true
+ false
+
+
+ make
+
+ pdf
+ true
+ true
+ false
+
+
+ make
+
+ ps
+ true
+ true
+ false
+
+
+ make
+
+ stamp-h1
+ true
+ true
+ false
+
+
+ make
+
+ tags
+ true
+ true
+ false
+
+
+ make
+
+ tags-recursive
+ true
+ true
+ false
+
+
+ make
+
+ uninstall
+ true
+ true
+ false
+
+
+
+
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..00788a8
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,2 @@
+docker
+deploy
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3f39719
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,27 @@
+*.pyc
+*.swp
+Makefile.in
+*.o
+*.pyo
+*.lo
+*.la
+.deps
+.libs
+*.log
+/build/
+/autom4te.cache/
+/aclocal.m4
+/config.guess
+/config.h.in
+/config.status
+/config.sub
+/configure
+/depcomp
+/install-sh
+/libtool
+/missing
+/stamp-h1
+/config.h
+/ltmain.sh
+/ar-lib
+workspace.code-workspace
diff --git a/.project b/.project
new file mode 100644
index 0000000..fab42e8
--- /dev/null
+++ b/.project
@@ -0,0 +1,62 @@
+
+
+ spell
+
+
+
+
+
+ org.eclipse.xtext.ui.shared.xtextBuilder
+
+
+
+
+ org.python.pydev.PyDevBuilder
+
+
+
+
+ org.eclipse.cdt.autotools.core.genmakebuilderV2
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.core.ccnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.autotools.core.autotoolsNatureV2
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+ org.python.pydev.pythonNature
+ org.eclipse.xtext.ui.shared.xtextNature
+
+
+
+ python2.7
+ 2
+ /home/spell/SPELL-COTS2.5.7a/include/python3.7m
+
+
+ spell_stubs
+ 2
+ /home/jgall/SPELL_TEST/spell
+
+
+ protos/google
+ 2
+ /home/spell/spell_cots/lib/python2.7/site-packages/grpc_tools/_proto/google
+
+
+
diff --git a/.pydevproject b/.pydevproject
new file mode 100644
index 0000000..389ee64
--- /dev/null
+++ b/.pydevproject
@@ -0,0 +1,11 @@
+
+
+Default
+python 3.0
+
+/${PROJECT_DIR_NAME}/src/spell
+/${PROJECT_DIR_NAME}/spell_stubs
+/${PROJECT_DIR_NAME}/drivers/remote_interface
+/${PROJECT_DIR_NAME}/drivers/service
+
+
diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml
new file mode 100644
index 0000000..adcc38a
--- /dev/null
+++ b/.settings/language.settings.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.settings/org.eclipse.cdt.codan.core.prefs b/.settings/org.eclipse.cdt.codan.core.prefs
new file mode 100644
index 0000000..b5248c6
--- /dev/null
+++ b/.settings/org.eclipse.cdt.codan.core.prefs
@@ -0,0 +1,71 @@
+eclipse.preferences.version=1
+org.eclipse.cdt.codan.checkers.errnoreturn=Warning
+org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return\\")",implicit\=>false}
+org.eclipse.cdt.codan.checkers.errreturnvalue=Error
+org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused return value\\")"}
+org.eclipse.cdt.codan.checkers.nocommentinside=-Error
+org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Nesting comments\\")"}
+org.eclipse.cdt.codan.checkers.nolinecomment=-Error
+org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Line comments\\")"}
+org.eclipse.cdt.codan.checkers.noreturn=Error
+org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return value\\")",implicit\=>false}
+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract class cannot be instantiated\\")"}
+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous problem\\")"}
+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment in condition\\")"}
+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment to itself\\")"}
+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No break at end of case\\")",no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false}
+org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
+org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching by reference is recommended\\")",unknown\=>false,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular inheritance\\")"}
+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class members should be properly initialized\\")",skip\=>true}
+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
+org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid arguments\\")"}
+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid template argument\\")"}
+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label statement not found\\")"}
+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member declaration not found\\")"}
+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Method cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name convention for function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class has a virtual method and non-virtual destructor\\")"}
+org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
+org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid overload\\")"}
+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redeclaration\\")"}
+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redefinition\\")"}
+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return with parenthesis\\")"}
+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format String Vulnerability\\")"}
+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement has no effect\\")",macro\=>true,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested parenthesis around expression\\")",paramNot\=>false}
+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious semicolon\\")",else\=>false,afterelse\=>false}
+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused function declaration\\")",macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused static function\\")",macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused variable declaration in file scope\\")",macro\=>true,exceptions\=>("@(\#)","$Id")}
+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol is not resolved\\")"}
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..371b909
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,132 @@
+# CLAUDE.md
+
+This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
+
+## What is SPELL
+
+SPELL (Spacecraft Procedure Execution Language and Library) is a ground software framework for spacecraft operations, developed by SES Engineering. It provides:
+- A Python-based **USL (User Script Language)** for writing spacecraft procedures
+- A distributed process architecture: Listener → Context → Executor(s)
+- A driver layer for connecting to different Ground Control Systems (GCS)
+
+## Build System
+
+SPELL uses GNU Autotools (autoconf + automake). The build requires:
+- GCC/G++ with pthreads
+- Python development headers
+- `xerces-c` (XML parsing), `log4cplus` (logging), `librt`, `libdl`, `libutil`
+- Optional: `cppunit` (unit tests), `ncurses`+`menu` (command-line executor)
+
+```bash
+# Standard build flow
+autoreconf -fi # Generate configure script (if needed)
+./configure [options] # Configure the build
+make # Build
+make install # Install to prefix
+
+# Configure options (all default to disabled except executor, shell, listener, context):
+./configure --enable-executor # Build SPELL-Executor binary (default on)
+./configure --enable-context # Build SPELL-Context binary (default on)
+./configure --enable-listener # Build SPELL-Shell binary (default on)
+./configure --enable-shell # Build SPELL-Shell binary (default on)
+./configure --enable-executorcmd # Build command-line executor (requires ncurses)
+./configure --enable-gui # Build SPELL-GUI (requires --with-eclipse=PATH)
+./configure --enable-driverstd # Build standalone driver
+./configure --enable-procs # Include sample procedures
+./configure --enable-documentation # Build Doxygen docs
+./configure --with-eclipse=PATH # Eclipse installation for GUI build
+./configure --with-log4cplus=PATH # log4cplus library path (default: /usr)
+```
+
+Compiler flags are defined in `common.mk`: includes `$(top_srcdir)/include`, `$SPELL_COTS/include`, Python headers, and log4cplus. All C++ objects are compiled with `-fPIC -g3 -Wall`.
+
+## Runtime Environment Variables
+
+Scripts in `scripts/linux/` require these to be set:
+
+| Variable | Purpose |
+|---|---|
+| `SPELL_HOME` | Installation root (contains `bin/`, `lib/`, `config/`, `data/`) |
+| `SPELL_DATA` | Runtime data directory (defaults to `$SPELL_HOME/data`) |
+| `SPELL_CONFIG` | Configuration directory (defaults to `$SPELL_HOME/config`) |
+
+Source `$SPELL_HOME/bin/setup-environment.sh` to set `LD_LIBRARY_PATH` and other derived variables.
+
+## Starting the Server
+
+```bash
+$SPELL_HOME/bin/SPELL-Server
+# Looks for config at: $SPELL_CONFIG/server/server__.xml
+```
+
+## Running Unit Tests
+
+After building with tests enabled:
+```bash
+$SPELL_HOME/bin/SPELL-RunTests
+# Runs all SPELL_unittest_* binaries from $SPELL_HOME/bin/
+# Logs output to $SPELL_HOME/log/unittests_.log
+# Test data expected at $SPELL_HOME/data/UnitTests/
+```
+
+## Architecture
+
+### Process Hierarchy
+
+```
+SPELL-Listener (entry point, port 9980)
+ └── SPELL-Context (manages spacecraft context, spawns executors)
+ └── SPELL-Executor (one per running procedure, embeds CPython)
+```
+
+All processes communicate over TCP sockets using the IPC layer (`lib/SPELL_IPC`). Configuration is loaded from XML files in `config/`.
+
+### C++ Library Layers (`lib/`)
+
+| Library | Purpose |
+|---|---|
+| `SPELL_UTIL` | Utilities (logging, time, string handling) |
+| `SPELL_IPC` | Inter-process communication (sockets, message mailboxes) |
+| `SPELL_SYN` | Synchronization primitives |
+| `SPELL_CFG` | XML configuration loading |
+| `SPELL_WRP` | Python/C++ wrapper layer (embeds CPython in executor) |
+| `SPELL_EXC` | Execution engine (bytecode analysis, callstack, controller) |
+| `SPELL_CTX` | Context management |
+| `SPELL_LST` | Listener process logic |
+| `SPELL_CIF` | Client interface (GUI-facing) |
+| `SPELL_CIFC` / `SPELL_CIFS` | CIF client/server implementations |
+| `SPELL_PRD` | Procedure management |
+| `SPELL_PRC` | Process control |
+| `SPELL_WS` | Warm-start / state persistence |
+| `SPELL_SDB` | Spacecraft database access |
+| `SPELL_DTA` | Data types and structures |
+
+Headers for all libraries live in `include/` (mirroring library names).
+
+### Python Layer (`src/spell/`)
+
+The `spell` Python package is what procedures import. Key sub-packages:
+
+- `spell.lang.functions` — USL functions (`Send`, `Verify`, `GetTM`, `BuildTC`, `Prompt`, `StartProc`, `Abort`, etc.)
+- `spell.lang.modifiers` — Modifier constants (`OnFailure`, `Timeout`, `Wait`, `ValueFormat`, etc.)
+- `spell.lang.constants` — Value constants (e.g., `ENG`, `RAW`, `ABORT`, `SKIP`)
+- `spell.lib.adapter` — Abstract base classes for driver interfaces (TC, TM, EV, USR, RSC, MEM, RNG, etc.)
+- `spell.lib.registry` — Runtime registry of active driver interface instances
+- `spell.utils` — Logging utilities
+
+### Driver Layer (`drivers/`)
+
+Drivers implement the `spell.lib.adapter` interfaces for a specific GCS. The `drivers/example/` directory is the reference implementation. Each driver provides modules: `tc.py`, `tm.py`, `ev.py`, `usr.py`, `resources.py`, `task.py`, `config.py`, `modifiers.py`.
+
+The `drivers/standalone/` driver runs without a GCS (simulator mode). Driver XML config files go in `config/contexts/`.
+
+### Configuration (`config/`)
+
+- `config/server/server.xml` — Main server config (ports, executor settings, driver list, context list)
+- `config/spell/language.xml` — Default modifier values per USL function
+- `config/contexts/context_STD.xml` — Context definition linking to satellite family and driver
+- `config/gui/config.xml` — GUI configuration
+
+### Sample Procedures (`procs/`)
+
+`procs/procedures/` contains example USL procedures. The `procs/userlib/` directory holds user procedure libraries importable from procedures.
diff --git a/INSTALL b/INSTALL
index 7d1c323..f214f5f 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,365 +1,17 @@
-Installation Instructions
-*************************
-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
-2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+$ autoreconf -fi
+$ mkdir build && cd build
+$ ../configure --prefix=/path/to/install/dir
- Copying and distribution of this file, with or without modification,
-are permitted in any medium without royalty provided the copyright
-notice and this notice are preserved. This file is offered as-is,
-without warranty of any kind.
+If some headers or libraries reside in exotic locations, add CPPFLAGS and LDFLAGS.
+Export PATH and LD_LIBRARY_PATH for those libraries to be detected. For example,
-Basic Installation
-==================
+$ SPELL_COTS=/path/to/spell/cots
+$ export LD_LIBRARY_PATH=$SPELL_COTS/lib:$LD_LIBRARY_PATH
+$ PATH=$SPELL_COTS/bin:$PATH
+$ ../configure --prefix=/path/to/install/dir CPPFLAGS="-I$SPELL_COTS/include" LDFLAGS="-L$SPELL_COTS/lib"
- Briefly, the shell commands `./configure; make; make install' should
-configure, build, and install this package. The following
-more-detailed instructions are generic; see the `README' file for
-instructions specific to this package. Some packages provide this
-`INSTALL' file but do not implement all of the features documented
-below. The lack of an optional feature in a given package is not
-necessarily a bug. More recommendations for GNU packages can be found
-in *note Makefile Conventions: (standards)Makefile Conventions.
-
- The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation. It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions. Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
-
- It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring. Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.
-
- If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release. If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
- The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'. You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
-
- The simplest way to compile this package is:
-
- 1. `cd' to the directory containing the package's source code and type
- `./configure' to configure the package for your system.
-
- Running `configure' might take a while. While running, it prints
- some messages telling which features it is checking for.
-
- 2. Type `make' to compile the package.
-
- 3. Optionally, type `make check' to run any self-tests that come with
- the package, generally using the just-built uninstalled binaries.
-
- 4. Type `make install' to install the programs and any data files and
- documentation. When installing into a prefix owned by root, it is
- recommended that the package be configured and built as a regular
- user, and only the `make install' phase executed with root
- privileges.
-
- 5. Optionally, type `make installcheck' to repeat any self-tests, but
- this time using the binaries in their final installed location.
- This target does not install anything. Running this target as a
- regular user, particularly if the prior `make install' required
- root privileges, verifies that the installation completed
- correctly.
-
- 6. You can remove the program binaries and object files from the
- source code directory by typing `make clean'. To also remove the
- files that `configure' created (so you can compile the package for
- a different kind of computer), type `make distclean'. There is
- also a `make maintainer-clean' target, but that is intended mainly
- for the package's developers. If you use it, you may have to get
- all sorts of other programs in order to regenerate files that came
- with the distribution.
-
- 7. Often, you can also type `make uninstall' to remove the installed
- files again. In practice, not all packages have tested that
- uninstallation works correctly, even though it is required by the
- GNU Coding Standards.
-
- 8. Some packages, particularly those that use Automake, provide `make
- distcheck', which can by used by developers to test that all other
- targets like `make install' and `make uninstall' work correctly.
- This target is generally not run by end users.
-
-Compilers and Options
-=====================
-
- Some systems require unusual options for compilation or linking that
-the `configure' script does not know about. Run `./configure --help'
-for details on some of the pertinent environment variables.
-
- You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment. Here
-is an example:
-
- ./configure CC=c99 CFLAGS=-g LIBS=-lposix
-
- *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
- You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory. To do this, you can use GNU `make'. `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script. `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'. This
-is known as a "VPATH" build.
-
- With a non-GNU `make', it is safer to compile the package for one
-architecture at a time in the source code directory. After you have
-installed the package for one architecture, use `make distclean' before
-reconfiguring for another architecture.
-
- On MacOS X 10.5 and later systems, you can create libraries and
-executables that work on multiple system types--known as "fat" or
-"universal" binaries--by specifying multiple `-arch' options to the
-compiler but only a single `-arch' option to the preprocessor. Like
-this:
-
- ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
- CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
- CPP="gcc -E" CXXCPP="g++ -E"
-
- This is not guaranteed to produce working output in all cases, you
-may have to build one architecture at a time and combine the results
-using the `lipo' tool if you have problems.
-
-Installation Names
-==================
-
- By default, `make install' installs the package's commands under
-`/usr/local/bin', include files under `/usr/local/include', etc. You
-can specify an installation prefix other than `/usr/local' by giving
-`configure' the option `--prefix=PREFIX', where PREFIX must be an
-absolute file name.
-
- You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files. If you
-pass the option `--exec-prefix=PREFIX' to `configure', the package uses
-PREFIX as the prefix for installing programs and libraries.
-Documentation and other data files still use the regular prefix.
-
- In addition, if you use an unusual directory layout you can give
-options like `--bindir=DIR' to specify different values for particular
-kinds of files. Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them. In general, the
-default for these options is expressed in terms of `${prefix}', so that
-specifying just `--prefix' will affect all of the other directory
-specifications that were not explicitly provided.
-
- The most portable way to affect installation locations is to pass the
-correct locations to `configure'; however, many packages provide one or
-both of the following shortcuts of passing variable assignments to the
-`make install' command line to change installation locations without
-having to reconfigure or recompile.
-
- The first method involves providing an override variable for each
-affected directory. For example, `make install
-prefix=/alternate/directory' will choose an alternate location for all
-directory configuration variables that were expressed in terms of
-`${prefix}'. Any directories that were specified during `configure',
-but not in terms of `${prefix}', must each be overridden at install
-time for the entire installation to be relocated. The approach of
-makefile variable overrides for each directory variable is required by
-the GNU Coding Standards, and ideally causes no recompilation.
-However, some platforms have known limitations with the semantics of
-shared libraries that end up requiring recompilation when using this
-method, particularly noticeable in packages that use GNU Libtool.
-
- The second method involves providing the `DESTDIR' variable. For
-example, `make install DESTDIR=/alternate/directory' will prepend
-`/alternate/directory' before all installation names. The approach of
-`DESTDIR' overrides is not required by the GNU Coding Standards, and
-does not work on platforms that have drive letters. On the other hand,
-it does better at avoiding recompilation issues, and works well even
-when some directory options were not specified in terms of `${prefix}'
-at `configure' time.
-
-Optional Features
-=================
-
- If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
- Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System). The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
- For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
- Some packages offer the ability to configure how verbose the
-execution of `make' will be. For these packages, running `./configure
---enable-silent-rules' sets the default to minimal output, which can be
-overridden with `make V=1'; while running `./configure
---disable-silent-rules' sets the default to verbose, which can be
-overridden with `make V=0'.
-
-Particular systems
-==================
-
- On HP-UX, the default C compiler is not ANSI C compatible. If GNU
-CC is not installed, it is recommended to use the following options in
-order to use an ANSI C compiler:
-
- ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
-
-and if that doesn't work, install pre-built binaries of GCC for HP-UX.
-
- On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
-parse its `' header file. The option `-nodtk' can be used as
-a workaround. If GNU CC is not installed, it is therefore recommended
-to try
-
- ./configure CC="cc"
-
-and if that doesn't work, try
-
- ./configure CC="cc -nodtk"
-
- On Solaris, don't put `/usr/ucb' early in your `PATH'. This
-directory contains several dysfunctional programs; working variants of
-these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
-in your `PATH', put it _after_ `/usr/bin'.
-
- On Haiku, software installed for all users goes in `/boot/common',
-not `/usr/local'. It is recommended to use the following options:
-
- ./configure --prefix=/boot/common
-
-Specifying the System Type
-==========================
-
- There may be some features `configure' cannot figure out
-automatically, but needs to determine by the type of machine the package
-will run on. Usually, assuming the package is built to be run on the
-_same_ architectures, `configure' can figure that out, but if it prints
-a message saying it cannot guess the machine type, give it the
-`--build=TYPE' option. TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
-
- CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
- OS
- KERNEL-OS
-
- See the file `config.sub' for the possible values of each field. If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
- If you are _building_ compiler tools for cross-compiling, you should
-use the option `--target=TYPE' to select the type of system they will
-produce code for.
-
- If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
-
-Sharing Defaults
-================
-
- If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists. Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Defining Variables
-==================
-
- Variables not defined in a site shell script can be set in the
-environment passed to `configure'. However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost. In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'. For example:
-
- ./configure CC=/usr/local2/bin/gcc
-
-causes the specified `gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf bug. Until the bug is fixed you can use this workaround:
-
- CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
-
-`configure' Invocation
-======================
-
- `configure' recognizes the following options to control how it
-operates.
-
-`--help'
-`-h'
- Print a summary of all of the options to `configure', and exit.
-
-`--help=short'
-`--help=recursive'
- Print a summary of the options unique to this package's
- `configure', and exit. The `short' variant lists options used
- only in the top level, while the `recursive' variant lists options
- also present in any nested packages.
-
-`--version'
-`-V'
- Print the version of Autoconf used to generate the `configure'
- script, and exit.
-
-`--cache-file=FILE'
- Enable the cache: use and save the results of the tests in FILE,
- traditionally `config.cache'. FILE defaults to `/dev/null' to
- disable caching.
-
-`--config-cache'
-`-C'
- Alias for `--cache-file=config.cache'.
-
-`--quiet'
-`--silent'
-`-q'
- Do not print messages saying which checks are being made. To
- suppress all normal output, redirect it to `/dev/null' (any error
- messages will still be shown).
-
-`--srcdir=DIR'
- Look for the package's source code in directory DIR. Usually
- `configure' can determine that directory automatically.
-
-`--prefix=DIR'
- Use DIR as the installation prefix. *note Installation Names::
- for more details, including other options available for fine-tuning
- the installation locations.
-
-`--no-create'
-`-n'
- Run the configure checks, but stop before creating any output
- files.
-
-`configure' also accepts some other, not widely useful, options. Run
-`configure --help' for more details.
+To enable debugging, add -DWITH_DEBUG to CPPFLAGS.
+$ make
+$ make install
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/Makefile.am b/Makefile.am
index 6935578..2e436d2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,34 +1,34 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2012 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
+AUTOMAKE_OPTIONS = subdir-objects foreign
+
+include ${top_srcdir}/common.mk
ACLOCAL_AMFLAGS = -I m4
-AUTOMAKE_OPTIONS = foreign
-SUBDIRS = lib drivers src config doc rcp scripts procs data
-install-exec-hook:
- mkdir -p ${exec_prefix}/log
+SUBDIRS = lib drivers src config data scripts
+RELEASE_NFO=${exec_prefix}/release.nfo
+install-exec-hook:
+ mkdir -p ${exec_prefix}/log
+ chmod g+w ${exec_prefix}/log
+ ${top_srcdir}/scripts/src/generate-release-nfo.sh ${top_srcdir}/RELEASENOTES ${PACKAGE_VERSION} ${exec_prefix} > ${RELEASE_NFO}
diff --git a/README b/README
deleted file mode 100644
index 1143bda..0000000
--- a/README
+++ /dev/null
@@ -1,20 +0,0 @@
-
- Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-
- This file is part of SPELL.
-
- SPELL is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- SPELL is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with SPELL. If not, see .
-
- Comments are welcome.
-
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..bc48c12
--- /dev/null
+++ b/README.md
@@ -0,0 +1,152 @@
+# SPELL
+
+**Spacecraft Procedure Execution Language and Library** — a ground software framework for spacecraft operations, developed by SES Engineering.
+
+> Current version: **2.6.8.4**
+> See [RELEASENOTES](RELEASENOTES) for the full changelog.
+
+## Overview
+
+SPELL provides:
+- A Python-based **USL (User Script Language)** for writing spacecraft procedures
+- A distributed process architecture: `SPELL-Listener` → `SPELL-Context` → `SPELL-Executor(s)`
+- A driver layer for connecting to different Ground Control Systems (GCS)
+
+## Requirements
+
+- GCC/G++ with pthreads (32-bit build: `gcc -m32` / `g++ -m32`)
+- Python development headers
+- `xerces-c`, `log4cplus`, `librt`, `libdl`, `libutil`
+- `SPELL_COTS` environment variable pointing to third-party dependencies directory
+- Optional: `cppunit` (unit tests), `ncurses`+`menu` (command-line executor)
+
+## Building
+
+### Quick build scripts (recommended)
+
+```bash
+# Standard (32-bit, with submodule proto support)
+./build_spell.sh hifly|scorpio|fuzzer|none [extra-configure-flags]
+
+# Ubuntu (64-bit, with address sanitizer)
+./build_spell_ubuntu.sh hifly|scorpio|fuzzer|none [extra-configure-flags]
+
+# Driver only
+./build_driver.sh hifly|scorpio|fuzzer|example [deps] [extra-configure-flags]
+```
+
+`SPELL_COTS` must be set before running any build script.
+
+### Manual build (Autotools)
+
+```bash
+autoreconf -fi
+mkdir -p build && cd build
+../configure --prefix=$SPELL_HOME [options] \
+ CPPFLAGS="-I$SPELL_COTS/include" \
+ LDFLAGS="-L$SPELL_COTS/lib"
+make -j4 && make install
+```
+
+### Configure options
+
+| Option | Default | Description |
+|---|---|---|
+| `--enable-executor` | on | Build SPELL-Executor |
+| `--enable-context` | on | Build SPELL-Context |
+| `--enable-listener` | on | Build SPELL-Listener |
+| `--enable-shell` | on | Build SPELL-Shell |
+| `--enable-executorcmd` | off | Command-line executor (requires ncurses) |
+| `--enable-gui` | off | SPELL-GUI (requires `--with-eclipse=PATH`) |
+| `--enable-hiflydriver` | off | Hifly GCS driver |
+| `--enable-scorpiodriver` | off | Scorpio GCS driver |
+| `--enable-fuzzerdriver` | off | Fuzzer driver |
+| `--enable-exampledriver` | off | Example/reference driver |
+| `--enable-driverstd` | off | Standalone driver |
+| `--enable-pace` | off | PACE support |
+| `--enable-tests` | off | Unit tests (requires cppunit) |
+| `--enable-address-sanitizer` | off | Build with AddressSanitizer |
+| `--enable-documentation` | off | Doxygen docs |
+| `--enable-procs` | off | Sample procedures |
+| `--with-eclipse=PATH` | — | Eclipse installation for GUI build |
+| `--with-log4cplus=PATH` | `/usr` | log4cplus library path |
+| `--with-exif=6` | — | EXIF version (required for hifly driver) |
+
+## Runtime
+
+### Environment variables
+
+| Variable | Purpose |
+|---|---|
+| `SPELL_HOME` | Installation root (`bin/`, `lib/`, `config/`, `data/`) |
+| `SPELL_COTS` | Third-party dependencies root |
+| `SPELL_DATA` | Runtime data directory (default: `$SPELL_HOME/data`) |
+| `SPELL_CONFIG` | Configuration directory (default: `$SPELL_HOME/config`) |
+
+Source `$SPELL_HOME/bin/setup-environment.sh` to set `LD_LIBRARY_PATH` and derived variables.
+
+### Starting the server
+
+```bash
+$SPELL_HOME/bin/SPELL-Server
+# Looks for config at: $SPELL_CONFIG/server/server__.xml
+```
+
+### Running unit tests
+
+```bash
+$SPELL_HOME/bin/SPELL-RunTests
+# Runs all SPELL_unittest_* binaries from $SPELL_HOME/bin/
+# Logs to $SPELL_HOME/log/unittests_.log
+# Test data expected at $SPELL_HOME/data/UnitTests/
+```
+
+## Architecture
+
+### Process hierarchy
+
+```
+SPELL-Listener (entry point, default port 9980)
+ └── SPELL-Context (manages spacecraft context, spawns executors)
+ └── SPELL-Executor (one per running procedure, embeds CPython)
+```
+
+All processes communicate over TCP sockets via `lib/SPELL_IPC`. Configuration is loaded from XML files in `config/`.
+
+### Key directories
+
+| Directory | Contents |
+|---|---|
+| `lib/` | C++ libraries (SPELL_EXC, SPELL_IPC, SPELL_WRP, etc.) |
+| `include/` | C++ headers mirroring `lib/` structure |
+| `src/spell/` | Python `spell` package (USL functions, adapters, utilities) |
+| `src/executor/` | SPELL-Executor binary |
+| `src/context/` | SPELL-Context binary |
+| `src/listener/` | SPELL-Listener binary |
+| `drivers/` | GCS driver implementations (example, standalone, and others) |
+| `config/` | XML configuration (server, contexts, language defaults) |
+| `procs/` | Sample USL procedures |
+| `data/` | Runtime data directories (AsRun, Warmstart, Procedures, etc.) |
+| `scripts/linux/` | Startup and utility scripts |
+| `deploy/` | Kubernetes/Helm deployment manifests |
+| `azure_pipelines/` | CI/CD pipeline definitions |
+
+### Python USL
+
+Procedures import from the `spell` package:
+
+```python
+from spell.lang.functions import Send, Verify, GetTM, Prompt, Abort
+from spell.lang.modifiers import OnFailure, Timeout, Wait
+from spell.lang.constants import ENG, RAW, ABORT, SKIP
+```
+
+### Implementing a driver
+
+Use `drivers/example/` as the reference. Each driver must implement these modules in its `src/` directory: `tc.py`, `tm.py`, `ev.py`, `usr.py`, `resources.py`, `task.py`, `config.py`, `modifiers.py`.
+
+## License
+
+SPELL is distributed under the [GNU General Public License v3](COPYING.GPLv3). Python library components use [LGPLv3](COPYING.LGPLv3).
+
+Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
diff --git a/RELEASENOTES b/RELEASENOTES
new file mode 100644
index 0000000..7dcc485
--- /dev/null
+++ b/RELEASENOTES
@@ -0,0 +1,332 @@
+---------
+CHANGELOG
+---------
+
+What's new in SPELL 2.6.8.4
+==========================
+** Task
+ * Fix procedure listener cleanup
+ * Fix port assignment for on prem deployment
+ * Fix badly formatted WaitFor
+ * Fix loading of SCDB and GDB entries
+
+What's new in SPELL 2.6.8.2
+==========================
+** Task
+ * [SPELL-650] - Issue when taking control of a background (ARC) service running for a long time
+
+What's new in SPELL 2.6.8.1
+==========================
+** Bug
+ * [SPELL-644] - AOS_TM_TC_MONITOR stuck on ARC BB and SPELL Froze
+
+** Enhancement
+ * [SPELL-547] - Containerize SPELL to ease deployment
+
+What's new in SPELL 2.6.8
+==========================
+** Bug
+ * [SPELL-631] - Merge file import does not read content correctly
+ * [SPELL-641] - TIME object can't be created using a long anymore
+
+What's new in SPELL 2.6.7.8
+==========================
+** Bug
+ * [SPELL-640] - SPELL Listener and SPELL context crash on Disconnect
+
+What's new in SPELL 2.6.7.7
+==========================
+** Enhancement
+ * [SPELL-635] - Implement RestoreNormalLimits using FleetLimits
+ * [SPELL-637] - allow fleetlimits and archiva to coexist in the driver config
+
+What's new in SPELL 2.6.7.6
+==========================
+** Bug
+ * [SPELL-636] - SPELL Scorpio driver crashes when loosing connection to GCS
+
+What's new in SPELL 2.6.7.5
+==========================
+** Bug
+ * [SPELL-631] - Merge file import does not read content correctly
+
+What's new in SPELL 2.6.7.4
+==========================
+** Bug
+ * [SPELL-625] - IPA_CALIBRATION procedure crashed for MP01 on M2
+ * [SPELL-631] - Merge file import does not read content correctly
+
+** Enhancement
+ * [FLEET-3342] - Use a clientname to enable sticky sessions
+
+What's new in SPELL 2.6.7.3
+==========================
+** Bug
+ * [SPELL-626] - PACE activities failing and not being able to reopen in SPELL
+
+What's new in SPELL 2.6.7.2
+==========================
+** Bug
+ * [SPELL-622] - Regression - Issues with Prompt after ECHO CV Failure
+
+What's new in SPELL 2.6.7.1
+==========================
+** Bug
+ * [SPELL-622] - Issues with Prompt after ECHO CV Failure
+
+What's new in SPELL 2.6.7
+==========================
+** Bug
+ * [SPELL-624] - Retry Command Prompts are broken
+
+What's new in SPELL 2.6.6.5
+==========================
+** Bug
+ * [SPELL-618] - stranded crtxcmdb processes on m2cntl - SPELL false CV failures
+
+What's new in SPELL 2.6.6.4
+==========================
+** Bug
+ * [SPELL-619] - NORTH_SOUTH_STATIONKEEPING proc crash due to Execution aborted: Key error
+
+What's new in SPELL 2.6.6.3
+==========================
+** Bug
+ * [SPELL-616] - Undefined error variable in Scoprio driver causes memory corruption in SPELL
+
+What's new in SPELL 2.6.6.2
+==========================
+** Bug
+ * [SPELL-615] - ORT Uplink Check script failing. (additional fix)
+
+What's new in SPELL 2.6.6.1
+==========================
+** Bug
+ * [SPELL-615] - ORT Uplink Check script failing.
+
+What's new in SPELL 2.6.6
+==========================
+** Bug
+ * [SPELL-608] - IPC not connected message for long running procedures
+ * [SPELL-610] - Recurrent failures trying to acquire ground variables
+ * [SPELL-611] - Use After Free Crash of scorpio driver interface
+ * [SPELL-614] - GAR13043-Procedure 31104_North_South_Stationkeeping aborted and could not be unrecovered
+
+What's new in SPELL 2.6.5.5
+==========================
+** Bug
+ * [SPELL-307] - Sorting of files at the import file viewer/edit calling arguments (Server file selection)Sorting of files at the import file viewer/edit calling arguments (Server file selection)
+ * [Commit-cb233664787] Fix-regression-in-sce-toggle-functionality
+
+What's new in SPELL 2.6.5.4
+==========================
+** Bug
+ * [SPELL-599] - SPELL error : Lost connection with executor - Process crashed.
+
+** New Requirement
+ * [SPELL-590] - Retrieve and output current limit, msg ab algo version and time stamp and output it in SPELL
+ * [MPD-705] - Update Lookup_DataObject with Field fswpackage
+
+What's new in SPELL 2.6.5.3
+==========================
+** Enhancement
+ * [FLEET-720] - Activation of ephemeral and Overlay limits from SPELL
+ * [SCO-2992] - Trigger TPU restart from SPELL script
+
+What's new in SPELL 2.6.5.2
+==========================
+** Enhancement
+ * [SCO-3740] - SPELL prompt options after command failure
+
+What's new in SPELL 2.6.5.1
+==========================
+** Bug
+ * [SES2223-190] - Spell instruction WaitFor cannot be interrupted
+
+What's new in SPELL 2.6.5
+==========================
+** Bug
+ * [SPELL-582] - Avoid calling doStep when doSkip fails
+
+What's new in SPELL 2.6.4.3
+==========================
+** Bug
+ * [SPELL-573] - SPELL Crash on Python 3 Abort()
+
+What's new in SPELL 2.6.4.2
+==========================
+** Bug
+ * [SPELL-571] - Setting DUVs is only supported on the SES Mnemonic
+
+What's new in SPELL 2.6.4.1
+==========================
+** Bug
+ * [SPELL-557] - SPELL Deadlock when Pausing a Procedure inside a WaitFor with TM checks
+ * [SPELL-560] - WaitFor TM instruction crashed upon REPEAT
+ * [SPELL-568] - FleetTM connector is reutrning 999999 as a raw value for DPs
+
+
+** New Requirement
+ * [SPELL-565] - Ability to set the Spell Execution by STEP in the procedure
+
+What's new in SPELL 2.6.4
+==========================
+** Bug
+ * [SPELL-554] - Fix SB4000 tduinfo global rewrite
+
+
+ ** New Requirement
+ * [SPELL-517] - SPELL procedure should be able to restore manually applied limits
+
+What's new in SPELL 2.6.3.3
+==========================
+** Enhancement
+ * [SPELL-551] - Make SPELL driver more robust when accessing Scorpio variables
+
+What's new in SPELL 2.6.3.2
+==========================
+** Hotfix
+ * [SPELL-549] - SPELL Unable to Read\Set Resources - Fix for endless loop when receiving bad data
+
+What's new in SPELL 2.6.3.1
+==========================
+** Bug
+ * [SPELL-549] - SPELL Unable to Read\Set Resources
+
+What's new in SPELL 2.6.3
+==========================
+** Bug
+ * [SPELL-539] - Send ping to Collector
+ * [SPELL-542] - SetGroundParameter can't be executed
+ * [SPELL-544] - SPELL did not send all commands during a PACE Bi-weekly operations (PR #261).
+
+What's new in SPELL 2.6.2.3
+==========================
+** Bug
+ * [SPELL-544] - SPELL did not send all commands during a PACE Bi-weekly operations.
+
+What's new in SPELL 2.6.2.2
+==========================
+** Bug
+ * [SPELL-537] - Properly handle Collector connection error and failures
+ * [SPELL-475] - Enable LoadDictionary to load Data from Pharos
+
+What's new in SPELL 2.6.2.1
+==========================
+** Bug
+ * [SPELL-536] - SPELL SCE toggle error checking mistake success with error
+
+
+ ** New Requirement
+ * [SPELL-475] - Enable LoadDictionary to load Data from Pharos
+
+What's new in SPELL 2.6.2
+==========================
+
+** Bug
+ * [SPELL-505] - Unable to command after a TC failure
+ * [SPELL-512] - Deadlock caused by ping not receiving any data
+
+
+** New Requirement
+ * [SPELL-516] - SPELL back-end to query for applied overlay limit files
+
+** Enhancement
+ * [SPELL-456] - GCS Enhancement Request - Automated Uplink Checks via SPELL
+ * [SPELL-484] - Raise an alarm (if possible) if procedure loses connection to context
+ * [SPELL-527] - Collector interfacing for SES20/21
+ * [SPELL-533] - Add bzcesim collector node number to scorpio driver
+
+What's new in SPELL 2.6.1.1
+==========================
+
+** Bug
+ * [SPELL-513] - SPELL failure to command at P2 for AMC18
+
+What's new in SPELL 2.6.1
+==========================
+
+** New Requirement
+ * [SPELL-457] - New message from SPELL to CWS to request VCC bump
+ * [SPELL-500] - New SPELL function to retrieve TM packets
+
+** Bug
+ * [SPELL-465] - Fix Python3 Memory lookup functions in Scorpio driver
+ * [SPELL-482] - SPELL crash during SN preparation
+ * [SPELL-489] - Python3: OpenFile with MODE=WRITE doesn't create a new file
+ * [SPELL-493] - IVARS and ARGS missing millisecond and microsecond
+ * [SPELL-496] - SPELL Context locks up when more then one service needs to get started
+ * [SPELL-506] - Missing import of TIME in the implementation of GetTMPackets makes the SPELL context crash
+
+** Enhancement
+ * [SPELL-426] - SPELL resource display (to check and set local TC options)
+ * [SPELL-455] - SES17: Improve CWS timeout message when TC packets are pending
+ * [SPELL-464] - Catch Common key/value parsing errors
+ * [SPELL-471] - Add M1/M2 node names
+ * [SPELL-473] - Add proto Git submodule
+ * [SPELL-494] - Improve SPELL Scorpio driver to make available exception messages to ARC
+ * [SPELL-507] - Meaningful error message on SCE toggle driver function error
+ * [SPELL-508] - Do not enforce the Collector availability for a procedure to run with mPower
+ * [SPELL-510] - Helper wrapping library to easily make GPS communication in Scorpio Driver
+
+What's new in SPELL 2.6.0.1
+==========================
+
+** Bug
+ * [SPELL-466] - SN1313: Process crashed during manoeuvre set up
+
+What's new in SPELL 2.6.0
+==========================
+
+** New Requirement
+ * [SPELL-337] - Make SPELL Python 3 compatible
+ * [SPELL-338] - Implement SES17 command capability
+ * [SPELL-344] - New SPELL functions to access Ground DTP Image
+
+** Bug
+ * [SPELL-281] - Don't do busy waiting while trying to receive an Ack in Scorpio driver
+ * [SPELL-340] - No audible for Spell Prompts
+ * [SPELL-356] - SES17 SetResource doesn't work and gives SPELL exeception
+ * [SPELL-357] - PACE alarm : Backup seat GE (g2anal02) not reachable: listener: login: send request: response timeout)
+ * [SPELL-358] - AMC07 & AMC08 SPELL Crash During BATMON Script
+ * [SPELL-359] - P.A3B.SEASON_MANAGEMENT procedure got stuck in the WaitFor statement
+ * [SPELL-365] - SPELL WaitFor TM crashes when there are issues
+ * [SPELL-373] - SPELl Service not copmpatible with Python3
+ * [SPELL-377] - Prompt will cuase SPELL v3 to crash
+ * [SPELL-383] - GOTO doesn't work on Python 3
+ * [SPELL-388] - Update STC.i for increased commanding buffer
+ * [SPELL-389] - Default sec/millis must be positive
+ * [SPELL-390] - Setting further TC options fails after encryption is set to ON
+ * [SPELL-392] - Python 3 breaks the Watch variables feature
+ * [SPELL-393] - SaveDictionary is not python 3 compatible
+ * [SPELL-394] - SPELL Warmstart crashes on throwing an excpetion within SPELL library code
+ * [SPELL-395] - SetUserAction crashes in Python 3
+ * [SPELL-396] - SendDelay/ReleaseTime modifiers don't work
+ * [SPELL-398] - Group command sending fails
+ * [SPELL-399] - mPower - big command crashes procedure
+ * [SPELL-401] - The Dynamic GRPCThreadPool used for GRPC connections and the SPELL Service is not working in Python 3
+ * [SPELL-403] - LoadExternalData doesn't work in new SPELL version
+ * [SPELL-406] - BuildTC command options are dropped in a command group of size one
+ * [SPELL-407] - SPELL-Driver start-up fails due to relative and missing imports
+ * [SPELL-413] - PACE: SPELL-Driver does not like relative parts
+ * [SPELL-430] - FleetTM output bus: With Wait=True, gRPC timeout does not work
+ * [SPELL-434] - SES17/mPower: Reset TC group after skip/cancel Prompt (Q, K, C)
+ * [SPELL-451] - Add missing sc= keyword in the GPS message
+ * [SPELL-460] - SES17 TC acceptance: n/a messges are not correctly handled resulting in timeouts
+ * [SPELL-463] - Long CWS messages crash Common client in the driver
+
+** Enhancement
+ * [SPELL-341] - FLEET - Enable SPELL access to PHAROS
+ * [SPELL-346] - Kill SPELL-Service as well when stopping SPELL
+ * [SPELL-348] - Add mission name to SPELL driver log file name
+ * [SPELL-354] - Add subschedule_id flag to SBNEO time tag command format
+ * [SPELL-370] - Add millisecond support for SES17 (SBNEO) platform
+ * [SPELL-371] - Make TC options and other ground resources local to the procedure
+ * [SPELL-372] - Update Scorpio TM Archiva interface to new Python3 module
+ * [SPELL-376] - Notify = False is not implemented for BuildTC
+ * [SPELL-385] - Teach mPower/sbneo drivers to use the convert_arguments_validate function
+ * [SPELL-391] - Add TC acceptance & verification flags to SBNEO
+ * [SPELL-429] - FleetTM output bus: Add gRPC request retries before throwing an exception
+ * [SPELL-433] - Check CWS request buffer size to avoid overflow in Common and STC
+ * [SPELL-453] - Refresh GPS connections after (long) commanding to avoid disconnections
+ * [SPELL-454] - Make Handle exception inherit from Exception
diff --git a/SPELL Debug.launch b/SPELL Debug.launch
new file mode 100644
index 0000000..7cd2f83
--- /dev/null
+++ b/SPELL Debug.launch
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/azure_pipelines/ci_logrotate.yaml b/azure_pipelines/ci_logrotate.yaml
new file mode 100644
index 0000000..2403643
--- /dev/null
+++ b/azure_pipelines/ci_logrotate.yaml
@@ -0,0 +1,139 @@
+# Starter pipeline
+# Start with a minimal pipeline that you can customize to build and deploy your code.
+# Add steps that build, run tests, deploy, and more:
+# https://aka.ms/yaml
+
+
+trigger:
+ branches:
+ include:
+ - develop
+ paths:
+ include:
+ - azure_pipelines/variables/logrotate.yaml
+ - azure_pipelines/variables/baseline.yaml
+ - azure_pipelines/ci_logrotate.yaml
+ - docker/logrotate/**
+
+
+name: "SPELL Logrotate CI Pipeline"
+
+pool:
+ name: weu1-d-keda
+
+variables:
+- template: variables/baseline.yaml
+- name: tags
+ value: "$(Build.DefinitionName)_$(Build.DefinitionVersion)_$(Build.BuildId)_$(Build.BuildNumber)"
+- name: DOCKER_BUILDKIT
+ value: 1
+- name: NODE_TLS_REJECT_UNAUTHORIZED
+ value: 0
+- template: variables/logrotate.yaml
+- group: nexus-auth
+- name: NEXUS_CONTAINER_SCANNING_SCANNER_IMAGE
+ value: neuvector/scanner
+- name: NEXUS_CONTAINER_SCANNING_REGISTRY_URL
+ value: https://docker-weu.spo.internal.ses.com
+- name: NEXUS_CONTAINER_IMAGE_REGISTRY_USER
+ value: $(NEXUS_USER)
+- name: NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD
+ value: $(NEXUS_PASSWORD)
+- name: NEXUS_CONTAINER_SCANNING_REGISTRY_USER
+ value: $(NEXUS_USER)
+- name: NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD
+ value: $(NEXUS_PASSWORD)
+
+stages:
+- stage:
+ displayName: Nexus IQ Check
+ jobs:
+ - job:
+ displayName: Docker image
+ steps:
+ - task: Bash@3
+ displayName: Extract Version
+ inputs:
+ targetType: inline
+ script: |
+ get_next_version() {
+ local increment_type="$1"
+ local RE='([0-9]*)[.]([0-9]*)[.]([0-9]*)([.-][0-9A-Za-z.-]+)?'
+
+ if [ -z "$increment_type" ]; then
+ increment_type="patch"
+ fi
+ if [[ "$2" =~ $RE ]]; then
+ local MAJOR="${BASH_REMATCH[1]}"
+ local MINOR="${BASH_REMATCH[2]}"
+ local PATCH="${BASH_REMATCH[3]}"
+ local pre=""
+ else
+ local MAJOR=0
+ local MINOR=0
+ local PATCH=0
+ local pre=""
+ fi
+
+ case "$increment_type" in
+ major)
+ ((MAJOR += 1))
+ ((MINOR = 0))
+ ((PATCH = 0))
+ ;;
+ minor)
+ ((MINOR += 1))
+ ((PATCH = 0))
+ ;;
+ patch)
+ ((PATCH += 1))
+ ;;
+ esac
+
+ local NEXT_VERSION="$MAJOR.$MINOR.$PATCH"
+ echo "$NEXT_VERSION"
+ }
+
+ HEAD=`git rev-parse --short HEAD` && echo HEAD: ${HEAD}
+ VERSION_TAG=`git describe --abbrev=0 --tags ${HEAD} 2>/dev/null || true` && echo VERSION_TAG: ${VERSION_TAG}
+ TAG_COMMIT=`git rev-list -n 1 --abbrev-commit ${VERSION_TAG}` && echo TAG_COMMIT: ${TAG_COMMIT}
+ if [[ "$HEAD" != "$TAG_COMMIT" ]]
+ then
+ VERSION_TAG=`get_next_version patch ${VERSION_TAG}`
+ fi
+ echo "##vso[task.setvariable variable=VERSION_TAG]$VERSION_TAG"
+ echo "ADO Tag: $(tags)"
+ echo "New Version to be built: ${VERSION_TAG}"
+
+ workingDirectory: "$(system.defaultWorkingDirectory)/"
+ - task: Docker@2
+ displayName: Build
+ inputs:
+ command: build
+ repository: "$(DOCKER_IMAGE)"
+ containerRegistry: "$(NEXUS_REGISTRY)"
+ buildContext: "**$(DOCKER_BUILD_CONTEXT)"
+ Dockerfile: "$(DOCKER_FILEPATH)/Dockerfile"
+ tags: "$(VERSION_TAG)"
+ arguments: "--build-arg RUNTIME_IMAGE=$(RUNTIME_IMAGE) --build-arg BUILD_IMAGE=$(BUILD_IMAGE) --build-arg http_proxy=$(PROXY) --build-arg https_proxy=$(PROXY) --build-arg no_proxy=$(NO_PROXY)"
+ - task: Docker@2
+ displayName: Push
+ inputs:
+ command: push
+ repository: "$(DOCKER_IMAGE)"
+ containerRegistry: "$(NEXUS_REGISTRY)"
+ tags: "$(VERSION_TAG)"
+ - task: NexusIqPipelineTask@1
+ continueOnError: true
+ env:
+ NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD: $(NEXUS_PASSWORD)
+ NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD: $(NEXUS_PASSWORD)
+ inputs:
+ nexusIqService: 'nexus-iq'
+ organizationId: 'b57c0bd6dfd247fa964dbc4cbfdf2f2a'
+ applicationId: '$(NEXUS_APPLICATION)'
+ stage: 'Build'
+ scanTargets: 'container:https://$(NEXUS_REGISTRY_URL)/$(DOCKER_IMAGE):$(VERSION_TAG)'
+ enableDebugLogging: true
+ ignoreSystemError: true
+ ignoreScanningError: true
\ No newline at end of file
diff --git a/azure_pipelines/ci_spell_driver_scorpio.yaml b/azure_pipelines/ci_spell_driver_scorpio.yaml
new file mode 100644
index 0000000..0a29170
--- /dev/null
+++ b/azure_pipelines/ci_spell_driver_scorpio.yaml
@@ -0,0 +1,139 @@
+# Starter pipeline
+# Start with a minimal pipeline that you can customize to build and deploy your code.
+# Add steps that build, run tests, deploy, and more:
+# https://aka.ms/yaml
+
+trigger:
+ branches:
+ include:
+ - develop
+ paths:
+ include:
+ - azure_pipelines/variables/spell_driver_scorpio.yaml
+ - azure_pipelines/variables/baseline.yaml
+ - azure_pipelines/ci_spell_driver_scorpio.yaml
+ - drivers/scorpio/**
+ - docker/drivers/scorpio/**
+ - include/**
+
+name: "SPELL Scorpio Driver CI Pipeline"
+
+pool:
+ name: weu1-d-keda
+
+variables:
+- template: variables/baseline.yaml
+- name: tags
+ value: "$(Build.DefinitionName)_$(Build.DefinitionVersion)_$(Build.BuildId)_$(Build.BuildNumber)"
+- name: DOCKER_BUILDKIT
+ value: 1
+- name: NODE_TLS_REJECT_UNAUTHORIZED
+ value: 0
+- template: variables/spell_driver_scorpio.yaml
+- group: nexus-auth
+- name: NEXUS_CONTAINER_SCANNING_SCANNER_IMAGE
+ value: neuvector/scanner
+- name: NEXUS_CONTAINER_SCANNING_REGISTRY_URL
+ value: https://docker-weu.spo.internal.ses.com
+- name: NEXUS_CONTAINER_IMAGE_REGISTRY_USER
+ value: $(NEXUS_USER)
+- name: NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD
+ value: $(NEXUS_PASSWORD)
+- name: NEXUS_CONTAINER_SCANNING_REGISTRY_USER
+ value: $(NEXUS_USER)
+- name: NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD
+ value: $(NEXUS_PASSWORD)
+
+stages:
+- stage:
+ displayName: Nexus IQ Check
+ jobs:
+ - job:
+ displayName: Docker image
+ steps:
+ - task: Bash@3
+ displayName: Extract Version
+ inputs:
+ targetType: inline
+ script: |
+ get_next_version() {
+ local increment_type="$1"
+ local RE='([0-9]*)[.]([0-9]*)[.]([0-9]*)([.-][0-9A-Za-z.-]+)?'
+
+ if [ -z "$increment_type" ]; then
+ increment_type="patch"
+ fi
+ if [[ "$2" =~ $RE ]]; then
+ local MAJOR="${BASH_REMATCH[1]}"
+ local MINOR="${BASH_REMATCH[2]}"
+ local PATCH="${BASH_REMATCH[3]}"
+ local pre=""
+ else
+ local MAJOR=0
+ local MINOR=0
+ local PATCH=0
+ local pre=""
+ fi
+
+ case "$increment_type" in
+ major)
+ ((MAJOR += 1))
+ ((MINOR = 0))
+ ((PATCH = 0))
+ ;;
+ minor)
+ ((MINOR += 1))
+ ((PATCH = 0))
+ ;;
+ patch)
+ ((PATCH += 1))
+ ;;
+ esac
+
+ local NEXT_VERSION="$MAJOR.$MINOR.$PATCH"
+ echo "$NEXT_VERSION"
+ }
+
+ HEAD=`git rev-parse --short HEAD` && echo HEAD: ${HEAD}
+ VERSION_TAG=`git describe --abbrev=0 --tags ${HEAD} 2>/dev/null || true` && echo VERSION_TAG: ${VERSION_TAG}
+ TAG_COMMIT=`git rev-list -n 1 --abbrev-commit ${VERSION_TAG}` && echo TAG_COMMIT: ${TAG_COMMIT}
+ if [[ "$HEAD" != "$TAG_COMMIT" ]]
+ then
+ VERSION_TAG=`get_next_version patch ${VERSION_TAG}`
+ fi
+ echo "##vso[task.setvariable variable=VERSION_TAG]$VERSION_TAG"
+ echo "ADO Tag: $(tags)"
+ echo "New Version to be built: ${VERSION_TAG}"
+
+ workingDirectory: "$(system.defaultWorkingDirectory)/"
+ - task: Docker@2
+ displayName: Build
+ inputs:
+ command: build
+ repository: "$(DOCKER_IMAGE)"
+ containerRegistry: "$(NEXUS_REGISTRY)"
+ buildContext: "**$(DOCKER_BUILD_CONTEXT)"
+ Dockerfile: "$(DOCKER_FILEPATH)/Dockerfile"
+ tags: "$(VERSION_TAG)"
+ arguments: "--build-arg RUNTIME_IMAGE=$(RUNTIME_IMAGE) --build-arg BUILD_IMAGE=$(BUILD_IMAGE) --build-arg http_proxy=$(PROXY) --build-arg https_proxy=$(PROXY) --build-arg no_proxy=$(NO_PROXY)"
+ - task: Docker@2
+ displayName: Push
+ inputs:
+ command: push
+ repository: "$(DOCKER_IMAGE)"
+ containerRegistry: "$(NEXUS_REGISTRY)"
+ tags: "$(VERSION_TAG)"
+ - task: NexusIqPipelineTask@1
+ continueOnError: true
+ env:
+ NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD: $(NEXUS_PASSWORD)
+ NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD: $(NEXUS_PASSWORD)
+ inputs:
+ nexusIqService: 'nexus-iq'
+ organizationId: 'b57c0bd6dfd247fa964dbc4cbfdf2f2a'
+ applicationId: '$(NEXUS_APPLICATION)'
+ stage: 'Build'
+ scanTargets: 'container:https://$(NEXUS_REGISTRY_URL)/$(DOCKER_IMAGE):$(VERSION_TAG)'
+ enableDebugLogging: true
+ ignoreSystemError: true
+ ignoreScanningError: true
diff --git a/azure_pipelines/ci_spell_registry.yaml b/azure_pipelines/ci_spell_registry.yaml
new file mode 100644
index 0000000..4e378ed
--- /dev/null
+++ b/azure_pipelines/ci_spell_registry.yaml
@@ -0,0 +1,158 @@
+# Starter pipeline
+# Start with a minimal pipeline that you can customize to build and deploy your code.
+# Add steps that build, run tests, deploy, and more:
+# https://aka.ms/yaml
+
+
+trigger:
+ branches:
+ include:
+ - develop
+ paths:
+ include:
+ - azure_pipelines/variables/spell_registry.yaml
+ - azure_pipelines/variables/baseline.yaml
+ - azure_pipelines/ci_spell_registry.yaml
+ - docker/spell-registry/**
+
+name: "SPELL Registry CI Pipeline"
+
+pool:
+ name: weu1-d-keda
+
+variables:
+- template: variables/baseline.yaml
+- name: tags
+ value: "$(Build.DefinitionName)_$(Build.DefinitionVersion)_$(Build.BuildId)_$(Build.BuildNumber)"
+- name: DOCKER_BUILDKIT
+ value: 1
+- name: NODE_TLS_REJECT_UNAUTHORIZED
+ value: 0
+- template: variables/spell_registry.yaml
+- group: nexus-auth
+- name: NEXUS_CONTAINER_SCANNING_SCANNER_IMAGE
+ value: neuvector/scanner
+- name: NEXUS_CONTAINER_SCANNING_REGISTRY_URL
+ value: https://docker-weu.spo.internal.ses.com
+- name: NEXUS_CONTAINER_IMAGE_REGISTRY_USER
+ value: $(NEXUS_USER)
+- name: NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD
+ value: $(NEXUS_PASSWORD)
+- name: NEXUS_CONTAINER_SCANNING_REGISTRY_USER
+ value: $(NEXUS_USER)
+- name: NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD
+ value: $(NEXUS_PASSWORD)
+
+stages:
+- stage:
+ displayName: Nexus IQ Check
+ jobs:
+ - job:
+ displayName: Docker image
+ steps:
+ - task: Bash@3
+ displayName: Extract Version
+ inputs:
+ targetType: inline
+ script: |
+ get_next_version() {
+ local increment_type="$1"
+ local RE='v?[^0-9]*\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)\([0-9A-Za-z-]*\)'
+
+ if [ -z "$increment_type" ]; then
+ increment_type="patch"
+ fi
+
+ local base=$(node -pe 'require("./package.json")["version"]')
+
+ local MAJOR=$(echo $base | sed -e "s#$RE#\1#")
+ local MINOR=$(echo $base | sed -e "s#$RE#\2#")
+ local PATCH=$(echo $base | sed -e "s#$RE#\3#")
+ local HOTFIX=$(echo $base | sed -e "s#$RE#\4#")
+
+ case "$increment_type" in
+ major)
+ ((MAJOR += 1))
+ ((MINOR = 0))
+ ((PATCH = 0))
+ ((HOTFIX = 0))
+ ;;
+ minor)
+ ((MINOR += 1))
+ ((PATCH = 0))
+ ((HOTFIX = 0))
+ ;;
+ patch)
+ ((PATCH += 1))
+ ((HOTFIX = 0))
+ ;;
+ hotfix)
+ ((HOTFIX += 1))
+ ;;
+ esac
+
+ local NEXT_VERSION="$MAJOR.$MINOR.$PATCH.$HOTFIX"
+ echo "$NEXT_VERSION"
+ }
+
+ HEAD=`git rev-parse --short HEAD` && echo HEAD: ${HEAD}
+ VERSION_TAG=`git describe --abbrev=0 --tags ${HEAD} 2>/dev/null || true` && echo VERSION_TAG: ${VERSION_TAG}
+ TAG_COMMIT=`git rev-list -n 1 --abbrev-commit ${VERSION_TAG}` && echo TAG_COMMIT: ${TAG_COMMIT}
+ if [[ "$HEAD" != "$TAG_COMMIT" ]]
+ then
+ VERSION_TAG=${VERSION_TAG}-dev
+ fi
+ echo "##vso[task.setvariable variable=VERSION_TAG]$VERSION_TAG"
+ echo "ADO Tag: $(tags)"
+
+ workingDirectory: "$(system.defaultWorkingDirectory)/"
+ - task: Docker@2
+ inputs:
+ containerRegistry: 'nexus-docker-weu'
+ command: 'login'
+ - task: Bash@3
+ displayName: Build
+ inputs:
+ targetType: inline
+ script: |
+ export HTTP_PROXY=$(PROXY)
+ export HTTPS_PROXY=$(PROXY)
+ export NO_PROXY=$(NO_PROXY)
+ cd $(DOCKER_FILEPATH)
+ ls -al
+ echo $(PWD)
+ docker pull docker-weu.spo.internal.ses.com/eclipse-temurin:19.0.1_10-jre-alpine
+ docker run --rm -e VERSION=$(VERSION_TAG) -e http_proxy=$(PROXY) -e https_proxy=$(PROXY) -e no_proxy=$(NO_PROXY) -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v `pwd`:/app -w /app $(BUILD_IMAGE) sbt docker:publishLocal
+
+ workingDirectory: "$(system.defaultWorkingDirectory)/"
+
+ # - task: Docker@2
+ # displayName: Build
+ # inputs:
+ # command: build
+ # repository: "$(DOCKER_IMAGE)"
+ # containerRegistry: "$(NEXUS_REGISTRY)"
+ # buildContext: "**$(DOCKER_BUILD_CONTEXT)"
+ # Dockerfile: "$(DOCKER_FILEPATH)/Dockerfile"
+ # tags: "$(VERSION_TAG)"
+ # arguments: "--build-arg http_proxy=$(PROXY) --build-arg https_proxy=$(PROXY) --build-arg no_proxy=$(NO_PROXY)"
+ - task: Docker@2
+ displayName: Push
+ inputs:
+ command: push
+ repository: "$(DOCKER_IMAGE)"
+ containerRegistry: "$(NEXUS_REGISTRY)"
+ tags: "$(VERSION_TAG)"
+ - task: NexusIqPipelineTask@1
+ env:
+ NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD: $(NEXUS_PASSWORD)
+ NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD: $(NEXUS_PASSWORD)
+ inputs:
+ nexusIqService: 'nexus-iq'
+ organizationId: 'b57c0bd6dfd247fa964dbc4cbfdf2f2a'
+ applicationId: '$(NEXUS_APPLICATION)'
+ stage: 'Build'
+ scanTargets: 'container:https://$(NEXUS_REGISTRY_URL)/$(DOCKER_IMAGE):$(VERSION_TAG)'
+ enableDebugLogging: true
+ ignoreSystemError: true
+ ignoreScanningError: true
diff --git a/azure_pipelines/ci_spell_server.yaml b/azure_pipelines/ci_spell_server.yaml
new file mode 100644
index 0000000..3b1f681
--- /dev/null
+++ b/azure_pipelines/ci_spell_server.yaml
@@ -0,0 +1,147 @@
+# Starter pipeline
+# Start with a minimal pipeline that you can customize to build and deploy your code.
+# Add steps that build, run tests, deploy, and more:
+# https://aka.ms/yaml
+
+trigger:
+ branches:
+ include:
+ - develop
+ paths:
+ include:
+ - azure_pipelines/variables/spell_server.yaml
+ - azure_pipelines/variables/baseline.yaml
+ - azure_pipelines/ci_spell_server.yaml
+ - lib/**
+ - src/**
+ - include/**
+ - configure.ac
+ - RELEASENOTES
+ - build_spell_ubuntu.sh
+ - docker/spell-server/**
+ - proto/**
+ - protos/**
+
+
+name: "SPELL Server CI Pipeline"
+
+pool:
+ name: weu1-d-keda
+
+variables:
+- template: variables/baseline.yaml
+- name: tags
+ value: "$(Build.DefinitionName)_$(Build.DefinitionVersion)_$(Build.BuildId)_$(Build.BuildNumber)"
+- name: DOCKER_BUILDKIT
+ value: 1
+- name: NODE_TLS_REJECT_UNAUTHORIZED
+ value: 0
+- template: variables/spell_server.yaml
+- group: nexus-auth
+- name: NEXUS_CONTAINER_SCANNING_SCANNER_IMAGE
+ value: neuvector/scanner
+- name: NEXUS_CONTAINER_SCANNING_REGISTRY_URL
+ value: https://docker-weu.spo.internal.ses.com
+- name: NEXUS_CONTAINER_IMAGE_REGISTRY_USER
+ value: $(NEXUS_USER)
+- name: NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD
+ value: $(NEXUS_PASSWORD)
+- name: NEXUS_CONTAINER_SCANNING_REGISTRY_USER
+ value: $(NEXUS_USER)
+- name: NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD
+ value: $(NEXUS_PASSWORD)
+
+
+stages:
+- stage:
+ displayName: Nexus IQ Check
+ jobs:
+ - job:
+ displayName: Docker image
+ steps:
+ - task: Bash@3
+ displayName: Extract Version
+ inputs:
+ targetType: inline
+ script: |
+ get_next_version() {
+ local increment_type="$1"
+ local RE='([0-9]*)[.]([0-9]*)[.]([0-9]*)([.-][0-9A-Za-z.-]+)?'
+
+ if [ -z "$increment_type" ]; then
+ increment_type="patch"
+ fi
+ if [[ "$2" =~ $RE ]]; then
+ local MAJOR="${BASH_REMATCH[1]}"
+ local MINOR="${BASH_REMATCH[2]}"
+ local PATCH="${BASH_REMATCH[3]}"
+ local pre=""
+ else
+ local MAJOR=0
+ local MINOR=0
+ local PATCH=0
+ local pre=""
+ fi
+
+ case "$increment_type" in
+ major)
+ ((MAJOR += 1))
+ ((MINOR = 0))
+ ((PATCH = 0))
+ ;;
+ minor)
+ ((MINOR += 1))
+ ((PATCH = 0))
+ ;;
+ patch)
+ ((PATCH += 1))
+ ;;
+ esac
+
+ local NEXT_VERSION="$MAJOR.$MINOR.$PATCH"
+ echo "$NEXT_VERSION"
+ }
+
+ HEAD=`git rev-parse --short HEAD` && echo HEAD: ${HEAD}
+ VERSION_TAG=`git describe --abbrev=0 --tags ${HEAD} 2>/dev/null || true` && echo VERSION_TAG: ${VERSION_TAG}
+ TAG_COMMIT=`git rev-list -n 1 --abbrev-commit ${VERSION_TAG}` && echo TAG_COMMIT: ${TAG_COMMIT}
+ if [[ "$HEAD" != "$TAG_COMMIT" ]]
+ then
+ VERSION_TAG=`get_next_version patch ${VERSION_TAG}`
+ fi
+ echo "##vso[task.setvariable variable=VERSION_TAG]$VERSION_TAG"
+ echo "ADO Tag: $(tags)"
+ echo "New Version to be built: ${VERSION_TAG}"
+
+ workingDirectory: "$(system.defaultWorkingDirectory)/"
+ - task: Docker@2
+ displayName: Build
+ inputs:
+ command: build
+ repository: "$(DOCKER_IMAGE)"
+ containerRegistry: "$(NEXUS_REGISTRY)"
+ buildContext: "**$(DOCKER_BUILD_CONTEXT)"
+ Dockerfile: "$(DOCKER_FILEPATH)/Dockerfile"
+ tags: "$(VERSION_TAG)"
+ arguments: "--build-arg RUNTIME_IMAGE=$(RUNTIME_IMAGE) --build-arg VERSION_TAG=$(VERSION_TAG) --build-arg BUILD_IMAGE=$(BUILD_IMAGE) --build-arg http_proxy=$(PROXY) --build-arg https_proxy=$(PROXY) --build-arg no_proxy=$(NO_PROXY)"
+ - task: Docker@2
+ displayName: Push
+ inputs:
+ command: push
+ repository: "$(DOCKER_IMAGE)"
+ containerRegistry: "$(NEXUS_REGISTRY)"
+ tags: "$(VERSION_TAG)"
+ - task: NexusIqPipelineTask@1
+ continueOnError: true
+ env:
+ NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD: $(NEXUS_PASSWORD)
+ NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD: $(NEXUS_PASSWORD)
+ inputs:
+ nexusIqService: 'nexus-iq'
+ organizationId: 'b57c0bd6dfd247fa964dbc4cbfdf2f2a'
+ applicationId: '$(NEXUS_APPLICATION)'
+ stage: 'Build'
+ scanTargets: 'container:https://$(NEXUS_REGISTRY_URL)/$(DOCKER_IMAGE):$(VERSION_TAG)'
+ enableDebugLogging: true
+ ignoreSystemError: true
+ ignoreScanningError: true
diff --git a/azure_pipelines/ci_spell_ssh.yaml b/azure_pipelines/ci_spell_ssh.yaml
new file mode 100644
index 0000000..50f3b6f
--- /dev/null
+++ b/azure_pipelines/ci_spell_ssh.yaml
@@ -0,0 +1,139 @@
+# Starter pipeline
+# Start with a minimal pipeline that you can customize to build and deploy your code.
+# Add steps that build, run tests, deploy, and more:
+# https://aka.ms/yaml
+
+
+trigger:
+ branches:
+ include:
+ - develop
+ paths:
+ include:
+ - azure_pipelines/variables/spell_ssh.yaml
+ - azure_pipelines/variables/baseline.yaml
+ - azure_pipelines/ci_spell_ssh.yaml
+ - docker/ssh-server/**
+
+
+name: "SPELL SSH Server CI Pipeline"
+
+pool:
+ name: weu1-d-keda
+
+variables:
+- template: variables/baseline.yaml
+- name: tags
+ value: "$(Build.DefinitionName)_$(Build.DefinitionVersion)_$(Build.BuildId)_$(Build.BuildNumber)"
+- name: DOCKER_BUILDKIT
+ value: 1
+- name: NODE_TLS_REJECT_UNAUTHORIZED
+ value: 0
+- template: variables/spell_ssh.yaml
+- group: nexus-auth
+- name: NEXUS_CONTAINER_SCANNING_SCANNER_IMAGE
+ value: neuvector/scanner
+- name: NEXUS_CONTAINER_SCANNING_REGISTRY_URL
+ value: https://docker-weu.spo.internal.ses.com
+- name: NEXUS_CONTAINER_IMAGE_REGISTRY_USER
+ value: $(NEXUS_USER)
+- name: NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD
+ value: $(NEXUS_PASSWORD)
+- name: NEXUS_CONTAINER_SCANNING_REGISTRY_USER
+ value: $(NEXUS_USER)
+- name: NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD
+ value: $(NEXUS_PASSWORD)
+
+stages:
+- stage:
+ displayName: Nexus IQ Check
+ jobs:
+ - job:
+ displayName: Docker image
+ steps:
+ - task: Bash@3
+ displayName: Extract Version
+ inputs:
+ targetType: inline
+ script: |
+ get_next_version() {
+ local increment_type="$1"
+ local RE='([0-9]*)[.]([0-9]*)[.]([0-9]*)([.-][0-9A-Za-z.-]+)?'
+
+ if [ -z "$increment_type" ]; then
+ increment_type="patch"
+ fi
+ if [[ "$2" =~ $RE ]]; then
+ local MAJOR="${BASH_REMATCH[1]}"
+ local MINOR="${BASH_REMATCH[2]}"
+ local PATCH="${BASH_REMATCH[3]}"
+ local pre=""
+ else
+ local MAJOR=0
+ local MINOR=0
+ local PATCH=0
+ local pre=""
+ fi
+
+ case "$increment_type" in
+ major)
+ ((MAJOR += 1))
+ ((MINOR = 0))
+ ((PATCH = 0))
+ ;;
+ minor)
+ ((MINOR += 1))
+ ((PATCH = 0))
+ ;;
+ patch)
+ ((PATCH += 1))
+ ;;
+ esac
+
+ local NEXT_VERSION="$MAJOR.$MINOR.$PATCH"
+ echo "$NEXT_VERSION"
+ }
+
+ HEAD=`git rev-parse --short HEAD` && echo HEAD: ${HEAD}
+ VERSION_TAG=`git describe --abbrev=0 --tags ${HEAD} 2>/dev/null || true` && echo VERSION_TAG: ${VERSION_TAG}
+ TAG_COMMIT=`git rev-list -n 1 --abbrev-commit ${VERSION_TAG}` && echo TAG_COMMIT: ${TAG_COMMIT}
+ if [[ "$HEAD" != "$TAG_COMMIT" ]]
+ then
+ VERSION_TAG=`get_next_version patch ${VERSION_TAG}`
+ fi
+ echo "##vso[task.setvariable variable=VERSION_TAG]$VERSION_TAG"
+ echo "ADO Tag: $(tags)"
+ echo "New Version to be built: ${VERSION_TAG}"
+
+ workingDirectory: "$(system.defaultWorkingDirectory)/"
+ - task: Docker@2
+ displayName: Build
+ inputs:
+ command: build
+ repository: "$(DOCKER_IMAGE)"
+ containerRegistry: "$(NEXUS_REGISTRY)"
+ buildContext: "**$(DOCKER_BUILD_CONTEXT)"
+ Dockerfile: "$(DOCKER_FILEPATH)/Dockerfile"
+ tags: "$(VERSION_TAG)"
+ arguments: "--build-arg RUNTIME_IMAGE=$(RUNTIME_IMAGE) --build-arg BUILD_IMAGE=$(BUILD_IMAGE) --build-arg http_proxy=$(PROXY) --build-arg https_proxy=$(PROXY) --build-arg no_proxy=$(NO_PROXY)"
+ - task: Docker@2
+ displayName: Push
+ inputs:
+ command: push
+ repository: "$(DOCKER_IMAGE)"
+ containerRegistry: "$(NEXUS_REGISTRY)"
+ tags: "$(VERSION_TAG)"
+ - task: NexusIqPipelineTask@1
+ continueOnError: true
+ env:
+ NEXUS_CONTAINER_IMAGE_REGISTRY_PASSWORD: $(NEXUS_PASSWORD)
+ NEXUS_CONTAINER_SCANNING_REGISTRY_PASSWORD: $(NEXUS_PASSWORD)
+ inputs:
+ nexusIqService: 'nexus-iq'
+ organizationId: 'b57c0bd6dfd247fa964dbc4cbfdf2f2a'
+ applicationId: '$(NEXUS_APPLICATION)'
+ stage: 'Build'
+ scanTargets: 'container:https://$(NEXUS_REGISTRY_URL)/$(DOCKER_IMAGE):$(VERSION_TAG)'
+ enableDebugLogging: true
+ ignoreSystemError: true
+ ignoreScanningError: true
\ No newline at end of file
diff --git a/azure_pipelines/variables/baseline.yaml b/azure_pipelines/variables/baseline.yaml
new file mode 100644
index 0000000..42845a7
--- /dev/null
+++ b/azure_pipelines/variables/baseline.yaml
@@ -0,0 +1,8 @@
+variables:
+ NEXUS_REGISTRY: nexus-docker-weu
+ NEXUS_REGISTRY_URL: docker-weu.spo.internal.ses.com
+ BUILD_IMAGE: docker-weu.spo.internal.ses.com/spell/spell-cots-ubuntu-build:1.0.1
+ RUNTIME_IMAGE: docker-weu.spo.internal.ses.com/spell/spell-cots-ubuntu-runtime:1.0.1
+ PROXY: "${HTTPS_PROXY}"
+ NO_PROXY: "${NO_PROXY}"
+
\ No newline at end of file
diff --git a/azure_pipelines/variables/logrotate.yaml b/azure_pipelines/variables/logrotate.yaml
new file mode 100644
index 0000000..1db6d1f
--- /dev/null
+++ b/azure_pipelines/variables/logrotate.yaml
@@ -0,0 +1,5 @@
+variables:
+ DOCKER_FILEPATH: docker/logrotate
+ DOCKER_IMAGE: spell/logrotate-ubuntu
+ NEXUS_APPLICATION: spell-logrotate
+ DOCKER_BUILD_CONTEXT: ""
\ No newline at end of file
diff --git a/azure_pipelines/variables/spell_driver_scorpio.yaml b/azure_pipelines/variables/spell_driver_scorpio.yaml
new file mode 100644
index 0000000..26d1700
--- /dev/null
+++ b/azure_pipelines/variables/spell_driver_scorpio.yaml
@@ -0,0 +1,5 @@
+variables:
+ DOCKER_FILEPATH: docker/drivers/scorpio
+ DOCKER_IMAGE: spell/spell-driver-ubuntu-scorpio
+ NEXUS_APPLICATION: spell-scorpio-driver
+ DOCKER_BUILD_CONTEXT: "/../"
\ No newline at end of file
diff --git a/azure_pipelines/variables/spell_registry.yaml b/azure_pipelines/variables/spell_registry.yaml
new file mode 100644
index 0000000..627aec2
--- /dev/null
+++ b/azure_pipelines/variables/spell_registry.yaml
@@ -0,0 +1,8 @@
+variables:
+ DOCKER_FILEPATH: docker/spell-registry
+ DOCKER_IMAGE: spell/spell-registry
+ NEXUS_APPLICATION: spell-registry
+ DOCKER_BUILD_CONTEXT: "."
+ BUILD_IMAGE: docker-weu.spo.internal.ses.com/sbtscala/scala-sbt:eclipse-temurin-19_36_1.8.0_3.2.1
+ #scala-sbt:eclipse-temurin-focal-17.0.10_7_1.9.9_3.4.0
+
\ No newline at end of file
diff --git a/azure_pipelines/variables/spell_server.yaml b/azure_pipelines/variables/spell_server.yaml
new file mode 100644
index 0000000..b359dc8
--- /dev/null
+++ b/azure_pipelines/variables/spell_server.yaml
@@ -0,0 +1,5 @@
+variables:
+ DOCKER_FILEPATH: docker/spell-server
+ DOCKER_IMAGE: spell/spell-server-ubuntu
+ NEXUS_APPLICATION: spell-server
+ DOCKER_BUILD_CONTEXT: "/../"
\ No newline at end of file
diff --git a/azure_pipelines/variables/spell_ssh.yaml b/azure_pipelines/variables/spell_ssh.yaml
new file mode 100644
index 0000000..29aebca
--- /dev/null
+++ b/azure_pipelines/variables/spell_ssh.yaml
@@ -0,0 +1,5 @@
+variables:
+ DOCKER_FILEPATH: docker/ssh-server
+ DOCKER_IMAGE: spell/ssh-server-ubuntu
+ NEXUS_APPLICATION: spell-ssh-server
+ DOCKER_BUILD_CONTEXT: ""
\ No newline at end of file
diff --git a/build_driver.sh b/build_driver.sh
new file mode 100644
index 0000000..1a3c113
--- /dev/null
+++ b/build_driver.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+function die() {
+ echo -e >&2 "ERROR: $@"
+ echo "Usage: $(basename $0) install-path hifly|scorpio|fuzzer"
+ exit 1
+}
+
+# sanity checks
+[ $# -ge 2 ] || die "Invalid arguments.\n\
+Please specify installation path and the driver."
+SPELL_HOME=$1
+[ -d $SPELL_HOME ] || die "cannot find the given installation directory: $SPELL_HOME"
+
+shift
+DRIVER=$1
+[[ "$DRIVER" == "hifly" ]] || [[ "$DRIVER" == "scorpio" ]] || [[ "$DRIVER" == "fuzzer" ]] || [[ "$DRIVER" == "example" ]] || die "Unknown driver \"$DRIVER\""
+shift
+DEPS=$1
+shift
+
+! [ -z $SPELL_COTS ] || die "Set SPELL_COTS environment variable"
+[ -d $SPELL_COTS ] || die "cannot find the SPELL_COTS directory: $SPELL_COTS"
+[ "$(ls -A $SPELL_COTS)" ] || die "SPELL_COTS directory $SPELL_COTS is empty"
+
+export LD_LIBRARY_PATH=$SPELL_COTS/lib
+export PATH=$SPELL_COTS/bin:$PATH
+
+
+if [[ "$DRIVER" == "hifly" ]]; then
+ DRIVER="--enable-hiflydriver --with-exif=6"
+ DRIVER_FOLDER="hifly2"
+elif [[ "$DRIVER" == "scorpio" ]]; then
+ DRIVER="--enable-scorpiodriver"
+ DRIVER_FOLDER="scorpio"
+elif [[ "$DRIVER" == "fuzzer" ]]; then
+ DRIVER="--enable-fuzzerdriver"
+ DRIVER_FOLDER="fuzzer"
+elif [[ "$DRIVER" == "example" ]]; then
+ DRIVER="--enable-exampledriver"
+ DRIVER_FOLDER="example"
+fi
+
+autoreconf -fi .|| die "autoreconf failed!"
+mkdir -p build
+rm -rf build/* > /dev/null 2>&1
+cd build
+set -x
+LSAN_OPTIONS=verbosity=1:log_threads=1 ASAN_OPTIONS=halt_on_error=0 ../configure --disable-dependency-tracking --enable-address-sanitizer --prefix=$SPELL_HOME $DRIVER --enable-pace CPPFLAGS="-w -I$SPELL_COTS/include $@" LDFLAGS="-Wl,--copy-dt-needed-entries -L$SPELL_COTS/lib"
+
+for dep in ${DEPS}; do
+ pushd lib/${dep}
+ make -j4 -s && make install
+ popd
+done
+
+cd drivers/${DRIVER_FOLDER}
+set +x
+make -j4 -s && make install
diff --git a/build_spell.sh b/build_spell.sh
new file mode 100644
index 0000000..fb5099a
--- /dev/null
+++ b/build_spell.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+function die() {
+ echo -e >&2 "ERROR: $@"
+ echo "Usage: $(basename $0) install-path hifly|scorpio|fuzzer"
+ exit 1
+}
+
+# sanity checks
+[ $# -ge 2 ] || die "Invalid arguments.\n\
+Please specify installation path and the driver."
+SPELL_HOME=$1
+[ -d $SPELL_HOME ] || die "cannot find the given installation directory: $SPELL_HOME"
+! [ "$(ls -A $SPELL_HOME)" ] || die "installation directory $SPELL_HOME must be empty"
+shift
+DRIVER=$1
+[[ "$DRIVER" == "hifly" ]] || [[ "$DRIVER" == "scorpio" ]] || [[ "$DRIVER" == "fuzzer" ]] || [[ "$DRIVER" == "none" ]] || die "Unknown driver \"$DRIVER\""
+shift
+
+! [ -z $SPELL_COTS ] || die "Set SPELL_COTS environment variable"
+[ -d $SPELL_COTS ] || die "cannot find the SPELL_COTS directory: $SPELL_COTS"
+[ "$(ls -A $SPELL_COTS)" ] || die "SPELL_COTS directory $SPELL_COTS is empty"
+
+export LD_LIBRARY_PATH=$SPELL_COTS/lib
+export PATH=$SPELL_COTS/bin:$PATH
+
+export CC="gcc -m32"
+export CXX="g++ -m32"
+
+if [[ "$DRIVER" == "hifly" ]]; then
+ DRIVER="--enable-hiflydriver --with-exif=6"
+elif [[ "$DRIVER" == "scorpio" ]]; then
+ DRIVER="--enable-scorpiodriver"
+elif [[ "$DRIVER" == "fuzzer" ]]; then
+ DRIVER="--enable-fuzzerdriver"
+elif [[ "$DRIVER" == "none" ]]; then
+ DRIVER=""
+fi
+
+git submodule init
+git submodule update
+cd proto
+git checkout develop
+cd ..
+
+autoreconf -fi
+mkdir -p build
+rm -rf build/* > /dev/null 2>&1
+cd build
+set -x
+../configure --prefix=$SPELL_HOME $DRIVER --enable-pace CPPFLAGS="-std=c++11 -I$SPELL_COTS/include $@" LDFLAGS="-L$SPELL_COTS/lib"
+set +x
+make -j4 -s && make install
diff --git a/build_spell_ubuntu.sh b/build_spell_ubuntu.sh
new file mode 100644
index 0000000..f80f2db
--- /dev/null
+++ b/build_spell_ubuntu.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+function die() {
+ echo -e >&2 "ERROR: $@"
+ echo "Usage: $(basename $0) install-path hifly|scorpio|fuzzer"
+ exit 1
+}
+
+# sanity checks
+[ $# -ge 2 ] || die "Invalid arguments.\n\
+Please specify installation path and the driver."
+SPELL_HOME=$1
+[ -d $SPELL_HOME ] || die "cannot find the given installation directory: $SPELL_HOME"
+! [ "$(ls -A $SPELL_HOME)" ] || die "installation directory $SPELL_HOME must be empty"
+shift
+DRIVER=$1
+[[ "$DRIVER" == "hifly" ]] || [[ "$DRIVER" == "scorpio" ]] || [[ "$DRIVER" == "fuzzer" ]] || [[ "$DRIVER" == "none" ]] || die "Unknown driver \"$DRIVER\""
+shift
+
+! [ -z $SPELL_COTS ] || die "Set SPELL_COTS environment variable"
+[ -d $SPELL_COTS ] || die "cannot find the SPELL_COTS directory: $SPELL_COTS"
+[ "$(ls -A $SPELL_COTS)" ] || die "SPELL_COTS directory $SPELL_COTS is empty"
+
+export LD_LIBRARY_PATH=$SPELL_COTS/lib
+export PATH=$SPELL_COTS/bin:$PATH
+
+if [[ "$DRIVER" == "hifly" ]]; then
+ DRIVER="--enable-hiflydriver --with-exif=6"
+elif [[ "$DRIVER" == "scorpio" ]]; then
+ DRIVER="--enable-scorpiodriver"
+elif [[ "$DRIVER" == "fuzzer" ]]; then
+ DRIVER="--enable-fuzzerdriver"
+elif [[ "$DRIVER" == "none" ]]; then
+ DRIVER=""
+fi
+
+mkdir -p build
+rm -rf build/* > /dev/null 2>&1
+
+
+autoreconf -fi . || die "autoconf failed"
+
+cd build
+set -x
+../configure --enable-address-sanitizer --prefix=$SPELL_HOME $DRIVER --enable-pace CPPFLAGS="-I$SPELL_COTS/include -fno-omit-frame-pointer $@" LDFLAGS="-rdynamic -ldw -Wl,--copy-dt-needed-entries -L$SPELL_COTS/lib" || die "configure failed"
+set +x
+make -j4 -s || die "build failed"
+
+make install || die "install failed"
diff --git a/common.mk b/common.mk
index e9701b6..b0d85e1 100644
--- a/common.mk
+++ b/common.mk
@@ -1,11 +1,11 @@
###################################################################################
## FILE : common.mk
-## DATE : Mar 17, 2011
+## DATE : May 11, 2017
## PROJECT : SPELL
-## DESCRIPTION: Automake rules
+## DESCRIPTION: Common compilation and linking flags
## --------------------------------------------------------------------------------
##
-## Copyright (C) 2008, 2012 SES ENGINEERING, Luxembourg S.A.R.L.
+## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
##
## This file is part of SPELL.
##
@@ -23,10 +23,7 @@
## along with SPELL. If not, see .
##
###################################################################################
-
-AUTOMAKE_OPTIONS=foreign
-#REMOVED -O2
-AM_CPPFLAGS = -I$(top_srcdir)/include -I${SPELL_COTS}/include $(PYTHON_CPPFLAGS) -I${WITH_LOG4CPLUS}/include -fPIC -fno-strict-aliasing -g3 -Wall -c -fmessage-length=0 -MMD -MP
-AM_LDFLAGS = $(PYTHON_LDFLAGS) $(PYTHON_EXTRA_LIBS) $(PYTHON_EXTRA_LDFLAGS) -L/usr/local/lib -L${WITH_LOG4CPLUS}/lib -llog4cplus
-RSYNC=rsync -av --exclude-from=${top_srcdir}/exclude.list
-
+AUTOMAKE_OPTIONS = subdir-objects foreign
+AM_CPPFLAGS = -I${top_srcdir}/include -Wall -fno-strict-aliasing -fmessage-length=0 -MMD
+AM_LDFLAGS = ${LIBS} -lxerces-c -lz -lrt -llog4cplus
+RELEASE_LDFLAG = -release ${PACKAGE_VERSION}
diff --git a/config/Makefile.am b/config/Makefile.am
index ba52126..76b24e8 100644
--- a/config/Makefile.am
+++ b/config/Makefile.am
@@ -1,53 +1,29 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
-include ${top_srcdir}/common.mk
+SRC=${srcdir}
+DST=${exec_prefix}/config
install-exec-hook:
- mkdir -p ${exec_prefix}/config
-if HAVE_RSYNC
-if WITH_LIBS
- $(RSYNC) ${top_srcdir}/config/server ${exec_prefix}/config/
- $(RSYNC) ${top_srcdir}/config/contexts ${exec_prefix}/config/
-endif
- $(RSYNC) ${top_srcdir}/config/spell ${exec_prefix}/config/
-if WITH_GUI
- $(RSYNC) ${top_srcdir}/config/gui ${exec_prefix}/config/
-endif
-
-else
-
-if WITH_LIBS
- cp -r ${top_srcdir}/config/server ${exec_prefix}/config/.
- cp -r ${top_srcdir}/config/contexts ${exec_prefix}/config/.
-endif
- cp -r ${top_srcdir}/config/spell ${exec_prefix}/config/.
-if WITH_GUI
- cp -r ${top_srcdir}/config/gui ${exec_prefix}/config/.
-endif
- find ${exec_prefix}/config -name ".svn" | xargs rm -rf
-endif
-
+ mkdir -p ${DST}
+ cp -ur ${SRC}/contexts ${DST}
+ cp -ur ${SRC}/server ${DST}
+ cp -ur ${SRC}/spell ${DST}
diff --git a/config/contexts/context_example.xml b/config/contexts/context_example.xml
new file mode 100644
index 0000000..61be975
--- /dev/null
+++ b/config/contexts/context_example.xml
@@ -0,0 +1,83 @@
+
+
+
+
+
+ Example context
+ Exmaple context description
+
+
+
+
+ example
+
+
+
+
+ Y
+ Spacecraft
+ X
+ N/A
+
+
+
+
+ $SPELL_DATA/Procedures
+ $SPELL_DATA/UserLib
+ $SPELL_DATA
+ $SPELL_DATA
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 30
+ True
+ False
+ False
+ 5
+
+ DISABLED
+ DISABLED
+ DISABLED
+ False
+
+
+
+
+
+
+
+ SpacecraftDB
+ GroundDB
+ ManeuvreMessage
+ User
+ OutputFiles/AsRun
+ OutputFiles/Warmstart
+ SCDB
+ GDB
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/server/server_example.xml b/config/server/server_example.xml
new file mode 100644
index 0000000..b228ac6
--- /dev/null
+++ b/config/server/server_example.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+ ENABLED
+ PROC
+
+ 9
+
+
+
+
+
+
+ language.xml
+
+
+
+
+
+
+ 9980
+ 9981
+
+
+
+ $SPELL_HOME/bin/SPELL-Executor
+ false
+
+
+
+
+
+
+ 0
+ True
+ False
+ True
+ 5
+ ON_LINE
+ ENABLED
+ ENABLED
+ False
+
+
+
+
+
+
+ driver_example.xml
+
+
+
+
+
+
+ context_example.xml
+
+
+
+
+
+
+ Y
+
+
+
diff --git a/config/spell/language.xml b/config/spell/language.xml
index 575d25c..ab9f0c2 100644
--- a/config/spell/language.xml
+++ b/config/spell/language.xml
@@ -29,6 +29,70 @@
False
False
+
+
+
+
+ ABORT|SKIP|RESEND|CANCEL
+ True
+ 0
+ 30
+ 0.1
+ None
+ False
+ True
+ ABORT|SKIP|RESEND|CANCEL
+ NOACTION
+ False
+ False
+
+
+
+ ABORT|SKIP|REPEAT
+ True
+ 1
+
+
+
+ ABORT|SKIP|REPEAT
+ True
+ 1
+
+
+
+ ABORT|SKIP|REPEAT
+ True
+ 1
+
+
+
+ ABORT|SKIP|REPEAT
+ True
+ 1
+
+
+
+ ABORT|REPEAT|RESEND|RECHECK|SKIP|CANCEL
+ ABORT|REPEAT|RESEND|RECHECK|SKIP|CANCEL
+ True
+ 1
+
+
+
+ ABORT|REPEAT|RESEND|RECHECK|SKIP|CANCEL
+ ABORT|REPEAT|RESEND|RECHECK|SKIP|CANCEL
+ True
+ 1
+
+
+
+ ABORT|SKIP|REPEAT
+ True
+ 1
+
+
+
+
ABORT|SKIP|REPEAT|CANCEL
@@ -210,6 +274,18 @@
ABORT|SKIP|REPEAT
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+
ABORT|SKIP|REPEAT
diff --git a/configure.ac b/configure.ac
index ab949b0..221a86b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,263 +1,271 @@
################################################################################
-#
-# FILE : configure.ac
-# DESCRIPTION: automake and autoconf configuration file, and source for the
-# 'configure' script. Describes the structure and organization
-# of all makefiles to be generated in order to build SPELL.
-#
-# LICENSE ------------------------------------------------------------------
-#
-#
-# Copyright (C) 2008, 2012 SES ENGINEERING, Luxembourg S.A.R.L.
#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
# This file is part of SPELL.
-#
-# SPELL is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# SPELL is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with SPELL. If not, see .
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
#
################################################################################
+AC_INIT([SPELL],
+ [m4_esyscmd([scripts/src/version.sh])],
+ [juergen.gall@ses.com, raimondas.sasnauskas@ses.com])
+AM_INIT_AUTOMAKE([1.9 tar-pax -Wall -Werror foreign subdir-objects])
-AC_INIT([SPELL], [2.4], [])
-AM_INIT_AUTOMAKE([1.9 tar-pax -Wall -Werror foreign])
+AC_CONFIG_SRCDIR([configure.ac])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
-CXXFLAGS=
-
+AM_DISABLE_STATIC
#------------------------------------------------------------------------------#
# Checks for basic standard programs
#------------------------------------------------------------------------------#
AC_PROG_CC
AC_PROG_CXX
+m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AC_PROG_LIBTOOL
AC_PROG_INSTALL
AC_PROG_MAKE_SET
-AM_PATH_PYTHON
+#AM_PATH_PYTHON
+
+AC_CHECK_PROG(protoc, protoc, true)
+if [ test x$protoc != xtrue ]
+then
+ AC_MSG_ERROR([Protobuf compiler protoc required to compile SPELL])
+fi
#------------------------------------------------------------------------------#
-# Checks for some development headers (POSIX-threads,C++ standard library)
+# Checks for some development headers (POSIX-threads, C++ standard library)
#------------------------------------------------------------------------------#
AC_HEADER_STDC
AC_LANG_CPLUSPLUS
-AC_CHECK_HEADER(pthread.h,,AC_MSG_ERROR(POSIX threads library is required))
-
-AC_CHECK_LIB([rt] , [clock_gettime] ,,[AC_MSG_ERROR(rt library is required)] )
-AC_CHECK_LIB([dl] , [dlopen] ,,[AC_MSG_ERROR(dl library is required)] )
-AC_CHECK_LIB([util] , [openpty] ,,[AC_MSG_ERROR(util library is required)] )
-AC_CHECK_LIB([xerces-c] , [_init] ,,[AC_MSG_ERROR(xerces-c library is required)])
-AX_PYTHON_DEVEL([])
-
-
-#------------------------------------------------------------------------------#
-# Conditional: check the platform in order to know which scripts to use
-#------------------------------------------------------------------------------#
-AM_CONDITIONAL(PLATFORM_LINUX, test ! -z `echo $host_os | grep "linux"`)
-
-#------------------------------------------------------------------------------#
-# Conditional: check rsync availability
-#------------------------------------------------------------------------------#
-AM_CONDITIONAL(HAVE_RSYNC, test `which rsync`)
-
-#------------------------------------------------------------------------------#
-# ENABLE argument to activate or deactivate the SPELL Executor component
-#------------------------------------------------------------------------------#
-AC_ARG_ENABLE([executor],
- [AS_HELP_STRING([--enable-executor],[Compile the executor process (default is yes) ])] ,
- [executor=true],
- [executor=true])
-AM_CONDITIONAL([WITH_EXECUTOR], [test x$executor = xtrue])
-
-
-#------------------------------------------------------------------------------#
-# ENABLE argument to activate or deactivate the SPELL Executor Command Line
-#------------------------------------------------------------------------------#
-AC_ARG_ENABLE([executorcmd],
- [AS_HELP_STRING([--enable-executorcmd],[Compile the command line executor (default is no) ])],
- [executorcmd=true],
- [executorcmd=false])
-AM_CONDITIONAL([WITH_EXECUTOR_CMD], [test x$executorcmd = xtrue])
-
-
-#------------------------------------------------------------------------------#
-# ENABLE argument to activate or deactivate the SPELL GUI component
-#------------------------------------------------------------------------------#
-AC_ARG_ENABLE([gui],
- [AS_HELP_STRING([--enable-gui],[Compile the SPELL-GUI (default is no) ])],
- [gui=true],
- [gui=false])
-AM_CONDITIONAL([WITH_GUI], [test x$gui = xtrue])
-
-
-#------------------------------------------------------------------------------#
-# ENABLE argument to activate or deactivate the SPELL standalone driver
-#------------------------------------------------------------------------------#
-AC_ARG_ENABLE([driverstd],
- [AS_HELP_STRING([--enable-driverstd],[Compile the SPELL standalone driver (default is no) ])],
- [driverstd=true],
- [driverstd=false])
-AM_CONDITIONAL([WITH_DRIVER_STD], [test x$driverstd = xtrue])
-
-
-#------------------------------------------------------------------------------#
-# ENABLE argument to activate or deactivate the SPELL Shell component
-#------------------------------------------------------------------------------#
-AC_ARG_ENABLE([shell],
- [AS_HELP_STRING([--enable-shell],[Compile the SPELL shell (default is yes) ])],
- [shell=true],
- [shell=true])
-AM_CONDITIONAL([WITH_SHELL], [test x$shell = xtrue])
-
-
-#------------------------------------------------------------------------------#
-# ENABLE argument to activate or deactivate the SPELL Listener component
-#------------------------------------------------------------------------------#
-AC_ARG_ENABLE([listener],
- [AS_HELP_STRING([--enable-listener],[Compile the SPELL listener process (default is yes) ])],
- [listener=true],
- [listener=true])
-AM_CONDITIONAL([WITH_LISTENER], [test x$listener = xtrue])
-
-
-#------------------------------------------------------------------------------#
-# ENABLE argument to activate or deactivate the SPELL Context component
-#------------------------------------------------------------------------------#
-AC_ARG_ENABLE([context],
- [AS_HELP_STRING([--enable-context],[Compile the SPELL context process (default is yes) ])],
- [context=true],
- [context=true])
-AM_CONDITIONAL([WITH_CONTEXT], [test x$context = xtrue])
-
-#------------------------------------------------------------------------------#
-# ENABLE argument to activate or deactivate the documentation build
-#------------------------------------------------------------------------------#
-AC_ARG_ENABLE([documentation],
- [AS_HELP_STRING([--enable-documentation],[Compile the SPELL documentation (default is no) ])],
- [documentation=true],
- [documentation=false])
-AM_CONDITIONAL([WITH_DOCUMENTATION], [test x$documentation = xtrue])
-
-
-#------------------------------------------------------------------------------#
-# ENABLE argument to activate or deactivate the sample procedures
-#------------------------------------------------------------------------------#
-AC_ARG_ENABLE([procs],
- [AS_HELP_STRING([--enable-procs],[Include the sample procedures (default is no) ])],
- [procs=true],
- [procs=false])
-AM_CONDITIONAL([WITH_PROCS], [test x$procs = xtrue])
-
-#------------------------------------------------------------------------------#
-# WITH argument to indicate the path to the Eclipse installation used to
-# compile the RCP applications. Shall be of version 3.7.
-#------------------------------------------------------------------------------#
-AC_ARG_WITH([eclipse],
- [AS_HELP_STRING([--with-eclipse=PATH],[eclipse installation used to compile RCP components])],
- [
- echo "using eclipse at ${withval}"
- if [[ ! -d ${withval} ]]
- then
- AC_MSG_ERROR([Unable to find the eclipse installation: ${withval}])
- fi
- with_eclipse_inst=${withval}
+PYTHON2_VERSION=2
+AC_PYTHON_DEVEL_V2
+PYTHON3_VERSION=3
+AC_PYTHON_DEVEL_V3
+AC_CHECK_HEADER(pthread.h,,AC_MSG_ERROR([pthread.h is required (POSIX threads library)]))
+AC_CHECK_HEADER(ncurses.h,,AC_MSG_ERROR([ncurses.h is required]))
+PKG_PROG_PKG_CONFIG
+
+AC_CHECK_LIB([rt] , [clock_gettime] ,[:],[AC_MSG_ERROR(rt library is required)])
+AC_CHECK_LIB([dl] , [dlopen] ,[:],[AC_MSG_ERROR(dl library is required)])
+AC_CHECK_LIB([util] , [openpty] ,[:],[AC_MSG_ERROR(util library is required)])
+AC_CHECK_LIB([xerces-c] , [_init] ,[:],[AC_MSG_ERROR(xerces-c library is required)])
+AC_CHECK_LIB([z] , [inflate] ,[:],[AC_MSG_ERROR(zlib library is required)])
+AC_CHECK_LIB([menu] , [_init] ,[:],[AC_MSG_ERROR(menu library is required)])
+AC_CHECK_LIB([ncurses] , [initscr] ,[:],[AC_MSG_ERROR(ncurses library is required)])
+AC_CHECK_LIB([ncursesw] , [initscr] ,[:],[AC_MSG_ERROR(ncursesw library is required)])
+AC_CHECK_LIB([log4cplus], [_init] ,[:],[AC_MSG_ERROR(log4cplus library is required)])
+
+#------------------------------------------------------------------------------#
+# ENABLE argument to activate or deactivate the SPELL hifly driver
+#------------------------------------------------------------------------------#
+AC_ARG_ENABLE([hiflydriver],
+ [AS_HELP_STRING([--enable-hiflydriver],[Compile the hifly driver (default is no) ])],
+ [hiflydriver=true],
+ [hiflydriver=false])
+AM_CONDITIONAL([WITH_DRIVER_HIFLY], [test x$hiflydriver = xtrue])
+
+#------------------------------------------------------------------------------#
+# WITH argument to indicate the EXIF version for the hifly driver 2.0
+#------------------------------------------------------------------------------#
+AC_ARG_WITH([exif],
+ [AS_HELP_STRING([--with-exif=5 or 6],[hifly EXIF version to be used ])],
+ [
+ case "${withval}" in
+ 5) with_exif_version=EXIF5 ;;
+ 6) with_exif_version=EXIF6 ;;
+ *) AC_MSG_ERROR([bad value ${withval} for --with-exif]) ;;
+ esac
],
[])
-WITH_ECLIPSE=
-AS_IF([ test "x$with_eclipse_inst" != x],
- [AC_SUBST([WITH_ECLIPSE],[${with_eclipse_inst}])],
+WITH_EXIF=
+AS_IF([ test "x$with_exif_version" != x],
+ [AC_SUBST([WITH_EXIF],[${with_exif_version}])],
[])
#------------------------------------------------------------------------------#
-# WITH argument to indicate the path to the Log4CPlus library
+# Hifly driver checks
#------------------------------------------------------------------------------#
-AC_ARG_WITH([log4cplus],
- [AS_HELP_STRING([--with-log4cplus=PATH],[path to the Log4C++ libraries])],
- [
- echo "using Log4C++ libraries at ${withval}"
- if [[ ! -d ${withval} ]]
- then
- AC_MSG_ERROR([Unable to find the Log$C++ libraries directory: ${withval}])
- fi
- with_log4cplus=${withval}
- ],
- [
- echo "using default Log4C++ libraries path (/usr)"
- with_log4cplus=/usr
+AS_IF([test x$hiflydriver = xtrue],
+ [
+ if [ test -z "$WITH_EXIF" ]
+ then
+ AC_MSG_ERROR([Must provide the EXIF version (--with-exif) to compile the hifly driver])
+ else
+ echo "using EXIF version $WITH_EXIF"
+ fi
+ ],
+ [])
+
+AS_IF([test x$hiflydriver = xtrue],
+ [
+ # just check for existence, don't create -l flags
+ AC_CHECK_LIB([boost_system], [_init], [AC_SUBST([BOOST_SYSTEM],[boost_system])], [
+ AC_CHECK_LIB([boost-system], [_init], [AC_SUBST([BOOST_SYSTEM],[boost-system])], [
+ AC_MSG_ERROR(boost-system library is required)
])
+ ])
-WITH_LOG4CPLUS=
-AS_IF([ test "x$with_log4cplus" != x],
- [AC_SUBST([WITH_LOG4CPLUS],[${with_log4cplus}])],
+ AC_CHECK_LIB([boost_thread], [_init], [AC_SUBST([BOOST_THREAD],[boost_thread])], [
+ AC_CHECK_LIB([boost-thread], [_init], [AC_SUBST([BOOST_THREAD],[boost-thread])], [
+ AC_MSG_ERROR(boost-thread library is required)
+ ])
+ ])
+ AC_CHECK_LIB([boost_chrono], [_init], [AC_SUBST([BOOST_CHRONO],[boost_chrono])], [
+ AC_CHECK_LIB([boost-chrono], [_init], [AC_SUBST([BOOST_CHRONO],[boost-chrono])], [
+ AC_MSG_ERROR(boost-chrono library is required)
+ ])
+ ])
+ AC_CHECK_LIB([omniORB4] , [_init], [:], [AC_MSG_ERROR(omniORB4 library is required)])
+ AC_CHECK_LIB([omnithread] , [_init], [:], [AC_MSG_ERROR(omnithread library is required)])
+ ],
[])
#------------------------------------------------------------------------------#
-# Some checks to do in case of compiling SPELL-DEV or SPELL-GUI
+# ENABLE argument to activate or deactivate the scorpio driver
+#------------------------------------------------------------------------------#
+AC_ARG_ENABLE([scorpiodriver],
+ [AS_HELP_STRING([--enable-scorpiodriver],[Compile the scorpio driver (default is no) ])],
+ [scorpiodriver=true],
+ [scorpiodriver=false])
+AM_CONDITIONAL([WITH_DRIVER_SCORPIO], [test x$scorpiodriver = xtrue])
+
+#------------------------------------------------------------------------------#
+# Scorpio driver checks
#------------------------------------------------------------------------------#
-AS_IF([ test x$gui = xtrue],
+AS_IF([test x$scorpiodriver = xtrue],
[
- if [[ -z "$WITH_ECLIPSE" ]]
+ AC_CHECK_LIB([zmq], [_init], [:], [AC_MSG_ERROR(zmq library is required)])
+ AC_CHECK_PROG(swig, swig, true)
+ if [ test x$swig != xtrue ]
then
- AC_MSG_ERROR([Must provide an eclipse installation path (--with-eclipse) to compile the SPELL-GUI])
+ AC_MSG_ERROR([SWIG required to compile the scorpio driver])
fi
+ SWIGFULL=`swig -version | grep "SWIG Version" | cut -d' ' -f3`
+ AX_COMPARE_VERSION([$SWIGFULL],[ge],[1.3.36],[],
+ [AC_MSG_ERROR(SWIG version >= 1.3.36 required)])
],
[])
#------------------------------------------------------------------------------#
-# Some checks to do in case of compiling tests
+# ENABLE argument to activate or deactivate the SPELL Unit Tests component
#------------------------------------------------------------------------------#
-AS_IF([ test x$tests = xtrue],
- [
- AC_MSG_WARN(Tests and unit tests programs enabled)
- AC_CHECK_LIB([cppunit],[_init],,[AC_MSG_ERROR(cppunit library is required to compile unit tests)])
- ],
- [
- AC_MSG_WARN(Tests and unit tests programs disabled)
- ])
+AC_ARG_ENABLE([tests],
+ [AS_HELP_STRING([--enable-tests],[Compile the SPELL tests (default is no) ])],
+ [tests=true],
+ [tests=false])
+AM_CONDITIONAL([WITH_TESTS], [test x$tests = xtrue])
-#------------------------------------------------------------------------------#
-# Some checks to do in case of compiling SPELL executor command line
-#------------------------------------------------------------------------------#
-AS_IF([ test x$executorcmd = xtrue],
+AS_IF([test x$tests = xtrue],
[
- AC_CHECK_LIB([menu],[_init],,[AC_MSG_ERROR(menu library is required to compile the command line executor)])
-
- # Checks for ncurses.
- AC_CHECK_HEADERS([ncurses.h], [
- AC_CHECK_LIB(ncurses, initscr, [
- LIBS="$LIBS -lncurses"
- AC_DEFINE(HAVE_LIBNCURSES, 1, [Define to 1 if you have the 'ncurses' library (-lncurses).])
- ], AC_MSG_ERROR(The ncurses library is required in order to build the command line executor!))
- ], AC_MSG_ERROR(The ncurses header is required in order to build the command line executor!))
+ AC_CHECK_LIB([cppunit], [_init], [:], [AC_MSG_ERROR(cppunit library is required)])
],
[])
-AM_CONDITIONAL([WITH_LIBS], [test x$executor$executorcmd$shell$tests != xfalsefalsefalsefalse ])
-
-#------------------------------------------------------------------------------#
-# Some checks to do in case of compiling documentation
#------------------------------------------------------------------------------#
-AM_CONDITIONAL([HAVE_DOXYGEN], [test x$`which doxygen &> /dev/null` != x])
+# ENABLE argument to include PACE
+#------------------------------------------------------------------------------#
+AC_ARG_ENABLE([pace],
+ [AS_HELP_STRING([--enable-pace],[Include PACE (default is no) ])],
+ [pace=true],
+ [pace=false])
+AM_CONDITIONAL([WITH_PACE], [test x$pace = xtrue])
+
+
+# Address Sanitizer
+
+AC_MSG_CHECKING([whether to build with Address Sanitizer support])
+AC_ARG_ENABLE(address-sanitizer,
+ [AS_HELP_STRING([--enable-address-sanitizer],[Enable Address Sanitizer support @<:@default=no@:>@.])],
+ [
+ case "${enableval}" in
+ no|yes)
+ enable_address_sanitizer=${enableval}
+ ;;
+ *)
+ AC_MSG_ERROR([Invalid value ${enableval} for --enable-address-sanitizer])
+ ;;
+ esac
+ ],
+ [enable_address_sanitizer=no])
+AC_MSG_RESULT(${enable_address_sanitizer})
+
+
+
+convert_warning_flags_to_positive() {
+ flags_to_check=""
+ warning_flag_backup=""
+ for option in ${1}; do
+ case "$option"
+ in
+ -Wno-*)
+ flags_to_check="${flags_to_check} -W${option##-Wno-}"
+ warning_flag_backup="${warning_flag_backup} ${option##-Wno-}";;
+ *)
+ flags_to_check="${flags_to_check} ${option}";;
+ esac
+ done
+}
+
+restore_negative_form_of_warning_flags() {
+ final_flags=${1}
+ for positive_option in ${warning_flag_backup}; do
+ final_flags=$(echo $ECHO_N $final_flags | $SED "s|-W${positive_option}|-Wno-${positive_option}|g")
+ done
+ unset flags_to_check
+ unset warning_flag_backup
+}
+
+check_prospective_CFLAGS() {
+ convert_warning_flags_to_positive "${PROSPECTIVE_CFLAGS}"
+ #AX_CHECK_COMPILER_OPTIONS([C], ${flags_to_check})
+ restore_negative_form_of_warning_flags "${CFLAGS}"
+ CFLAGS=${final_flags}
+ unset final_flags
+
+}
+
+check_prospective_CXXFLAGS() {
+ convert_warning_flags_to_positive "${PROSPECTIVE_CXXFLAGS}"
+ #AX_CHECK_COMPILER_OPTIONS([C++], ${flags_to_check})
+ restore_negative_form_of_warning_flags "${CXXFLAGS}"
+ CXXFLAGS=${final_flags}
+ unset final_flags
+}
+
+if test "${enable_address_sanitizer}" = "yes" ; then
+
+ PROSPECTIVE_CFLAGS="-fsanitize-recover=address -fsanitize=address -O1 -fno-omit-frame-pointer -g"
+ PROSPECTIVE_CXXFLAGS="-fsanitize-recover=address -fsanitize=address -O1 -fno-omit-frame-pointer -g "
+
+ # Check if the compilers support address sanitizer
+ check_prospective_CFLAGS
+ check_prospective_CXXFLAGS
+fi
+
#------------------------------------------------------------------------------#
# Specification of all the makefiles to be generated.
#------------------------------------------------------------------------------#
-
MAKEFILES=Makefile
AC_CONFIG_FILES([Makefile \
- lib/Makefile \
+ lib/Makefile \
lib/SPELL_CIF/Makefile \
lib/SPELL_CTX/Makefile \
@@ -276,25 +284,23 @@ AC_CONFIG_FILES([Makefile \
lib/SPELL_SDB/Makefile \
lib/SPELL_DTA/Makefile \
- doc/Makefile \
- procs/Makefile \
config/Makefile \
- rcp/Makefile \
data/Makefile \
scripts/Makefile \
- scripts/linux/Makefile \
src/Makefile \
- src/spell/Makefile \
+ src/context/Makefile \
src/executor/Makefile \
src/executorcmd/Makefile\
- src/context/Makefile \
src/listener/Makefile \
+ src/service/Makefile \
src/shell/Makefile \
- src/spel-gui/Makefile \
+ src/spell/Makefile \
+ src/ping/Makefile \
drivers/Makefile \
- drivers/standalone/Makefile \
+ drivers/example/Makefile\
+ drivers/hifly2/Makefile \
+ drivers/scorpio/Makefile
])
-AC_OUTPUT()
-
+AC_OUTPUT
diff --git a/data/InputFiles/GroundDB/GDB.DB b/data/InputFiles/GroundDB/GDB.DB
new file mode 100644
index 0000000..24cfc40
--- /dev/null
+++ b/data/InputFiles/GroundDB/GDB.DB
@@ -0,0 +1,24 @@
+# Sample boolean
+BOOL1 True
+# Sample forced string
+STR1 A string
+# Sample string
+STR2 "A string"
+# Sample list
+LIST1 [1,2,3]
+# Sample dictionary
+DICT1 {"A":1,"B":2}
+# Sample hexadecimal value
+HEX1 0xA
+# Sample float value
+FLT1 -0.435
+# Sample float value
+FLT2 0.34
+# Sample integer value
+INT1 345
+# Sample octal value
+OCT1 041
+# Sample date/time value
+DAT1 01/01/2001 00:11:22
+# Sample binary value
+BIN1 0b00101
diff --git a/data/InputFiles/ManeuvreMessage/TEST.IMP b/data/InputFiles/ManeuvreMessage/TEST.IMP
new file mode 100644
index 0000000..24cfc40
--- /dev/null
+++ b/data/InputFiles/ManeuvreMessage/TEST.IMP
@@ -0,0 +1,24 @@
+# Sample boolean
+BOOL1 True
+# Sample forced string
+STR1 A string
+# Sample string
+STR2 "A string"
+# Sample list
+LIST1 [1,2,3]
+# Sample dictionary
+DICT1 {"A":1,"B":2}
+# Sample hexadecimal value
+HEX1 0xA
+# Sample float value
+FLT1 -0.435
+# Sample float value
+FLT2 0.34
+# Sample integer value
+INT1 345
+# Sample octal value
+OCT1 041
+# Sample date/time value
+DAT1 01/01/2001 00:11:22
+# Sample binary value
+BIN1 0b00101
diff --git a/data/InputFiles/SpacecraftDB/SCDB.DB b/data/InputFiles/SpacecraftDB/SCDB.DB
new file mode 100644
index 0000000..2b72837
--- /dev/null
+++ b/data/InputFiles/SpacecraftDB/SCDB.DB
@@ -0,0 +1,2 @@
+Number_Of_EQUs 2
+Available_EQUs ['EQU1', 'EQU2']
diff --git a/data/InputFiles/User/TEST.IMP b/data/InputFiles/User/TEST.IMP
new file mode 100644
index 0000000..24cfc40
--- /dev/null
+++ b/data/InputFiles/User/TEST.IMP
@@ -0,0 +1,24 @@
+# Sample boolean
+BOOL1 True
+# Sample forced string
+STR1 A string
+# Sample string
+STR2 "A string"
+# Sample list
+LIST1 [1,2,3]
+# Sample dictionary
+DICT1 {"A":1,"B":2}
+# Sample hexadecimal value
+HEX1 0xA
+# Sample float value
+FLT1 -0.435
+# Sample float value
+FLT2 0.34
+# Sample integer value
+INT1 345
+# Sample octal value
+OCT1 041
+# Sample date/time value
+DAT1 01/01/2001 00:11:22
+# Sample binary value
+BIN1 0b00101
diff --git a/data/Makefile.am b/data/Makefile.am
index 2f22bf0..d76907e 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -1,46 +1,30 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
-include ${top_srcdir}/common.mk
+SRC=${srcdir}
+DST=${exec_prefix}/data
install-exec-hook:
- mkdir -p ${exec_prefix}/data
-if HAVE_RSYNC
- $(RSYNC) ${top_srcdir}/data/DriverData ${exec_prefix}/data/
- $(RSYNC) ${top_srcdir}/data/InputFiles ${exec_prefix}/data/
- $(RSYNC) ${top_srcdir}/data/OutputFiles ${exec_prefix}/data/
- $(RSYNC) ${top_srcdir}/data/Runtime ${exec_prefix}/data/
- $(RSYNC) ${top_srcdir}/data/Simulator ${exec_prefix}/data/
-else
- cp -r ${top_srcdir}/data/DriverData ${exec_prefix}/data/.
- cp -r ${top_srcdir}/data/InputFiles ${exec_prefix}/data/.
- cp -r ${top_srcdir}/data/OutputFiles ${exec_prefix}/data/.
- cp -r ${top_srcdir}/data/Runtime ${exec_prefix}/data/.
- cp -r ${top_srcdir}/data/Simulator ${exec_prefix}/data/.
- find ${exec_prefix}/data -name ".svn" | xargs rm -rf
- rm -f ${exec_prefix}/data/Makefile*
-endif
-
+ cp -ur ${SRC}/InputFiles ${DST}
+ cp -ur ${SRC}/OutputFiles ${DST}
+ cp -ur ${SRC}/Procedures ${DST}
+ cp -ur ${SRC}/UserLib ${DST}
+ cp -ur ${SRC}/Runtime ${DST}
diff --git a/data/OutputFiles/AsRun/.gitignore b/data/OutputFiles/AsRun/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/data/OutputFiles/Warmstart/.gitignore b/data/OutputFiles/Warmstart/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/data/Procedures/.gitignore b/data/Procedures/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/data/Procedures/TestProcedure.py b/data/Procedures/TestProcedure.py
new file mode 100644
index 0000000..1590f7b
--- /dev/null
+++ b/data/Procedures/TestProcedure.py
@@ -0,0 +1,19 @@
+################################################################################
+#
+# NAME : TestProcedure
+# DESCRIPTION : This is a sample procedure
+#
+# FILE : TestProcedure.py
+#
+# SPACECRAFT : Y
+#
+# SPECIFICATION :
+# REVISION HISTORY:
+#
+################################################################################
+
+Step('INIT', 'Initializing test procedure')
+
+Display('Hello, world!')
+
+Finish('Done!')
diff --git a/data/Runtime/.gitignore b/data/Runtime/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/data/UserLib/.gitignore b/data/UserLib/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/deploy/bftd/ddcntl.yaml b/deploy/bftd/ddcntl.yaml
new file mode 100644
index 0000000..5a15356
--- /dev/null
+++ b/deploy/bftd/ddcntl.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: ddcntl
+ labels:
+ app.kubernetes.io/name: spell-cws-scorpio-ddcntl
+ app.kubernetes.io/instance: spell
+ app.kubernetes.io/version: "v2.6.5.1-dev" # {"$imagepolicy": "spell:spell-server:tag"}
+spec:
+ type: ExternalName
+ externalName: cws-lb.scorpio.svc.cluster.local
+# ---
+# apiVersion: v1
+# kind: Endpoints
+# metadata:
+# name: ddcntl
+# subsets:
+# - addresses:
+# - hostname: ddcntl
+# ip: 10.35.46.170
diff --git a/deploy/bftd/externalsecret.yaml b/deploy/bftd/externalsecret.yaml
new file mode 100644
index 0000000..7a21cf4
--- /dev/null
+++ b/deploy/bftd/externalsecret.yaml
@@ -0,0 +1,34 @@
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: spell-git-access
+spec:
+ refreshInterval: "15s" # synchronisation
+ secretStoreRef:
+ name: spell-vault-backend
+ kind: SecretStore
+
+ data:
+ - secretKey: id_rsa
+ remoteRef:
+ key: /spell-git-access
+ property: id_rsa
+ - secretKey: id_rsa.pub
+ remoteRef:
+ key: /spell-git-access
+ property: id_rsa.pub
+---
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: ldap-secret
+spec:
+ refreshInterval: "15s" # synchronisation
+ secretStoreRef:
+ name: spell-vault-backend
+ kind: SecretStore
+ data:
+ - secretKey: ldap-secret
+ remoteRef:
+ key: /ldap-secret
+ property: ldap-secret
\ No newline at end of file
diff --git a/deploy/bftd/flux-policies/imagepolicy.yaml b/deploy/bftd/flux-policies/imagepolicy.yaml
new file mode 100644
index 0000000..4223022
--- /dev/null
+++ b/deploy/bftd/flux-policies/imagepolicy.yaml
@@ -0,0 +1,27 @@
+apiVersion: image.toolkit.fluxcd.io/v1beta1
+kind: ImagePolicy
+metadata:
+ name: spell-registry
+spec:
+ imageRepositoryRef:
+ name: spell-registry
+ filterTags:
+ pattern: '^v(?P[^.]+(\.[^.]+)?(\.[^.]+)?)\.?(?P[^-]*)'
+ extract: '$semver$minor'
+ policy:
+ semver:
+ range: x.x.x
+---
+apiVersion: image.toolkit.fluxcd.io/v1beta1
+kind: ImagePolicy
+metadata:
+ name: spell-server
+spec:
+ imageRepositoryRef:
+ name: spell-server
+ filterTags:
+ pattern: '^v(?P[^.]+(\.[^.]+)?(\.[^.]+)?)\.?(?P[^-]*)'
+ extract: '$semver$minor'
+ policy:
+ semver:
+ range: x.x.x
\ No newline at end of file
diff --git a/deploy/bftd/flux-policies/imagerepository.yaml b/deploy/bftd/flux-policies/imagerepository.yaml
new file mode 100644
index 0000000..b18478b
--- /dev/null
+++ b/deploy/bftd/flux-policies/imagerepository.yaml
@@ -0,0 +1,23 @@
+apiVersion: image.toolkit.fluxcd.io/v1beta1
+kind: ImageRepository
+metadata:
+ name: spell-registry
+spec:
+ certSecretRef:
+ name: nexus-ca
+ image: bzengnexus1.idmz.eng.ses/spell/spell-registry
+ interval: 1m0s
+ secretRef:
+ name: bzengnexus-secret
+---
+apiVersion: image.toolkit.fluxcd.io/v1beta1
+kind: ImageRepository
+metadata:
+ name: spell-server
+spec:
+ certSecretRef:
+ name: nexus-ca
+ image: bzengnexus1.idmz.eng.ses/spell/spell-server
+ interval: 1m0s
+ secretRef:
+ name: bzengnexus-secret
\ No newline at end of file
diff --git a/deploy/bftd/flux-policies/imageupdateautomation.yaml b/deploy/bftd/flux-policies/imageupdateautomation.yaml
new file mode 100644
index 0000000..61fa4e2
--- /dev/null
+++ b/deploy/bftd/flux-policies/imageupdateautomation.yaml
@@ -0,0 +1,43 @@
+apiVersion: image.toolkit.fluxcd.io/v1beta1
+kind: ImageUpdateAutomation
+metadata:
+ name: spell-repo
+ namespace: spell
+spec:
+ interval: 1m0s
+ sourceRef:
+ kind: GitRepository
+ name: spell-repo
+ namespace: flux-system
+ git:
+ checkout:
+ ref:
+ branch: jgall/container-updates
+ commit:
+ author:
+ email: fluxcdbot@users.noreply.internal.ses.com
+ name: fluxcdbot
+ messageTemplate: |
+ Automated image update
+
+ Automation name: {{ .AutomationObject }}
+
+ Files:
+ {{ range $filename, $_ := .Updated.Files -}}
+ - {{ $filename }}
+ {{ end -}}
+
+ Objects:
+ {{ range $resource, $_ := .Updated.Objects -}}
+ - {{ $resource.Kind }} {{ $resource.Name }}
+ {{ end -}}
+
+ Images:
+ {{ range .Updated.Images -}}
+ - {{.}}
+ {{ end -}}
+ push:
+ branch: flux-image-version-update
+ update:
+ path: ./deploy/bfts
+ strategy: Setters
\ No newline at end of file
diff --git a/deploy/bftd/flux-policies/nexus-ca.yaml b/deploy/bftd/flux-policies/nexus-ca.yaml
new file mode 100644
index 0000000..977340d
--- /dev/null
+++ b/deploy/bftd/flux-policies/nexus-ca.yaml
@@ -0,0 +1,6 @@
+apiVersion: v1
+data:
+ caFile: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVtVENDQTRHZ0F3SUJBZ0lUTlFBQUFVeWxRZW1sNGwrcVdRQUFBQUFCVERBTkJna3Foa2lHOXcwQkFRc0YKQURBak1TRXdId1lEVlFRREV4aFRSVk5UWldOMWNtbDBlVWx6YzNWcGJtZERRVXhWTURFd0hoY05NakF3T0RBMgpNakUwTkRReldoY05NalF3T0RBMk1qRTFORFF6V2pDQmh6RUxNQWtHQTFVRUJoTUNURlV4RVRBUEJnTlZCQWNUCkNFSmxkSHBrYjNKbU1Rd3dDZ1lEVlFRS0V3TlRSVk14RERBS0JnTlZCQXNUQTFOUFJURWhNQjhHQTFVRUF4TVkKWW5wbGJtZHVaWGgxY3pFdWFXUnRlaTVsYm1jdWMyVnpNU1l3SkFZSktvWklodmNOQVFrQkZoZEZaSGRoY21RdQpRbUZ6ZEdWc2JHbEFjMlZ6TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCCkFMbndHKzdJSTBtVCtidVp5cXU4TEd4V1NWQ3hMc1JJREpsYkZwUlNUOFdPdjh5SlpzVDBQMkNwbXZlUk9XNnMKNGNuOGs4RnBZdVRBZndLRVVTM3l5S1FyTjZobjlDZllJWVcrQ1FpcVJPQldiQWVQNVFQaDJmc3o3NURjRW5DTQoxeXRtOHZTcE05ejVHSm45b1VObTVyMEh0dmFUdVNoNzgxdEt6TEVtaHhRbE9kSWdqYzluZ2lLb1RqUC9zV2tuCkM0aU0rVEVFemtKYTNZaUZacVRsT3M5Q0JNVnhmK0IxTUMzODRvcU51YmtzSDRIVUZNbnp5cm9UOGJoVThiN1cKQk4vRUk0aEV6NDZ2ODlyZHFrdHVJZGwveklKejUrMm1ZYXRpWnc1M2VYRm1pVEV5VWNqem96YWFIdEpDWG1teQpUeDJuWnNIYllDeEs3Q3R4UWtMUTJXRUNBd0VBQWFPQ0FWOHdnZ0ZiTUIwR0ExVWREZ1FXQkJTYVc0WTUzbU1TCk1hZTJodm1qYzJhbmJIRGZNVEFmQmdOVkhTTUVHREFXZ0JTa3g2TVp3SGxoejlNaHRWWUVTRnByeC83YzBEQngKQmdOVkhSOEVhakJvTUdhZ1pLQmloaTlvZEhSd09pOHZZM0pzTG5ObGN5NWpiMjB2VTBWVFUyVmpkWEpwZEhsSgpjM04xYVc1blEwRk1WVEF4TG1OeWJJWXZhSFIwY0RvdkwyTnliQzV3YTJrdWMyVnpMMU5GVTFObFkzVnlhWFI1ClNYTnpkV2x1WjBOQlRGVXdNUzVqY213d1N3WUlLd1lCQlFVSEFRRUVQekE5TURzR0NDc0dBUVVGQnpBQ2hpOW8KZEhSd09pOHZZM0pzTG5CcmFTNXpaWE12VTBWVFUyVmpkWEpwZEhsSmMzTjFhVzVuUTBGTVZUQXhMbU55ZERBTQpCZ05WSFJNQkFmOEVBakFBTUNNR0ExVWRFUVFjTUJxQ0dHSjZaVzVuYm1WNGRYTXhMbWxrYlhvdVpXNW5Mbk5sCmN6QU9CZ05WSFE4QkFmOEVCQU1DQmFBd0ZnWURWUjBsQVFIL0JBd3dDZ1lJS3dZQkJRVUhBd0V3RFFZSktvWkkKaHZjTkFRRUxCUUFEZ2dFQkFCVlA4Z1hiVmxVTzVLNExQL1lrWXY5Ykp4MnNSODdHbjBRMi85dWZDOXpHMjJOdApYZUlCcDdqc2RDTWpNYzd4QzRWUHhTNktrSjRiUk9WZWI3V3BZK2tFbTRsSklreDNSQlhsemp4aitaT2JvVmhECjNoblNrWTRhNFFzdlJURTlucjQrYlRpSGN4ck90VGNIM244NEtFZXhjRDBwaktkN29yVWVGWHl6MjBJdTN4QjYKT0w0aHB4aEUrVkNTd1I0NXhVSFRLckt3K3pJa3VUV1NYMzBVQ0hZblExRWNTQkFKdHdLNWNkbXZtdUlXazJSdgpWSlVHSjlRQnFOV0padElUZlh3Zk4yT0ljT1VweHRPK3lXckQ5RHZGak1SYVZiUEIwMkIzNW5OcXA2QWN1N21hCnVsNjRicjlSc1grS2w2SGQ1eWltTTBieWJNTXZ4QUtpczNDaGFSMD0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
+kind: Secret
+metadata:
+ name: nexus-ca
diff --git a/deploy/bftd/kube-mp01-values.yaml b/deploy/bftd/kube-mp01-values.yaml
new file mode 100644
index 0000000..af698d5
--- /dev/null
+++ b/deploy/bftd/kube-mp01-values.yaml
@@ -0,0 +1,33 @@
+# Default values for spell-server.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+serviceAccountName: spell-sa
+image:
+ registry: bzengnexus1.idmz.eng.ses
+spell_server:
+ version: v2.6.6.5-dev # {"$imagepolicy": "spell:spell-server:tag"}
+ driver:
+ name: scorpio
+ properties:
+ key: value
+ settings:
+ cws: "ddcntl"
+ #archiva: "{{ .Values.spell_server.seat | lower }}dbs01.scorpio.eng.ses"
+ obus: obus-server.obus.svc:54407
+ maxprocs: 15
+ mission: MP01
+ family: BSS702SP
+ seat: DEVB
+ applicable_missions:
+ MPOWER: MP01,ZMP01,ZMP02,ZMP03,ZMP04,ZMP05,ZMP06,ZMP07,ZMP08,ZMP09,ZMP10,ZMP11
+ input_folder: "{{ .Values.spell_server.mission }}/InputFiles/{{ .Values.spell_server.mission }}"
+ output_folder: "{{ .Values.spell_server.mission }}/OutputFiles/{{ .Values.spell_server.mission }}"
+procedures:
+ size: 5Gi
+ repo_folder: MPOWER
+ branch: SIM
+ server: bzengrcs1.idmz.eng.ses
+ known_hosts: |-
+ bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ==
+ prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT
diff --git a/deploy/bftd/kustomization.yaml b/deploy/bftd/kustomization.yaml
new file mode 100644
index 0000000..d2c53a2
--- /dev/null
+++ b/deploy/bftd/kustomization.yaml
@@ -0,0 +1,42 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+namespace: spell
+resources:
+- ../spell-registry/
+- secretstore.yaml
+- externalsecret.yaml
+- mp09-s3-server.yaml
+- mp01-kube-server.yaml
+- s3cntl.yaml
+- s5cntl.yaml
+- flux-policies/imagepolicy.yaml
+- flux-policies/imagerepository.yaml
+- flux-policies/imageupdateautomation.yaml
+- flux-policies/nexus-ca.yaml
+- ddcntl.yaml
+
+configMapGenerator:
+- name: s3-mp09-spell-server
+ files:
+ - s3-mp09-values.yaml
+- name: kube-mp01-spell-server
+ files:
+ - kube-mp01-values.yaml
+
+configurations:
+- kustomizeconfig.yaml
+
+
+patchesJson6902:
+ - target:
+ kind: Ingress
+ name: spell-registry
+ version: v1
+ patch: |-
+ - op: replace
+ path: "/spec/rules/0/host"
+ value: "spell-registry.ing-lu-d.spo.internal.ses.com"
+ - op: replace
+ path: "/spec/tls/0/hosts/0"
+ value: "spell-registry.ing-lu-d.spo.internal.ses.com"
\ No newline at end of file
diff --git a/deploy/bftd/kustomizeconfig.yaml b/deploy/bftd/kustomizeconfig.yaml
new file mode 100644
index 0000000..f6b2027
--- /dev/null
+++ b/deploy/bftd/kustomizeconfig.yaml
@@ -0,0 +1,6 @@
+nameReference:
+- kind: ConfigMap
+ version: v1
+ fieldSpecs:
+ - path: spec/valuesFrom/name
+ kind: HelmRelease
\ No newline at end of file
diff --git a/deploy/bftd/mp01-kube-server.yaml b/deploy/bftd/mp01-kube-server.yaml
new file mode 100644
index 0000000..deb3470
--- /dev/null
+++ b/deploy/bftd/mp01-kube-server.yaml
@@ -0,0 +1,22 @@
+---
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+ name: kube-mp01-spell-server
+spec:
+ chart:
+ spec:
+ chart: ./deploy/spell-server
+ reconcileStrategy: Revision
+ sourceRef:
+ kind: GitRepository
+ name: spell-repo
+ namespace: flux-system
+ interval: 10m0s
+ valuesFrom:
+ - kind: ConfigMap
+ name: kube-mp01-spell-server
+ valuesKey: kube-mp01-values.yaml
+
+
+
diff --git a/deploy/bftd/mp09-s3-server.yaml b/deploy/bftd/mp09-s3-server.yaml
new file mode 100644
index 0000000..93d1b4b
--- /dev/null
+++ b/deploy/bftd/mp09-s3-server.yaml
@@ -0,0 +1,22 @@
+---
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+ name: s3-mp09-spell-server
+spec:
+ chart:
+ spec:
+ chart: ./deploy/spell-server
+ reconcileStrategy: Revision
+ sourceRef:
+ kind: GitRepository
+ name: spell-repo
+ namespace: flux-system
+ interval: 10m0s
+ valuesFrom:
+ - kind: ConfigMap
+ name: s3-mp09-spell-server
+ valuesKey: s3-mp09-values.yaml
+
+
+
diff --git a/deploy/bftd/s3-mp09-values.yaml b/deploy/bftd/s3-mp09-values.yaml
new file mode 100644
index 0000000..cfdc3aa
--- /dev/null
+++ b/deploy/bftd/s3-mp09-values.yaml
@@ -0,0 +1,34 @@
+# Default values for spell-server.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+serviceAccountName: spell-sa
+image:
+ registry: bzengnexus1.idmz.eng.ses
+spell_server:
+ version: v2.6.5.1-dev # {"$imagepolicy": "spell:spell-server:tag"}
+ driver:
+ name: scorpio
+ properties:
+ key: value
+ settings:
+ cws: "{{ .Values.spell_server.seat | lower }}cntl"
+ archiva: "{{ .Values.spell_server.seat | lower }}dbs01.scorpio.eng.ses"
+ obus: bfts-ob.eng.ses:54407
+ maxprocs: 15
+ ssh_port: 22
+ mission: ZMP09
+ family: BSS702SP
+ seat: S3
+ applicable_missions:
+ MPOWER: MP01,ZMP01,ZMP02,ZMP03,ZMP04,ZMP05,ZMP06,ZMP07,ZMP08,ZMP09,ZMP10,ZMP11
+ input_folder: "{{ .Values.spell_server.mission }}/InputFiles/{{ substr 1 99999 .Values.spell_server.mission }}"
+ output_folder: "{{ .Values.spell_server.mission }}/OutputFiles/{{ substr 1 99999 .Values.spell_server.mission }}"
+procedures:
+ size: 5Gi
+ repo_folder: MPOWER
+ branch: SIM
+ server: bzengrcs1.idmz.eng.ses
+ known_hosts: |-
+ bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ==
+ prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT
diff --git a/deploy/bftd/s3cntl.yaml b/deploy/bftd/s3cntl.yaml
new file mode 100644
index 0000000..f2fcd66
--- /dev/null
+++ b/deploy/bftd/s3cntl.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: s3cntl
+ labels:
+ app.kubernetes.io/name: spell-cws-scorpio-s3cntl
+ app.kubernetes.io/instance: spell
+ app.kubernetes.io/version: "v2.6.5.1-dev" # {"$imagepolicy": "spell:spell-server:tag"}
+spec:
+ type: ExternalName
+ externalName: s3cntl.scorpio.eng.ses
+# ---
+# apiVersion: v1
+# kind: Endpoints
+# metadata:
+# name: s3cntl
+# subsets:
+# - addresses:
+# - hostname: s3cntl
+# ip: 10.35.24.30
diff --git a/deploy/bftd/s5cntl.yaml b/deploy/bftd/s5cntl.yaml
new file mode 100644
index 0000000..200f1ad
--- /dev/null
+++ b/deploy/bftd/s5cntl.yaml
@@ -0,0 +1,20 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: s5cntl
+ labels:
+ app.kubernetes.io/name: spell-cws-scorpio-s5cntl
+ app.kubernetes.io/instance: spell
+ app.kubernetes.io/version: "v2.6.5.1-dev" # {"$imagepolicy": "spell:spell-server:tag"}
+spec:
+ type: ExternalName
+ externalName: s5cntl.scorpio.eng.ses
+# ---
+# apiVersion: v1
+# kind: Endpoints
+# metadata:
+# name: s5cntl
+# subsets:
+# - addresses:
+# - hostname: s5cntl
+# ip: 10.35.35.30
diff --git a/deploy/bftd/secretstore.yaml b/deploy/bftd/secretstore.yaml
new file mode 100644
index 0000000..f42d8c6
--- /dev/null
+++ b/deploy/bftd/secretstore.yaml
@@ -0,0 +1,26 @@
+# Expected Structure:
+# spell-git-access: {"id_rsa":"", "id_rsa.pub":""}
+# ldap-access: {}
+#
+#
+#
+apiVersion: external-secrets.io/v1beta1
+kind: SecretStore
+metadata:
+ name: spell-vault-backend
+spec:
+ provider:
+ vault:
+ server: "https://vault.vault:8200"
+ path: "soe/secret/spell"
+ version: "v2"
+ caProvider:
+ type: "Secret"
+ name: "vault-ca"
+ key: "ca.crt"
+ auth:
+ kubernetes:
+ mountPath: "kubernetes"
+ role: "serviceaccount"
+ serviceAccountRef:
+ name: "default"
diff --git a/deploy/bfts/externalsecret.yaml b/deploy/bfts/externalsecret.yaml
new file mode 100644
index 0000000..dfdbc01
--- /dev/null
+++ b/deploy/bfts/externalsecret.yaml
@@ -0,0 +1,66 @@
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: spell-git-access
+spec:
+ refreshInterval: "15s" # synchronisation
+ secretStoreRef:
+ name: spell-vault-backend
+ kind: SecretStore
+
+ data:
+ - secretKey: id_rsa
+ remoteRef:
+ key: /spell-git-access
+ property: id_rsa
+ - secretKey: id_rsa.pub
+ remoteRef:
+ key: /spell-git-access
+ property: id_rsa.pub
+---
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: ldap-secret
+spec:
+ refreshInterval: "15s" # synchronisation
+ secretStoreRef:
+ name: spell-vault-backend
+ kind: SecretStore
+ data:
+ - secretKey: ldap-secret
+ remoteRef:
+ key: /ldap-secret
+ property: ldap-secret
+---
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: ses24-encryption-keys
+spec:
+ refreshInterval: "15s" # synchronisation
+ secretStoreRef:
+ name: spell-vault-backend
+ kind: SecretStore
+
+ dataFrom:
+ - extract:
+ key: /ses24-encryption
+ decodingStrategy: Auto
+
+---
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: ses24-encryption-cert
+spec:
+ refreshInterval: "15s" # synchronisation
+ secretStoreRef:
+ name: spell-vault-backend
+ kind: SecretStore
+
+ data:
+ - secretKey: ses24_rsa.pem
+ remoteRef:
+ key: /ses24-encryption
+ property: ses24_rsa.pem
diff --git a/deploy/bfts/kustomization.yaml b/deploy/bfts/kustomization.yaml
new file mode 100644
index 0000000..d60f692
--- /dev/null
+++ b/deploy/bfts/kustomization.yaml
@@ -0,0 +1,30 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+namespace: spell
+resources:
+- ../spell-registry/
+- secretstore.yaml
+- externalsecret.yaml
+- missions/zs24a/
+- missions/zs24b/
+- missions/zs24c/
+- missions/zs24d/
+- missions/zs24e/
+- missions/zs24f/
+
+patchesJson6902:
+ - target:
+ kind: Ingress
+ name: spell-registry
+ version: v1
+ patch: |-
+ - op: replace
+ path: "/spec/rules/0/host"
+ value: "spell-registry.ing-lu-s.spo.internal.ses.com"
+ - op: replace
+ path: "/spec/tls/0/hosts/0"
+ value: "spell-registry.ing-lu-s.spo.internal.ses.com"
+
+configurations:
+- kustomizeconfig.yaml
diff --git a/deploy/bfts/kustomizeconfig.yaml b/deploy/bfts/kustomizeconfig.yaml
new file mode 100644
index 0000000..f6b2027
--- /dev/null
+++ b/deploy/bfts/kustomizeconfig.yaml
@@ -0,0 +1,6 @@
+nameReference:
+- kind: ConfigMap
+ version: v1
+ fieldSpecs:
+ - path: spec/valuesFrom/name
+ kind: HelmRelease
\ No newline at end of file
diff --git a/deploy/bfts/missions/zs24a/kube-ses24-server.yaml b/deploy/bfts/missions/zs24a/kube-ses24-server.yaml
new file mode 100644
index 0000000..438142d
--- /dev/null
+++ b/deploy/bfts/missions/zs24a/kube-ses24-server.yaml
@@ -0,0 +1,18 @@
+---
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+ name: kube-zs24a-spell-server
+spec:
+ chart:
+ spec:
+ chart: ./deploy/spell-server
+ sourceRef:
+ kind: GitRepository
+ name: spell-repo
+ namespace: flux-system
+ interval: 10m0s
+ valuesFrom:
+ - kind: ConfigMap
+ name: kube-zs24a-spell-release
+ valuesKey: kube-ses24-values.yaml
diff --git a/deploy/bfts/missions/zs24a/kube-ses24-values.yaml b/deploy/bfts/missions/zs24a/kube-ses24-values.yaml
new file mode 100644
index 0000000..959bd95
--- /dev/null
+++ b/deploy/bfts/missions/zs24a/kube-ses24-values.yaml
@@ -0,0 +1,75 @@
+# Default values for spell-server.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+serviceAccountName: spell-sa
+image:
+ registry: bzengnexus1.idmz.eng.ses
+spell_server:
+ version: v2.6.8.1-dev # {"$imagepolicy": "spell:spell-server:tag"}
+ driver:
+ name: scorpio
+ env:
+ NODE_ID_zs24asim: "3369"
+ NODE_NAME_3369: zs24asim
+ properties:
+ key: value
+ settings:
+ archiva: "zs24asim"
+ FLEETLIMITS: limitsdb-api.limitsdb.svc:8080
+ FLEETLIMITS_SEAT: SIMB
+ SATDB: satdb-api.satdb.svc:8080
+ cws: "zs24asim"
+ obus: obus-test-server.obus.svc:54407
+ maxprocs: 15
+ mission: ZS24A
+ context_mission: SES24
+ family: SBNEO
+ seat: SIMB
+ applicable_missions:
+ SBNEO: "SES24,ZS24A,ZS24B,ZS24C"
+ input_folder: "{{ .Values.spell_server.mission }}/InputFiles"
+ output_folder: "{{ .Values.spell_server.mission }}/OutputFiles"
+ additionalInitSteps: "[ -d '/etc/pki/tls/private/wrapped_keys/' ] && (cd /etc/pki/tls/private/wrapped_keys/ && unzip -u ses24-keys.zip && (find . | grep ses24 | sed 'p;s/ses24/zs24a/' | xargs -n2 mv)) || echo 'Could not find encryption key archive!'"
+ additionalVolumeMounts:
+ - mountPath: /etc/pki/tls/private/wrapped_keys/
+ name: ses24-certs-folder
+ - mountPath: /etc/pki/tls/private/wrapped_keys/ses24-keys.zip
+ name: ses24-encryption-keys
+ subPath: ses24-keys.zip
+ - mountPath: /etc/pki/tls/zs24a_keys/zs24a_rsa.pem
+ name: ses24-encryption-cert
+ subPath: ses24_rsa.pem
+ additionalVolumes:
+ - name: ses24-certs-folder
+ emptyDir:
+ sizeLimit: 100Mi
+ medium: Memory
+ - name: ses24-encryption-cert
+ secret:
+ secretName: ses24-encryption-cert
+ optional: true
+ defaultMode: 0400
+ - name: ses24-encryption-keys
+ secret:
+ secretName: ses24-encryption-keys
+ optional: true
+ defaultMode: 0400
+procedures:
+ size: 5Gi
+ repo_folder: SES24
+ branch: SIM
+ server: bzengrcs1.idmz.eng.ses
+ known_hosts: |-
+ propsrcs1.idmz.soc.ses,10.114.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDwEclkdaNWKtL0iuulsFrzG5VGH2y2ct7uZu755g6oKKYhyTrs9ytCdS7sK5NTwDNBjiEuywXtcZcX1RyGenxc/3YQTj0aHWC3tXfVSUcbkzKle0Tdxaq+arlI35TcLLsDnaI1OWN/TMUhGasGGSwOOp2IzJP8JAuD1/iNfzhVa1SOD39jt55oDEnncHqKS25CqBNWY1XC23+gQexB+6ai+bYZutDP+IKmnx/5quPeTnIJnXRRvGHh01oTNRTlVH5Nz4evVmSQst57vNcXzY76WwDvav2u8Gu6Yz2cyngCelXnU8Ko76sRR+VxwYeZvBDbgh0//S8aWl72KFVCH9o5
+ bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ==
+ prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT
+
+auth:
+ ssh:
+ version: v2.6.7.7-dev # {"$imagepolicy": "spell:spell-server:tag"}
+ ldap:
+ url: ldaps://beacdc1.xeneng.ses
+
+service:
+ loadBalancerIP: 10.35.47.136
\ No newline at end of file
diff --git a/deploy/bfts/missions/zs24a/kustomization.yaml b/deploy/bfts/missions/zs24a/kustomization.yaml
new file mode 100644
index 0000000..a50f7a0
--- /dev/null
+++ b/deploy/bfts/missions/zs24a/kustomization.yaml
@@ -0,0 +1,18 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+namespace: spell
+resources:
+- kube-ses24-server.yaml
+- ses24cntl.yaml
+
+configMapGenerator:
+- name: kube-zs24a-spell-release
+ options:
+ disableNameSuffixHash: false
+ files:
+ - kube-ses24-values.yaml
+
+
+configurations:
+- kustomizeconfig.yaml
\ No newline at end of file
diff --git a/deploy/bfts/missions/zs24a/kustomizeconfig.yaml b/deploy/bfts/missions/zs24a/kustomizeconfig.yaml
new file mode 100644
index 0000000..f6b2027
--- /dev/null
+++ b/deploy/bfts/missions/zs24a/kustomizeconfig.yaml
@@ -0,0 +1,6 @@
+nameReference:
+- kind: ConfigMap
+ version: v1
+ fieldSpecs:
+ - path: spec/valuesFrom/name
+ kind: HelmRelease
\ No newline at end of file
diff --git a/deploy/bfts/missions/zs24a/ses24cntl.yaml b/deploy/bfts/missions/zs24a/ses24cntl.yaml
new file mode 100644
index 0000000..ea425fb
--- /dev/null
+++ b/deploy/bfts/missions/zs24a/ses24cntl.yaml
@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: zs24asim
+ labels:
+ app.kubernetes.io/name: spell-cws-scorpio-zs24asim
+ app.kubernetes.io/instance: spell
+spec:
+ type: ExternalName
+ externalName: cws-lb.scorpio-zs24a.svc.cluster.local
+
diff --git a/deploy/bfts/missions/zs24b/kube-ses24-server.yaml b/deploy/bfts/missions/zs24b/kube-ses24-server.yaml
new file mode 100644
index 0000000..c2a382c
--- /dev/null
+++ b/deploy/bfts/missions/zs24b/kube-ses24-server.yaml
@@ -0,0 +1,18 @@
+---
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+ name: kube-zs24b-spell-server
+spec:
+ chart:
+ spec:
+ chart: ./deploy/spell-server
+ sourceRef:
+ kind: GitRepository
+ name: spell-repo
+ namespace: flux-system
+ interval: 10m0s
+ valuesFrom:
+ - kind: ConfigMap
+ name: kube-zs24b-spell-release
+ valuesKey: kube-ses24-values.yaml
diff --git a/deploy/bfts/missions/zs24b/kube-ses24-values.yaml b/deploy/bfts/missions/zs24b/kube-ses24-values.yaml
new file mode 100644
index 0000000..57b05da
--- /dev/null
+++ b/deploy/bfts/missions/zs24b/kube-ses24-values.yaml
@@ -0,0 +1,75 @@
+# Default values for spell-server.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+serviceAccountName: spell-sa
+image:
+ registry: bzengnexus1.idmz.eng.ses
+spell_server:
+ version: v2.6.8.1-dev # {"$imagepolicy": "spell:spell-server:tag"}
+ driver:
+ name: scorpio
+ env:
+ NODE_ID_zs24bsim: "3369"
+ NODE_NAME_3369: zs24bsim
+ properties:
+ key: value
+ settings:
+ archiva: "zs24bsim"
+ FLEETLIMITS: limitsdb-api.limitsdb.svc:8080
+ FLEETLIMITS_SEAT: SIMB
+ SATDB: satdb-api.satdb.svc:8080
+ cws: "zs24bsim"
+ obus: obus-test-server.obus.svc:54407
+ maxprocs: 15
+ mission: ZS24B
+ context_mission: SES24
+ family: SBNEO
+ seat: SIMB
+ applicable_missions:
+ SBNEO: "SES24,ZS24A,ZS24B,ZS24C,ZS24D,ZS24E,ZS24F"
+ input_folder: "{{ .Values.spell_server.mission }}/InputFiles"
+ output_folder: "{{ .Values.spell_server.mission }}/OutputFiles"
+ additionalInitSteps: "[ -d '/etc/pki/tls/private/wrapped_keys/' ] && (cd /etc/pki/tls/private/wrapped_keys/ && unzip -u ses24-keys.zip && (find . | grep ses24 | sed 'p;s/ses24/zs24b/' | xargs -n2 mv)) || echo 'Could not find encryption key archive!'"
+ additionalVolumeMounts:
+ - mountPath: /etc/pki/tls/private/wrapped_keys/
+ name: ses24-certs-folder
+ - mountPath: /etc/pki/tls/private/wrapped_keys/ses24-keys.zip
+ name: ses24-encryption-keys
+ subPath: ses24-keys.zip
+ - mountPath: /etc/pki/tls/zs24b_keys/zs24b_rsa.pem
+ name: ses24-encryption-cert
+ subPath: ses24_rsa.pem
+ additionalVolumes:
+ - name: ses24-certs-folder
+ emptyDir:
+ sizeLimit: 100Mi
+ medium: Memory
+ - name: ses24-encryption-cert
+ secret:
+ secretName: ses24-encryption-cert
+ optional: true
+ defaultMode: 0400
+ - name: ses24-encryption-keys
+ secret:
+ secretName: ses24-encryption-keys
+ optional: true
+ defaultMode: 0400
+procedures:
+ size: 5Gi
+ repo_folder: SES24
+ branch: SIM
+ server: bzengrcs1.idmz.eng.ses
+ known_hosts: |-
+ propsrcs1.idmz.soc.ses,10.114.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDwEclkdaNWKtL0iuulsFrzG5VGH2y2ct7uZu755g6oKKYhyTrs9ytCdS7sK5NTwDNBjiEuywXtcZcX1RyGenxc/3YQTj0aHWC3tXfVSUcbkzKle0Tdxaq+arlI35TcLLsDnaI1OWN/TMUhGasGGSwOOp2IzJP8JAuD1/iNfzhVa1SOD39jt55oDEnncHqKS25CqBNWY1XC23+gQexB+6ai+bYZutDP+IKmnx/5quPeTnIJnXRRvGHh01oTNRTlVH5Nz4evVmSQst57vNcXzY76WwDvav2u8Gu6Yz2cyngCelXnU8Ko76sRR+VxwYeZvBDbgh0//S8aWl72KFVCH9o5
+ bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ==
+ prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT
+
+auth:
+ ssh:
+ version: v2.6.7.7-dev # {"$imagepolicy": "spell:spell-server:tag"}
+ ldap:
+ url: ldaps://beacdc1.xeneng.ses
+
+service:
+ loadBalancerIP: 10.35.47.182
diff --git a/deploy/bfts/missions/zs24b/kustomization.yaml b/deploy/bfts/missions/zs24b/kustomization.yaml
new file mode 100644
index 0000000..74f3511
--- /dev/null
+++ b/deploy/bfts/missions/zs24b/kustomization.yaml
@@ -0,0 +1,18 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+namespace: spell
+resources:
+- kube-ses24-server.yaml
+- ses24cntl.yaml
+
+configMapGenerator:
+- name: kube-zs24b-spell-release
+ options:
+ disableNameSuffixHash: false
+ files:
+ - kube-ses24-values.yaml
+
+
+configurations:
+- kustomizeconfig.yaml
\ No newline at end of file
diff --git a/deploy/bfts/missions/zs24b/kustomizeconfig.yaml b/deploy/bfts/missions/zs24b/kustomizeconfig.yaml
new file mode 100644
index 0000000..f6b2027
--- /dev/null
+++ b/deploy/bfts/missions/zs24b/kustomizeconfig.yaml
@@ -0,0 +1,6 @@
+nameReference:
+- kind: ConfigMap
+ version: v1
+ fieldSpecs:
+ - path: spec/valuesFrom/name
+ kind: HelmRelease
\ No newline at end of file
diff --git a/deploy/bfts/missions/zs24b/ses24cntl.yaml b/deploy/bfts/missions/zs24b/ses24cntl.yaml
new file mode 100644
index 0000000..2ea3539
--- /dev/null
+++ b/deploy/bfts/missions/zs24b/ses24cntl.yaml
@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: zs24bsim
+ labels:
+ app.kubernetes.io/name: spell-cws-scorpio-zs24bsim
+ app.kubernetes.io/instance: spell
+spec:
+ type: ExternalName
+ externalName: cws-lb.scorpio-zs24b.svc.cluster.local
+
diff --git a/deploy/bfts/missions/zs24c/kube-ses24-server.yaml b/deploy/bfts/missions/zs24c/kube-ses24-server.yaml
new file mode 100644
index 0000000..7637c7d
--- /dev/null
+++ b/deploy/bfts/missions/zs24c/kube-ses24-server.yaml
@@ -0,0 +1,18 @@
+---
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+ name: kube-zs24c-spell-server
+spec:
+ chart:
+ spec:
+ chart: ./deploy/spell-server
+ sourceRef:
+ kind: GitRepository
+ name: spell-repo
+ namespace: flux-system
+ interval: 10m0s
+ valuesFrom:
+ - kind: ConfigMap
+ name: kube-zs24c-spell-release
+ valuesKey: kube-ses24-values.yaml
diff --git a/deploy/bfts/missions/zs24c/kube-ses24-values.yaml b/deploy/bfts/missions/zs24c/kube-ses24-values.yaml
new file mode 100644
index 0000000..1ab0f76
--- /dev/null
+++ b/deploy/bfts/missions/zs24c/kube-ses24-values.yaml
@@ -0,0 +1,75 @@
+# Default values for spell-server.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+serviceAccountName: spell-sa
+image:
+ registry: bzengnexus1.idmz.eng.ses
+spell_server:
+ version: v2.6.8.1-dev # {"$imagepolicy": "spell:spell-server:tag"}
+ driver:
+ name: scorpio
+ env:
+ NODE_ID_zs24csim: "3369"
+ NODE_NAME_3369: zs24csim
+ properties:
+ key: value
+ settings:
+ archiva: "zs24csim"
+ FLEETLIMITS: limitsdb-api.limitsdb.svc:8080
+ FLEETLIMITS_SEAT: SIMB
+ SATDB: satdb-api.satdb.svc:8080
+ cws: "zs24csim"
+ obus: obus-test-server.obus.svc:54407
+ maxprocs: 15
+ mission: ZS24C
+ context_mission: SES24
+ family: SBNEO
+ seat: SIMB
+ applicable_missions:
+ SBNEO: "SES24,ZS24A,ZS24B,ZS24C,ZS24D,ZS24E,ZS24F"
+ input_folder: "{{ .Values.spell_server.mission }}/InputFiles"
+ output_folder: "{{ .Values.spell_server.mission }}/OutputFiles"
+ additionalInitSteps: "[ -d '/etc/pki/tls/private/wrapped_keys/' ] && (cd /etc/pki/tls/private/wrapped_keys/ && unzip -u ses24-keys.zip && (find . | grep ses24 | sed 'p;s/ses24/zs24c/' | xargs -n2 mv)) || echo 'Could not find encryption key archive!'"
+ additionalVolumeMounts:
+ - mountPath: /etc/pki/tls/private/wrapped_keys/
+ name: ses24-certs-folder
+ - mountPath: /etc/pki/tls/private/wrapped_keys/ses24-keys.zip
+ name: ses24-encryption-keys
+ subPath: ses24-keys.zip
+ - mountPath: /etc/pki/tls/zs24c_keys/zs24c_rsa.pem
+ name: ses24-encryption-cert
+ subPath: ses24_rsa.pem
+ additionalVolumes:
+ - name: ses24-certs-folder
+ emptyDir:
+ sizeLimit: 100Mi
+ medium: Memory
+ - name: ses24-encryption-cert
+ secret:
+ secretName: ses24-encryption-cert
+ optional: true
+ defaultMode: 0400
+ - name: ses24-encryption-keys
+ secret:
+ secretName: ses24-encryption-keys
+ optional: true
+ defaultMode: 0400
+procedures:
+ size: 5Gi
+ repo_folder: SES24
+ branch: SIM
+ server: bzengrcs1.idmz.eng.ses
+ known_hosts: |-
+ propsrcs1.idmz.soc.ses,10.114.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDwEclkdaNWKtL0iuulsFrzG5VGH2y2ct7uZu755g6oKKYhyTrs9ytCdS7sK5NTwDNBjiEuywXtcZcX1RyGenxc/3YQTj0aHWC3tXfVSUcbkzKle0Tdxaq+arlI35TcLLsDnaI1OWN/TMUhGasGGSwOOp2IzJP8JAuD1/iNfzhVa1SOD39jt55oDEnncHqKS25CqBNWY1XC23+gQexB+6ai+bYZutDP+IKmnx/5quPeTnIJnXRRvGHh01oTNRTlVH5Nz4evVmSQst57vNcXzY76WwDvav2u8Gu6Yz2cyngCelXnU8Ko76sRR+VxwYeZvBDbgh0//S8aWl72KFVCH9o5
+ bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ==
+ prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT
+
+auth:
+ ssh:
+ version: v2.6.7.7-dev # {"$imagepolicy": "spell:spell-server:tag"}
+ ldap:
+ url: ldaps://beacdc1.xeneng.ses
+
+service:
+ loadBalancerIP: 10.35.47.226
diff --git a/deploy/bfts/missions/zs24c/kustomization.yaml b/deploy/bfts/missions/zs24c/kustomization.yaml
new file mode 100644
index 0000000..1eb4aa5
--- /dev/null
+++ b/deploy/bfts/missions/zs24c/kustomization.yaml
@@ -0,0 +1,18 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+namespace: spell
+resources:
+- kube-ses24-server.yaml
+- ses24cntl.yaml
+
+configMapGenerator:
+- name: kube-zs24c-spell-release
+ options:
+ disableNameSuffixHash: false
+ files:
+ - kube-ses24-values.yaml
+
+
+configurations:
+- kustomizeconfig.yaml
\ No newline at end of file
diff --git a/deploy/bfts/missions/zs24c/kustomizeconfig.yaml b/deploy/bfts/missions/zs24c/kustomizeconfig.yaml
new file mode 100644
index 0000000..f6b2027
--- /dev/null
+++ b/deploy/bfts/missions/zs24c/kustomizeconfig.yaml
@@ -0,0 +1,6 @@
+nameReference:
+- kind: ConfigMap
+ version: v1
+ fieldSpecs:
+ - path: spec/valuesFrom/name
+ kind: HelmRelease
\ No newline at end of file
diff --git a/deploy/bfts/missions/zs24c/ses24cntl.yaml b/deploy/bfts/missions/zs24c/ses24cntl.yaml
new file mode 100644
index 0000000..9b86107
--- /dev/null
+++ b/deploy/bfts/missions/zs24c/ses24cntl.yaml
@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: zs24csim
+ labels:
+ app.kubernetes.io/name: spell-cws-scorpio-zs24csim
+ app.kubernetes.io/instance: spell
+spec:
+ type: ExternalName
+ externalName: cws-lb.scorpio-zs24c.svc.cluster.local
+
diff --git a/deploy/bfts/missions/zs24d/kube-ses24-server.yaml b/deploy/bfts/missions/zs24d/kube-ses24-server.yaml
new file mode 100644
index 0000000..8b650fc
--- /dev/null
+++ b/deploy/bfts/missions/zs24d/kube-ses24-server.yaml
@@ -0,0 +1,18 @@
+---
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+ name: kube-zs24d-spell-server
+spec:
+ chart:
+ spec:
+ chart: ./deploy/spell-server
+ sourceRef:
+ kind: GitRepository
+ name: spell-repo
+ namespace: flux-system
+ interval: 10m0s
+ valuesFrom:
+ - kind: ConfigMap
+ name: kube-zs24d-spell-release
+ valuesKey: kube-ses24-values.yaml
diff --git a/deploy/bfts/missions/zs24d/kube-ses24-values.yaml b/deploy/bfts/missions/zs24d/kube-ses24-values.yaml
new file mode 100644
index 0000000..66d2eed
--- /dev/null
+++ b/deploy/bfts/missions/zs24d/kube-ses24-values.yaml
@@ -0,0 +1,75 @@
+# Default values for spell-server.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+serviceAccountName: spell-sa
+image:
+ registry: bzengnexus1.idmz.eng.ses
+spell_server:
+ version: v2.6.8.1-dev # {"$imagepolicy": "spell:spell-server:tag"}
+ driver:
+ name: scorpio
+ env:
+ NODE_ID_zs24dsim: "3369"
+ NODE_NAME_3369: zs24dsim
+ properties:
+ key: value
+ settings:
+ archiva: "zs24dsim"
+ FLEETLIMITS: limitsdb-api.limitsdb.svc:8080
+ FLEETLIMITS_SEAT: SIMB
+ SATDB: satdb-api.satdb.svc:8080
+ cws: "zs24dsim"
+ obus: obus-test-server.obus.svc:54407
+ maxprocs: 15
+ mission: ZS24D
+ context_mission: SES24
+ family: SBNEO
+ seat: SIMB
+ applicable_missions:
+ SBNEO: "SES24,ZS24A,ZS24D,ZS24C,ZS24D,ZS24E,ZS24F"
+ input_folder: "{{ .Values.spell_server.mission }}/InputFiles"
+ output_folder: "{{ .Values.spell_server.mission }}/OutputFiles"
+ additionalInitSteps: "[ -d '/etc/pki/tls/private/wrapped_keys/' ] && (cd /etc/pki/tls/private/wrapped_keys/ && unzip -u ses24-keys.zip && (find . | grep ses24 | sed 'p;s/ses24/zs24d/' | xargs -n2 mv)) || echo 'Could not find encryption key archive!'"
+ additionalVolumeMounts:
+ - mountPath: /etc/pki/tls/private/wrapped_keys/
+ name: ses24-certs-folder
+ - mountPath: /etc/pki/tls/private/wrapped_keys/ses24-keys.zip
+ name: ses24-encryption-keys
+ subPath: ses24-keys.zip
+ - mountPath: /etc/pki/tls/zs24d_keys/zs24d_rsa.pem
+ name: ses24-encryption-cert
+ subPath: ses24_rsa.pem
+ additionalVolumes:
+ - name: ses24-certs-folder
+ emptyDir:
+ sizeLimit: 100Mi
+ medium: Memory
+ - name: ses24-encryption-cert
+ secret:
+ secretName: ses24-encryption-cert
+ optional: true
+ defaultMode: 0400
+ - name: ses24-encryption-keys
+ secret:
+ secretName: ses24-encryption-keys
+ optional: true
+ defaultMode: 0400
+procedures:
+ size: 5Gi
+ repo_folder: SES24
+ branch: SIM
+ server: bzengrcs1.idmz.eng.ses
+ known_hosts: |-
+ propsrcs1.idmz.soc.ses,10.114.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDwEclkdaNWKtL0iuulsFrzG5VGH2y2ct7uZu755g6oKKYhyTrs9ytCdS7sK5NTwDNBjiEuywXtcZcX1RyGenxc/3YQTj0aHWC3tXfVSUcbkzKle0Tdxaq+arlI35TcLLsDnaI1OWN/TMUhGasGGSwOOp2IzJP8JAuD1/iNfzhVa1SOD39jt55oDEnncHqKS25CqBNWY1XC23+gQexB+6ai+bYZutDP+IKmnx/5quPeTnIJnXRRvGHh01oTNRTlVH5Nz4evVmSQst57vNcXzY76WwDvav2u8Gu6Yz2cyngCelXnU8Ko76sRR+VxwYeZvBDbgh0//S8aWl72KFVCH9o5
+ bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ==
+ prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT
+
+auth:
+ ssh:
+ version: v2.6.7.7-dev # {"$imagepolicy": "spell:spell-server:tag"}
+ ldap:
+ url: ldaps://beacdc1.xeneng.ses
+
+service:
+ loadBalancerIP: 10.35.47.230
diff --git a/deploy/bfts/missions/zs24d/kustomization.yaml b/deploy/bfts/missions/zs24d/kustomization.yaml
new file mode 100644
index 0000000..0af5d03
--- /dev/null
+++ b/deploy/bfts/missions/zs24d/kustomization.yaml
@@ -0,0 +1,18 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+namespace: spell
+resources:
+- kube-ses24-server.yaml
+- ses24cntl.yaml
+
+configMapGenerator:
+- name: kube-zs24d-spell-release
+ options:
+ disableNameSuffixHash: false
+ files:
+ - kube-ses24-values.yaml
+
+
+configurations:
+- kustomizeconfig.yaml
\ No newline at end of file
diff --git a/deploy/bfts/missions/zs24d/kustomizeconfig.yaml b/deploy/bfts/missions/zs24d/kustomizeconfig.yaml
new file mode 100644
index 0000000..f6b2027
--- /dev/null
+++ b/deploy/bfts/missions/zs24d/kustomizeconfig.yaml
@@ -0,0 +1,6 @@
+nameReference:
+- kind: ConfigMap
+ version: v1
+ fieldSpecs:
+ - path: spec/valuesFrom/name
+ kind: HelmRelease
\ No newline at end of file
diff --git a/deploy/bfts/missions/zs24d/ses24cntl.yaml b/deploy/bfts/missions/zs24d/ses24cntl.yaml
new file mode 100644
index 0000000..d2d5731
--- /dev/null
+++ b/deploy/bfts/missions/zs24d/ses24cntl.yaml
@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: zs24dsim
+ labels:
+ app.kubernetes.io/name: spell-cws-scorpio-zs24dsim
+ app.kubernetes.io/instance: spell
+spec:
+ type: ExternalName
+ externalName: cws-lb.scorpio-zs24d.svc.cluster.local
+
diff --git a/deploy/bfts/missions/zs24e/kube-ses24-server.yaml b/deploy/bfts/missions/zs24e/kube-ses24-server.yaml
new file mode 100644
index 0000000..9b3984c
--- /dev/null
+++ b/deploy/bfts/missions/zs24e/kube-ses24-server.yaml
@@ -0,0 +1,18 @@
+---
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+ name: kube-zs24e-spell-server
+spec:
+ chart:
+ spec:
+ chart: ./deploy/spell-server
+ sourceRef:
+ kind: GitRepository
+ name: spell-repo
+ namespace: flux-system
+ interval: 10m0s
+ valuesFrom:
+ - kind: ConfigMap
+ name: kube-zs24e-spell-release
+ valuesKey: kube-ses24-values.yaml
diff --git a/deploy/bfts/missions/zs24e/kube-ses24-values.yaml b/deploy/bfts/missions/zs24e/kube-ses24-values.yaml
new file mode 100644
index 0000000..07b0b6f
--- /dev/null
+++ b/deploy/bfts/missions/zs24e/kube-ses24-values.yaml
@@ -0,0 +1,75 @@
+# Default values for spell-server.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+serviceAccountName: spell-sa
+image:
+ registry: bzengnexus1.idmz.eng.ses
+spell_server:
+ version: v2.6.8.1-dev # {"$imagepolicy": "spell:spell-server:tag"}
+ driver:
+ name: scorpio
+ env:
+ NODE_ID_zs24esim: "3369"
+ NODE_NAME_3369: zs24esim
+ properties:
+ key: value
+ settings:
+ archiva: "zs24esim"
+ FLEETLIMITS: limitsdb-api.limitsdb.svc:8080
+ FLEETLIMITS_SEAT: SIMB
+ SATDB: satdb-api.satdb.svc:8080
+ cws: "zs24esim"
+ obus: obus-test-server.obus.svc:54407
+ maxprocs: 15
+ mission: ZS24E
+ context_mission: SES24
+ family: SBNEO
+ seat: SIMB
+ applicable_missions:
+ SBNEO: "SES24,ZS24A,ZS24E,ZS24C,ZS24D,ZS24E,ZS24F"
+ input_folder: "{{ .Values.spell_server.mission }}/InputFiles"
+ output_folder: "{{ .Values.spell_server.mission }}/OutputFiles"
+ additionalInitSteps: "[ -d '/etc/pki/tls/private/wrapped_keys/' ] && (cd /etc/pki/tls/private/wrapped_keys/ && unzip -u ses24-keys.zip && (find . | grep ses24 | sed 'p;s/ses24/zs24e/' | xargs -n2 mv)) || echo 'Could not find encryption key archive!'"
+ additionalVolumeMounts:
+ - mountPath: /etc/pki/tls/private/wrapped_keys/
+ name: ses24-certs-folder
+ - mountPath: /etc/pki/tls/private/wrapped_keys/ses24-keys.zip
+ name: ses24-encryption-keys
+ subPath: ses24-keys.zip
+ - mountPath: /etc/pki/tls/zs24e_keys/zs24e_rsa.pem
+ name: ses24-encryption-cert
+ subPath: ses24_rsa.pem
+ additionalVolumes:
+ - name: ses24-certs-folder
+ emptyDir:
+ sizeLimit: 100Mi
+ medium: Memory
+ - name: ses24-encryption-cert
+ secret:
+ secretName: ses24-encryption-cert
+ optional: true
+ defaultMode: 0400
+ - name: ses24-encryption-keys
+ secret:
+ secretName: ses24-encryption-keys
+ optional: true
+ defaultMode: 0400
+procedures:
+ size: 5Gi
+ repo_folder: SES24
+ branch: SIM
+ server: bzengrcs1.idmz.eng.ses
+ known_hosts: |-
+ propsrcs1.idmz.soc.ses,10.114.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDwEclkdaNWKtL0iuulsFrzG5VGH2y2ct7uZu755g6oKKYhyTrs9ytCdS7sK5NTwDNBjiEuywXtcZcX1RyGenxc/3YQTj0aHWC3tXfVSUcbkzKle0Tdxaq+arlI35TcLLsDnaI1OWN/TMUhGasGGSwOOp2IzJP8JAuD1/iNfzhVa1SOD39jt55oDEnncHqKS25CqBNWY1XC23+gQexB+6ai+bYZutDP+IKmnx/5quPeTnIJnXRRvGHh01oTNRTlVH5Nz4evVmSQst57vNcXzY76WwDvav2u8Gu6Yz2cyngCelXnU8Ko76sRR+VxwYeZvBDbgh0//S8aWl72KFVCH9o5
+ bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ==
+ prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT
+
+auth:
+ ssh:
+ version: v2.6.7.7-dev # {"$imagepolicy": "spell:spell-server:tag"}
+ ldap:
+ url: ldaps://beacdc1.xeneng.ses
+
+service:
+ loadBalancerIP: 10.35.47.155
diff --git a/deploy/bfts/missions/zs24e/kustomization.yaml b/deploy/bfts/missions/zs24e/kustomization.yaml
new file mode 100644
index 0000000..a3a5f4a
--- /dev/null
+++ b/deploy/bfts/missions/zs24e/kustomization.yaml
@@ -0,0 +1,18 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+namespace: spell
+resources:
+- kube-ses24-server.yaml
+- ses24cntl.yaml
+
+configMapGenerator:
+- name: kube-zs24e-spell-release
+ options:
+ disableNameSuffixHash: false
+ files:
+ - kube-ses24-values.yaml
+
+
+configurations:
+- kustomizeconfig.yaml
\ No newline at end of file
diff --git a/deploy/bfts/missions/zs24e/kustomizeconfig.yaml b/deploy/bfts/missions/zs24e/kustomizeconfig.yaml
new file mode 100644
index 0000000..f6b2027
--- /dev/null
+++ b/deploy/bfts/missions/zs24e/kustomizeconfig.yaml
@@ -0,0 +1,6 @@
+nameReference:
+- kind: ConfigMap
+ version: v1
+ fieldSpecs:
+ - path: spec/valuesFrom/name
+ kind: HelmRelease
\ No newline at end of file
diff --git a/deploy/bfts/missions/zs24e/ses24cntl.yaml b/deploy/bfts/missions/zs24e/ses24cntl.yaml
new file mode 100644
index 0000000..2d408fa
--- /dev/null
+++ b/deploy/bfts/missions/zs24e/ses24cntl.yaml
@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: zs24esim
+ labels:
+ app.kubernetes.io/name: spell-cws-scorpio-zs24esim
+ app.kubernetes.io/instance: spell
+spec:
+ type: ExternalName
+ externalName: cws-lb.scorpio-zs24e.svc.cluster.local
+
diff --git a/deploy/bfts/missions/zs24f/kube-ses24-server.yaml b/deploy/bfts/missions/zs24f/kube-ses24-server.yaml
new file mode 100644
index 0000000..6770b57
--- /dev/null
+++ b/deploy/bfts/missions/zs24f/kube-ses24-server.yaml
@@ -0,0 +1,18 @@
+---
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+ name: kube-zs24f-spell-server
+spec:
+ chart:
+ spec:
+ chart: ./deploy/spell-server
+ sourceRef:
+ kind: GitRepository
+ name: spell-repo
+ namespace: flux-system
+ interval: 10m0s
+ valuesFrom:
+ - kind: ConfigMap
+ name: kube-zs24f-spell-release
+ valuesKey: kube-ses24-values.yaml
diff --git a/deploy/bfts/missions/zs24f/kube-ses24-values.yaml b/deploy/bfts/missions/zs24f/kube-ses24-values.yaml
new file mode 100644
index 0000000..b153875
--- /dev/null
+++ b/deploy/bfts/missions/zs24f/kube-ses24-values.yaml
@@ -0,0 +1,75 @@
+# Default values for spell-server.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+serviceAccountName: spell-sa
+image:
+ registry: bzengnexus1.idmz.eng.ses
+spell_server:
+ version: v2.6.8.1-dev # {"$imagepolicy": "spell:spell-server:tag"}
+ driver:
+ name: scorpio
+ env:
+ NODE_ID_zs24fsim: "3369"
+ NODE_NAME_3369: zs24fsim
+ properties:
+ key: value
+ settings:
+ archiva: "zs24fsim"
+ FLEETLIMITS: limitsdb-api.limitsdb.svc:8080
+ FLEETLIMITS_SEAT: SIMB
+ SATDB: satdb-api.satdb.svc:8080
+ cws: "zs24fsim"
+ obus: obus-test-server.obus.svc:54407
+ maxprocs: 15
+ mission: ZS24F
+ context_mission: SES24
+ family: SBNEO
+ seat: SIMB
+ applicable_missions:
+ SBNEO: "SES24,ZS24A,ZS24F,ZS24C,ZS24D,ZS24E,ZS24F"
+ input_folder: "{{ .Values.spell_server.mission }}/InputFiles"
+ output_folder: "{{ .Values.spell_server.mission }}/OutputFiles"
+ additionalInitSteps: "[ -d '/etc/pki/tls/private/wrapped_keys/' ] && (cd /etc/pki/tls/private/wrapped_keys/ && unzip -u ses24-keys.zip && (find . | grep ses24 | sed 'p;s/ses24/zs24f/' | xargs -n2 mv) ) || echo 'Could not find encryption key archive!'"
+ additionalVolumeMounts:
+ - mountPath: /etc/pki/tls/private/wrapped_keys/
+ name: ses24-certs-folder
+ - mountPath: /etc/pki/tls/private/wrapped_keys/ses24-keys.zip
+ name: ses24-encryption-keys
+ subPath: ses24-keys.zip
+ - mountPath: /etc/pki/tls/zs24f_keys/zs24f_rsa.pem
+ name: ses24-encryption-cert
+ subPath: ses24_rsa.pem
+ additionalVolumes:
+ - name: ses24-certs-folder
+ emptyDir:
+ sizeLimit: 100Mi
+ medium: Memory
+ - name: ses24-encryption-cert
+ secret:
+ secretName: ses24-encryption-cert
+ optional: true
+ defaultMode: 0400
+ - name: ses24-encryption-keys
+ secret:
+ secretName: ses24-encryption-keys
+ optional: true
+ defaultMode: 0400
+procedures:
+ size: 5Gi
+ repo_folder: SES24
+ branch: SIM
+ server: bzengrcs1.idmz.eng.ses
+ known_hosts: |-
+ propsrcs1.idmz.soc.ses,10.114.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDwEclkdaNWKtL0iuulsFrzG5VGH2y2ct7uZu755g6oKKYhyTrs9ytCdS7sK5NTwDNBjiEuywXtcZcX1RyGenxc/3YQTj0aHWC3tXfVSUcbkzKle0Tdxaq+arlI35TcLLsDnaI1OWN/TMUhGasGGSwOOp2IzJP8JAuD1/iNfzhVa1SOD39jt55oDEnncHqKS25CqBNWY1XC23+gQexB+6ai+bYZutDP+IKmnx/5quPeTnIJnXRRvGHh01oTNRTlVH5Nz4evVmSQst57vNcXzY76WwDvav2u8Gu6Yz2cyngCelXnU8Ko76sRR+VxwYeZvBDbgh0//S8aWl72KFVCH9o5
+ bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ==
+ prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT
+
+auth:
+ ssh:
+ version: v2.6.7.7-dev # {"$imagepolicy": "spell:spell-server:tag"}
+ ldap:
+ url: ldaps://beacdc1.xeneng.ses
+
+service:
+ loadBalancerIP: 10.35.47.172
diff --git a/deploy/bfts/missions/zs24f/kustomization.yaml b/deploy/bfts/missions/zs24f/kustomization.yaml
new file mode 100644
index 0000000..58f87ec
--- /dev/null
+++ b/deploy/bfts/missions/zs24f/kustomization.yaml
@@ -0,0 +1,18 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+namespace: spell
+resources:
+- kube-ses24-server.yaml
+- ses24cntl.yaml
+
+configMapGenerator:
+- name: kube-zs24f-spell-release
+ options:
+ disableNameSuffixHash: false
+ files:
+ - kube-ses24-values.yaml
+
+
+configurations:
+- kustomizeconfig.yaml
\ No newline at end of file
diff --git a/deploy/bfts/missions/zs24f/kustomizeconfig.yaml b/deploy/bfts/missions/zs24f/kustomizeconfig.yaml
new file mode 100644
index 0000000..f6b2027
--- /dev/null
+++ b/deploy/bfts/missions/zs24f/kustomizeconfig.yaml
@@ -0,0 +1,6 @@
+nameReference:
+- kind: ConfigMap
+ version: v1
+ fieldSpecs:
+ - path: spec/valuesFrom/name
+ kind: HelmRelease
\ No newline at end of file
diff --git a/deploy/bfts/missions/zs24f/ses24cntl.yaml b/deploy/bfts/missions/zs24f/ses24cntl.yaml
new file mode 100644
index 0000000..354e864
--- /dev/null
+++ b/deploy/bfts/missions/zs24f/ses24cntl.yaml
@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: zs24fsim
+ labels:
+ app.kubernetes.io/name: spell-cws-scorpio-zs24fsim
+ app.kubernetes.io/instance: spell
+spec:
+ type: ExternalName
+ externalName: cws-lb.scorpio-zs24f.svc.cluster.local
+
diff --git a/deploy/bfts/secretstore.yaml b/deploy/bfts/secretstore.yaml
new file mode 100644
index 0000000..f42d8c6
--- /dev/null
+++ b/deploy/bfts/secretstore.yaml
@@ -0,0 +1,26 @@
+# Expected Structure:
+# spell-git-access: {"id_rsa":"", "id_rsa.pub":""}
+# ldap-access: {}
+#
+#
+#
+apiVersion: external-secrets.io/v1beta1
+kind: SecretStore
+metadata:
+ name: spell-vault-backend
+spec:
+ provider:
+ vault:
+ server: "https://vault.vault:8200"
+ path: "soe/secret/spell"
+ version: "v2"
+ caProvider:
+ type: "Secret"
+ name: "vault-ca"
+ key: "ca.crt"
+ auth:
+ kubernetes:
+ mountPath: "kubernetes"
+ role: "serviceaccount"
+ serviceAccountRef:
+ name: "default"
diff --git a/deploy/pfte/externalsecret.yaml b/deploy/pfte/externalsecret.yaml
new file mode 100644
index 0000000..7a21cf4
--- /dev/null
+++ b/deploy/pfte/externalsecret.yaml
@@ -0,0 +1,34 @@
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: spell-git-access
+spec:
+ refreshInterval: "15s" # synchronisation
+ secretStoreRef:
+ name: spell-vault-backend
+ kind: SecretStore
+
+ data:
+ - secretKey: id_rsa
+ remoteRef:
+ key: /spell-git-access
+ property: id_rsa
+ - secretKey: id_rsa.pub
+ remoteRef:
+ key: /spell-git-access
+ property: id_rsa.pub
+---
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: ldap-secret
+spec:
+ refreshInterval: "15s" # synchronisation
+ secretStoreRef:
+ name: spell-vault-backend
+ kind: SecretStore
+ data:
+ - secretKey: ldap-secret
+ remoteRef:
+ key: /ldap-secret
+ property: ldap-secret
\ No newline at end of file
diff --git a/deploy/pfte/flux-policies/imagepolicy.yaml b/deploy/pfte/flux-policies/imagepolicy.yaml
new file mode 100644
index 0000000..4223022
--- /dev/null
+++ b/deploy/pfte/flux-policies/imagepolicy.yaml
@@ -0,0 +1,27 @@
+apiVersion: image.toolkit.fluxcd.io/v1beta1
+kind: ImagePolicy
+metadata:
+ name: spell-registry
+spec:
+ imageRepositoryRef:
+ name: spell-registry
+ filterTags:
+ pattern: '^v(?P[^.]+(\.[^.]+)?(\.[^.]+)?)\.?(?P[^-]*)'
+ extract: '$semver$minor'
+ policy:
+ semver:
+ range: x.x.x
+---
+apiVersion: image.toolkit.fluxcd.io/v1beta1
+kind: ImagePolicy
+metadata:
+ name: spell-server
+spec:
+ imageRepositoryRef:
+ name: spell-server
+ filterTags:
+ pattern: '^v(?P[^.]+(\.[^.]+)?(\.[^.]+)?)\.?(?P[^-]*)'
+ extract: '$semver$minor'
+ policy:
+ semver:
+ range: x.x.x
\ No newline at end of file
diff --git a/deploy/pfte/flux-policies/imagerepository.yaml b/deploy/pfte/flux-policies/imagerepository.yaml
new file mode 100644
index 0000000..b18478b
--- /dev/null
+++ b/deploy/pfte/flux-policies/imagerepository.yaml
@@ -0,0 +1,23 @@
+apiVersion: image.toolkit.fluxcd.io/v1beta1
+kind: ImageRepository
+metadata:
+ name: spell-registry
+spec:
+ certSecretRef:
+ name: nexus-ca
+ image: bzengnexus1.idmz.eng.ses/spell/spell-registry
+ interval: 1m0s
+ secretRef:
+ name: bzengnexus-secret
+---
+apiVersion: image.toolkit.fluxcd.io/v1beta1
+kind: ImageRepository
+metadata:
+ name: spell-server
+spec:
+ certSecretRef:
+ name: nexus-ca
+ image: bzengnexus1.idmz.eng.ses/spell/spell-server
+ interval: 1m0s
+ secretRef:
+ name: bzengnexus-secret
\ No newline at end of file
diff --git a/deploy/pfte/flux-policies/imageupdateautomation.yaml b/deploy/pfte/flux-policies/imageupdateautomation.yaml
new file mode 100644
index 0000000..37858a8
--- /dev/null
+++ b/deploy/pfte/flux-policies/imageupdateautomation.yaml
@@ -0,0 +1,43 @@
+apiVersion: image.toolkit.fluxcd.io/v1beta1
+kind: ImageUpdateAutomation
+metadata:
+ name: spell-repo
+ namespace: spell
+spec:
+ interval: 1m0s
+ sourceRef:
+ kind: GitRepository
+ name: spell-repo
+ namespace: flux-system
+ git:
+ checkout:
+ ref:
+ branch: jgall/container-updates
+ commit:
+ author:
+ email: fluxcdbot@users.noreply.internal.ses.com
+ name: fluxcdbot
+ messageTemplate: |
+ Automated image update
+
+ Automation name: {{ .AutomationObject }}
+
+ Files:
+ {{ range $filename, $_ := .Updated.Files -}}
+ - {{ $filename }}
+ {{ end -}}
+
+ Objects:
+ {{ range $resource, $_ := .Updated.Objects -}}
+ - {{ $resource.Kind }} {{ $resource.Name }}
+ {{ end -}}
+
+ Images:
+ {{ range .Updated.Images -}}
+ - {{.}}
+ {{ end -}}
+ push:
+ branch: flux-image-version-update
+ update:
+ path: ./deploy/pfts
+ strategy: Setters
\ No newline at end of file
diff --git a/deploy/pfte/flux-policies/nexus-ca.yaml b/deploy/pfte/flux-policies/nexus-ca.yaml
new file mode 100644
index 0000000..977340d
--- /dev/null
+++ b/deploy/pfte/flux-policies/nexus-ca.yaml
@@ -0,0 +1,6 @@
+apiVersion: v1
+data:
+ caFile: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVtVENDQTRHZ0F3SUJBZ0lUTlFBQUFVeWxRZW1sNGwrcVdRQUFBQUFCVERBTkJna3Foa2lHOXcwQkFRc0YKQURBak1TRXdId1lEVlFRREV4aFRSVk5UWldOMWNtbDBlVWx6YzNWcGJtZERRVXhWTURFd0hoY05NakF3T0RBMgpNakUwTkRReldoY05NalF3T0RBMk1qRTFORFF6V2pDQmh6RUxNQWtHQTFVRUJoTUNURlV4RVRBUEJnTlZCQWNUCkNFSmxkSHBrYjNKbU1Rd3dDZ1lEVlFRS0V3TlRSVk14RERBS0JnTlZCQXNUQTFOUFJURWhNQjhHQTFVRUF4TVkKWW5wbGJtZHVaWGgxY3pFdWFXUnRlaTVsYm1jdWMyVnpNU1l3SkFZSktvWklodmNOQVFrQkZoZEZaSGRoY21RdQpRbUZ6ZEdWc2JHbEFjMlZ6TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCCkFMbndHKzdJSTBtVCtidVp5cXU4TEd4V1NWQ3hMc1JJREpsYkZwUlNUOFdPdjh5SlpzVDBQMkNwbXZlUk9XNnMKNGNuOGs4RnBZdVRBZndLRVVTM3l5S1FyTjZobjlDZllJWVcrQ1FpcVJPQldiQWVQNVFQaDJmc3o3NURjRW5DTQoxeXRtOHZTcE05ejVHSm45b1VObTVyMEh0dmFUdVNoNzgxdEt6TEVtaHhRbE9kSWdqYzluZ2lLb1RqUC9zV2tuCkM0aU0rVEVFemtKYTNZaUZacVRsT3M5Q0JNVnhmK0IxTUMzODRvcU51YmtzSDRIVUZNbnp5cm9UOGJoVThiN1cKQk4vRUk0aEV6NDZ2ODlyZHFrdHVJZGwveklKejUrMm1ZYXRpWnc1M2VYRm1pVEV5VWNqem96YWFIdEpDWG1teQpUeDJuWnNIYllDeEs3Q3R4UWtMUTJXRUNBd0VBQWFPQ0FWOHdnZ0ZiTUIwR0ExVWREZ1FXQkJTYVc0WTUzbU1TCk1hZTJodm1qYzJhbmJIRGZNVEFmQmdOVkhTTUVHREFXZ0JTa3g2TVp3SGxoejlNaHRWWUVTRnByeC83YzBEQngKQmdOVkhSOEVhakJvTUdhZ1pLQmloaTlvZEhSd09pOHZZM0pzTG5ObGN5NWpiMjB2VTBWVFUyVmpkWEpwZEhsSgpjM04xYVc1blEwRk1WVEF4TG1OeWJJWXZhSFIwY0RvdkwyTnliQzV3YTJrdWMyVnpMMU5GVTFObFkzVnlhWFI1ClNYTnpkV2x1WjBOQlRGVXdNUzVqY213d1N3WUlLd1lCQlFVSEFRRUVQekE5TURzR0NDc0dBUVVGQnpBQ2hpOW8KZEhSd09pOHZZM0pzTG5CcmFTNXpaWE12VTBWVFUyVmpkWEpwZEhsSmMzTjFhVzVuUTBGTVZUQXhMbU55ZERBTQpCZ05WSFJNQkFmOEVBakFBTUNNR0ExVWRFUVFjTUJxQ0dHSjZaVzVuYm1WNGRYTXhMbWxrYlhvdVpXNW5Mbk5sCmN6QU9CZ05WSFE4QkFmOEVCQU1DQmFBd0ZnWURWUjBsQVFIL0JBd3dDZ1lJS3dZQkJRVUhBd0V3RFFZSktvWkkKaHZjTkFRRUxCUUFEZ2dFQkFCVlA4Z1hiVmxVTzVLNExQL1lrWXY5Ykp4MnNSODdHbjBRMi85dWZDOXpHMjJOdApYZUlCcDdqc2RDTWpNYzd4QzRWUHhTNktrSjRiUk9WZWI3V3BZK2tFbTRsSklreDNSQlhsemp4aitaT2JvVmhECjNoblNrWTRhNFFzdlJURTlucjQrYlRpSGN4ck90VGNIM244NEtFZXhjRDBwaktkN29yVWVGWHl6MjBJdTN4QjYKT0w0aHB4aEUrVkNTd1I0NXhVSFRLckt3K3pJa3VUV1NYMzBVQ0hZblExRWNTQkFKdHdLNWNkbXZtdUlXazJSdgpWSlVHSjlRQnFOV0padElUZlh3Zk4yT0ljT1VweHRPK3lXckQ5RHZGak1SYVZiUEIwMkIzNW5OcXA2QWN1N21hCnVsNjRicjlSc1grS2w2SGQ1eWltTTBieWJNTXZ4QUtpczNDaGFSMD0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
+kind: Secret
+metadata:
+ name: nexus-ca
diff --git a/deploy/pfte/kustomization.yaml b/deploy/pfte/kustomization.yaml
new file mode 100644
index 0000000..495766b
--- /dev/null
+++ b/deploy/pfte/kustomization.yaml
@@ -0,0 +1,26 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+namespace: spell
+resources:
+- ../spell-registry/
+- secretstore.yaml
+- externalsecret.yaml
+- missions/ses24/
+- flux-policies/imagepolicy.yaml
+- flux-policies/imagerepository.yaml
+- flux-policies/imageupdateautomation.yaml
+- flux-policies/nexus-ca.yaml
+
+patchesJson6902:
+ - target:
+ kind: Ingress
+ name: spell-registry
+ version: v1
+ patch: |-
+ - op: replace
+ path: "/spec/rules/0/host"
+ value: "spell-registry.ing-us-p.spo.internal.ses.com"
+ - op: replace
+ path: "/spec/tls/0/hosts/0"
+ value: "spell-registry.ing-us-p.spo.internal.ses.com"
diff --git a/deploy/pfte/missions/ses24/kube-ses24-server.yaml b/deploy/pfte/missions/ses24/kube-ses24-server.yaml
new file mode 100644
index 0000000..14f88a9
--- /dev/null
+++ b/deploy/pfte/missions/ses24/kube-ses24-server.yaml
@@ -0,0 +1,51 @@
+---
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+ name: kube-ses24-spell-server
+spec:
+ chart:
+ spec:
+ chart: ./deploy/spell-server
+ reconcileStrategy: Revision
+ sourceRef:
+ kind: GitRepository
+ name: spell-repo
+ namespace: flux-system
+ interval: 10m0s
+ valuesFrom:
+ - kind: ConfigMap
+ name: kube-ses24-spell-release
+ valuesKey: kube-ses24-values.yaml
+---
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: ses24-encryption-keys
+spec:
+ refreshInterval: "15s" # synchronisation
+ secretStoreRef:
+ name: spell-vault-backend
+ kind: SecretStore
+
+ dataFrom:
+ - extract:
+ key: /ses24-encryption
+ decodingStrategy: Auto
+
+---
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: ses24-encryption-cert
+spec:
+ refreshInterval: "15s" # synchronisation
+ secretStoreRef:
+ name: spell-vault-backend
+ kind: SecretStore
+
+ data:
+ - secretKey: ses24_rsa.pem
+ remoteRef:
+ key: /ses24-encryption
+ property: ses24_rsa.pem
diff --git a/deploy/pfte/missions/ses24/kube-ses24-values.yaml b/deploy/pfte/missions/ses24/kube-ses24-values.yaml
new file mode 100644
index 0000000..2313135
--- /dev/null
+++ b/deploy/pfte/missions/ses24/kube-ses24-values.yaml
@@ -0,0 +1,74 @@
+# Default values for spell-server.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+serviceAccountName: spell-sa
+image:
+ registry: bzengnexus1.idmz.eng.ses
+spell_server:
+ version: v2.6.6.5-dev # {"$imagepolicy": "spell:spell-server:tag"}
+ driver:
+ name: scorpio
+ env:
+ NODE_ID_ses24prod: "3369"
+ NODE_NAME_3369: ses24prod
+ properties:
+ key: value
+ settings:
+ archiva: "ses24prod"
+ FLEETLIMITS: limitsdb-api.limitsdb.svc:8080
+ FLEETLIMITS_SEAT: VALP
+ SATDB: satdb-api.satdb.svc:8080
+ cws: "ses24prod"
+ obus: obus-server.obus.svc:54407
+ maxprocs: 15
+ mission: SES24
+ family: SBNEO
+ seat: ""
+ applicable_missions:
+ SBNEO: SES24
+ input_folder: "{{ .Values.spell_server.mission }}/InputFiles"
+ output_folder: "{{ .Values.spell_server.mission }}/OutputFiles"
+ additionalInitSteps: "[ -d '/etc/pki/tls/private/wrapped_keys/' ] && (cd /etc/pki/tls/private/wrapped_keys/ && unzip -u ses24-keys.zip) || echo 'Could not find encryption key archive!'"
+ additionalVolumeMounts:
+ - mountPath: /etc/pki/tls/private/wrapped_keys/
+ name: ses24-certs-folder
+ - mountPath: /etc/pki/tls/private/wrapped_keys/ses24-keys.zip
+ name: ses24-encryption-keys
+ subPath: ses24-keys.zip
+ - mountPath: /etc/pki/tls/ses24_keys/ses24_rsa.pem
+ name: ses24-encryption-cert
+ subPath: ses24_rsa.pem
+ additionalVolumes:
+ - name: ses24-certs-folder
+ emptyDir:
+ sizeLimit: 100Mi
+ medium: Memory
+ - name: ses24-encryption-cert
+ secret:
+ secretName: ses24-encryption-cert
+ optional: true
+ defaultMode: 0400
+ - name: ses24-encryption-keys
+ secret:
+ secretName: ses24-encryption-keys
+ optional: true
+ defaultMode: 0400
+procedures:
+ size: 5Gi
+ repo_folder: SES24
+ branch: OPS
+ server: prengrcs1.idmz.eng.ses
+ known_hosts: |-
+ propsrcs1.idmz.soc.ses,10.114.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDwEclkdaNWKtL0iuulsFrzG5VGH2y2ct7uZu755g6oKKYhyTrs9ytCdS7sK5NTwDNBjiEuywXtcZcX1RyGenxc/3YQTj0aHWC3tXfVSUcbkzKle0Tdxaq+arlI35TcLLsDnaI1OWN/TMUhGasGGSwOOp2IzJP8JAuD1/iNfzhVa1SOD39jt55oDEnncHqKS25CqBNWY1XC23+gQexB+6ai+bYZutDP+IKmnx/5quPeTnIJnXRRvGHh01oTNRTlVH5Nz4evVmSQst57vNcXzY76WwDvav2u8Gu6Yz2cyngCelXnU8Ko76sRR+VxwYeZvBDbgh0//S8aWl72KFVCH9o5
+ bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ==
+ prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT
+
+auth:
+ ssh:
+ version: v2.6.6.5-dev # {"$imagepolicy": "spell:spell-server:tag"}
+ ldap:
+ url: ldaps://peacdc1.xeneng.ses
+
+service:
+ loadBalancerIP: 10.113.45.168
\ No newline at end of file
diff --git a/deploy/pfte/missions/ses24/kustomization.yaml b/deploy/pfte/missions/ses24/kustomization.yaml
new file mode 100644
index 0000000..f7b5592
--- /dev/null
+++ b/deploy/pfte/missions/ses24/kustomization.yaml
@@ -0,0 +1,18 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+namespace: spell
+resources:
+- kube-ses24-server.yaml
+- ses24cntl.yaml
+
+configMapGenerator:
+- name: kube-ses24-spell-release
+ options:
+ disableNameSuffixHash: true
+ files:
+ - kube-ses24-values.yaml
+
+
+# configurations:
+# - kustomizeconfig.yaml
\ No newline at end of file
diff --git a/deploy/pfte/missions/ses24/kustomizeconfig.yaml b/deploy/pfte/missions/ses24/kustomizeconfig.yaml
new file mode 100644
index 0000000..f6b2027
--- /dev/null
+++ b/deploy/pfte/missions/ses24/kustomizeconfig.yaml
@@ -0,0 +1,6 @@
+nameReference:
+- kind: ConfigMap
+ version: v1
+ fieldSpecs:
+ - path: spec/valuesFrom/name
+ kind: HelmRelease
\ No newline at end of file
diff --git a/deploy/pfte/missions/ses24/ses24cntl.yaml b/deploy/pfte/missions/ses24/ses24cntl.yaml
new file mode 100644
index 0000000..b0aa0da
--- /dev/null
+++ b/deploy/pfte/missions/ses24/ses24cntl.yaml
@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: ses24prod
+ labels:
+ app.kubernetes.io/name: spell-cws-scorpio-ses24cntl
+ app.kubernetes.io/instance: spell
+ app.kubernetes.io/version: "v2.6.6.5-dev" # {"$imagepolicy": "spell:spell-server:tag"}
+spec:
+ type: ExternalName
+ externalName: cws-lb.scorpio-ses24.svc.cluster.local
+
diff --git a/deploy/pfte/secretstore.yaml b/deploy/pfte/secretstore.yaml
new file mode 100644
index 0000000..f42d8c6
--- /dev/null
+++ b/deploy/pfte/secretstore.yaml
@@ -0,0 +1,26 @@
+# Expected Structure:
+# spell-git-access: {"id_rsa":"", "id_rsa.pub":""}
+# ldap-access: {}
+#
+#
+#
+apiVersion: external-secrets.io/v1beta1
+kind: SecretStore
+metadata:
+ name: spell-vault-backend
+spec:
+ provider:
+ vault:
+ server: "https://vault.vault:8200"
+ path: "soe/secret/spell"
+ version: "v2"
+ caProvider:
+ type: "Secret"
+ name: "vault-ca"
+ key: "ca.crt"
+ auth:
+ kubernetes:
+ mountPath: "kubernetes"
+ role: "serviceaccount"
+ serviceAccountRef:
+ name: "default"
diff --git a/deploy/pfts/externalsecret.yaml b/deploy/pfts/externalsecret.yaml
new file mode 100644
index 0000000..7a21cf4
--- /dev/null
+++ b/deploy/pfts/externalsecret.yaml
@@ -0,0 +1,34 @@
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: spell-git-access
+spec:
+ refreshInterval: "15s" # synchronisation
+ secretStoreRef:
+ name: spell-vault-backend
+ kind: SecretStore
+
+ data:
+ - secretKey: id_rsa
+ remoteRef:
+ key: /spell-git-access
+ property: id_rsa
+ - secretKey: id_rsa.pub
+ remoteRef:
+ key: /spell-git-access
+ property: id_rsa.pub
+---
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: ldap-secret
+spec:
+ refreshInterval: "15s" # synchronisation
+ secretStoreRef:
+ name: spell-vault-backend
+ kind: SecretStore
+ data:
+ - secretKey: ldap-secret
+ remoteRef:
+ key: /ldap-secret
+ property: ldap-secret
\ No newline at end of file
diff --git a/deploy/pfts/flux-policies/imagepolicy.yaml b/deploy/pfts/flux-policies/imagepolicy.yaml
new file mode 100644
index 0000000..4223022
--- /dev/null
+++ b/deploy/pfts/flux-policies/imagepolicy.yaml
@@ -0,0 +1,27 @@
+apiVersion: image.toolkit.fluxcd.io/v1beta1
+kind: ImagePolicy
+metadata:
+ name: spell-registry
+spec:
+ imageRepositoryRef:
+ name: spell-registry
+ filterTags:
+ pattern: '^v(?P[^.]+(\.[^.]+)?(\.[^.]+)?)\.?(?P[^-]*)'
+ extract: '$semver$minor'
+ policy:
+ semver:
+ range: x.x.x
+---
+apiVersion: image.toolkit.fluxcd.io/v1beta1
+kind: ImagePolicy
+metadata:
+ name: spell-server
+spec:
+ imageRepositoryRef:
+ name: spell-server
+ filterTags:
+ pattern: '^v(?P[^.]+(\.[^.]+)?(\.[^.]+)?)\.?(?P[^-]*)'
+ extract: '$semver$minor'
+ policy:
+ semver:
+ range: x.x.x
\ No newline at end of file
diff --git a/deploy/pfts/flux-policies/imagerepository.yaml b/deploy/pfts/flux-policies/imagerepository.yaml
new file mode 100644
index 0000000..b18478b
--- /dev/null
+++ b/deploy/pfts/flux-policies/imagerepository.yaml
@@ -0,0 +1,23 @@
+apiVersion: image.toolkit.fluxcd.io/v1beta1
+kind: ImageRepository
+metadata:
+ name: spell-registry
+spec:
+ certSecretRef:
+ name: nexus-ca
+ image: bzengnexus1.idmz.eng.ses/spell/spell-registry
+ interval: 1m0s
+ secretRef:
+ name: bzengnexus-secret
+---
+apiVersion: image.toolkit.fluxcd.io/v1beta1
+kind: ImageRepository
+metadata:
+ name: spell-server
+spec:
+ certSecretRef:
+ name: nexus-ca
+ image: bzengnexus1.idmz.eng.ses/spell/spell-server
+ interval: 1m0s
+ secretRef:
+ name: bzengnexus-secret
\ No newline at end of file
diff --git a/deploy/pfts/flux-policies/imageupdateautomation.yaml b/deploy/pfts/flux-policies/imageupdateautomation.yaml
new file mode 100644
index 0000000..37858a8
--- /dev/null
+++ b/deploy/pfts/flux-policies/imageupdateautomation.yaml
@@ -0,0 +1,43 @@
+apiVersion: image.toolkit.fluxcd.io/v1beta1
+kind: ImageUpdateAutomation
+metadata:
+ name: spell-repo
+ namespace: spell
+spec:
+ interval: 1m0s
+ sourceRef:
+ kind: GitRepository
+ name: spell-repo
+ namespace: flux-system
+ git:
+ checkout:
+ ref:
+ branch: jgall/container-updates
+ commit:
+ author:
+ email: fluxcdbot@users.noreply.internal.ses.com
+ name: fluxcdbot
+ messageTemplate: |
+ Automated image update
+
+ Automation name: {{ .AutomationObject }}
+
+ Files:
+ {{ range $filename, $_ := .Updated.Files -}}
+ - {{ $filename }}
+ {{ end -}}
+
+ Objects:
+ {{ range $resource, $_ := .Updated.Objects -}}
+ - {{ $resource.Kind }} {{ $resource.Name }}
+ {{ end -}}
+
+ Images:
+ {{ range .Updated.Images -}}
+ - {{.}}
+ {{ end -}}
+ push:
+ branch: flux-image-version-update
+ update:
+ path: ./deploy/pfts
+ strategy: Setters
\ No newline at end of file
diff --git a/deploy/pfts/flux-policies/nexus-ca.yaml b/deploy/pfts/flux-policies/nexus-ca.yaml
new file mode 100644
index 0000000..977340d
--- /dev/null
+++ b/deploy/pfts/flux-policies/nexus-ca.yaml
@@ -0,0 +1,6 @@
+apiVersion: v1
+data:
+ caFile: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVtVENDQTRHZ0F3SUJBZ0lUTlFBQUFVeWxRZW1sNGwrcVdRQUFBQUFCVERBTkJna3Foa2lHOXcwQkFRc0YKQURBak1TRXdId1lEVlFRREV4aFRSVk5UWldOMWNtbDBlVWx6YzNWcGJtZERRVXhWTURFd0hoY05NakF3T0RBMgpNakUwTkRReldoY05NalF3T0RBMk1qRTFORFF6V2pDQmh6RUxNQWtHQTFVRUJoTUNURlV4RVRBUEJnTlZCQWNUCkNFSmxkSHBrYjNKbU1Rd3dDZ1lEVlFRS0V3TlRSVk14RERBS0JnTlZCQXNUQTFOUFJURWhNQjhHQTFVRUF4TVkKWW5wbGJtZHVaWGgxY3pFdWFXUnRlaTVsYm1jdWMyVnpNU1l3SkFZSktvWklodmNOQVFrQkZoZEZaSGRoY21RdQpRbUZ6ZEdWc2JHbEFjMlZ6TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCCkFMbndHKzdJSTBtVCtidVp5cXU4TEd4V1NWQ3hMc1JJREpsYkZwUlNUOFdPdjh5SlpzVDBQMkNwbXZlUk9XNnMKNGNuOGs4RnBZdVRBZndLRVVTM3l5S1FyTjZobjlDZllJWVcrQ1FpcVJPQldiQWVQNVFQaDJmc3o3NURjRW5DTQoxeXRtOHZTcE05ejVHSm45b1VObTVyMEh0dmFUdVNoNzgxdEt6TEVtaHhRbE9kSWdqYzluZ2lLb1RqUC9zV2tuCkM0aU0rVEVFemtKYTNZaUZacVRsT3M5Q0JNVnhmK0IxTUMzODRvcU51YmtzSDRIVUZNbnp5cm9UOGJoVThiN1cKQk4vRUk0aEV6NDZ2ODlyZHFrdHVJZGwveklKejUrMm1ZYXRpWnc1M2VYRm1pVEV5VWNqem96YWFIdEpDWG1teQpUeDJuWnNIYllDeEs3Q3R4UWtMUTJXRUNBd0VBQWFPQ0FWOHdnZ0ZiTUIwR0ExVWREZ1FXQkJTYVc0WTUzbU1TCk1hZTJodm1qYzJhbmJIRGZNVEFmQmdOVkhTTUVHREFXZ0JTa3g2TVp3SGxoejlNaHRWWUVTRnByeC83YzBEQngKQmdOVkhSOEVhakJvTUdhZ1pLQmloaTlvZEhSd09pOHZZM0pzTG5ObGN5NWpiMjB2VTBWVFUyVmpkWEpwZEhsSgpjM04xYVc1blEwRk1WVEF4TG1OeWJJWXZhSFIwY0RvdkwyTnliQzV3YTJrdWMyVnpMMU5GVTFObFkzVnlhWFI1ClNYTnpkV2x1WjBOQlRGVXdNUzVqY213d1N3WUlLd1lCQlFVSEFRRUVQekE5TURzR0NDc0dBUVVGQnpBQ2hpOW8KZEhSd09pOHZZM0pzTG5CcmFTNXpaWE12VTBWVFUyVmpkWEpwZEhsSmMzTjFhVzVuUTBGTVZUQXhMbU55ZERBTQpCZ05WSFJNQkFmOEVBakFBTUNNR0ExVWRFUVFjTUJxQ0dHSjZaVzVuYm1WNGRYTXhMbWxrYlhvdVpXNW5Mbk5sCmN6QU9CZ05WSFE4QkFmOEVCQU1DQmFBd0ZnWURWUjBsQVFIL0JBd3dDZ1lJS3dZQkJRVUhBd0V3RFFZSktvWkkKaHZjTkFRRUxCUUFEZ2dFQkFCVlA4Z1hiVmxVTzVLNExQL1lrWXY5Ykp4MnNSODdHbjBRMi85dWZDOXpHMjJOdApYZUlCcDdqc2RDTWpNYzd4QzRWUHhTNktrSjRiUk9WZWI3V3BZK2tFbTRsSklreDNSQlhsemp4aitaT2JvVmhECjNoblNrWTRhNFFzdlJURTlucjQrYlRpSGN4ck90VGNIM244NEtFZXhjRDBwaktkN29yVWVGWHl6MjBJdTN4QjYKT0w0aHB4aEUrVkNTd1I0NXhVSFRLckt3K3pJa3VUV1NYMzBVQ0hZblExRWNTQkFKdHdLNWNkbXZtdUlXazJSdgpWSlVHSjlRQnFOV0padElUZlh3Zk4yT0ljT1VweHRPK3lXckQ5RHZGak1SYVZiUEIwMkIzNW5OcXA2QWN1N21hCnVsNjRicjlSc1grS2w2SGQ1eWltTTBieWJNTXZ4QUtpczNDaGFSMD0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
+kind: Secret
+metadata:
+ name: nexus-ca
diff --git a/deploy/pfts/kustomization.yaml b/deploy/pfts/kustomization.yaml
new file mode 100644
index 0000000..cc709e4
--- /dev/null
+++ b/deploy/pfts/kustomization.yaml
@@ -0,0 +1,26 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+namespace: spell
+resources:
+- ../spell-registry/
+- secretstore.yaml
+- externalsecret.yaml
+- missions/ses24/
+- flux-policies/imagepolicy.yaml
+- flux-policies/imagerepository.yaml
+- flux-policies/imageupdateautomation.yaml
+- flux-policies/nexus-ca.yaml
+
+patchesJson6902:
+ - target:
+ kind: Ingress
+ name: spell-registry
+ version: v1
+ patch: |-
+ - op: replace
+ path: "/spec/rules/0/host"
+ value: "spell-registry.ing-us-s.spo.internal.ses.com"
+ - op: replace
+ path: "/spec/tls/0/hosts/0"
+ value: "spell-registry.ing-us-s.spo.internal.ses.com"
diff --git a/deploy/pfts/missions/ses24/kube-ses24-server.yaml b/deploy/pfts/missions/ses24/kube-ses24-server.yaml
new file mode 100644
index 0000000..72c8409
--- /dev/null
+++ b/deploy/pfts/missions/ses24/kube-ses24-server.yaml
@@ -0,0 +1,51 @@
+---
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+ name: kube-ses24-spell-server
+spec:
+ chart:
+ spec:
+ chart: ./deploy/spell-server
+ reconcileStrategy: Revision
+ sourceRef:
+ kind: GitRepository
+ name: spell-repo
+ namespace: flux-system
+ interval: 10m0s
+ valuesFrom:
+ - kind: ConfigMap
+ name: kube-ses24-spell-server
+ valuesKey: kube-ses24-values.yaml
+---
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: ses24-encryption-keys
+spec:
+ refreshInterval: "15s" # synchronisation
+ secretStoreRef:
+ name: spell-vault-backend
+ kind: SecretStore
+
+ dataFrom:
+ - extract:
+ key: /ses24-encryption
+ decodingStrategy: Auto
+
+---
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: ses24-encryption-cert
+spec:
+ refreshInterval: "15s" # synchronisation
+ secretStoreRef:
+ name: spell-vault-backend
+ kind: SecretStore
+
+ data:
+ - secretKey: ses24_rsa.pem
+ remoteRef:
+ key: /ses24-encryption
+ property: ses24_rsa.pem
diff --git a/deploy/pfts/missions/ses24/kube-ses24-values.yaml b/deploy/pfts/missions/ses24/kube-ses24-values.yaml
new file mode 100644
index 0000000..f13b594
--- /dev/null
+++ b/deploy/pfts/missions/ses24/kube-ses24-values.yaml
@@ -0,0 +1,65 @@
+# Default values for spell-server.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+serviceAccountName: spell-sa
+image:
+ registry: bzengnexus1.idmz.eng.ses
+spell_server:
+ version: v2.6.6.5-dev # {"$imagepolicy": "spell:spell-server:tag"}
+ driver:
+ name: scorpio
+ env:
+ NODE_ID_ddcntl: "3369"
+ NODE_NAME_3369: ddcntl
+ properties:
+ key: value
+ settings:
+ archiva: "ddcntl"
+ FLEETLIMITS: limitsdb-api.limitsdb.svc:8080
+ SATDB: satdb-api.satdb.svc:8080
+ cws: "ddcntl"
+ obus: obus-server.obus.svc:54407
+ maxprocs: 15
+ ssh_port: 22
+ mission: SES24
+ family: SBNEO
+ seat: SIMP
+ applicable_missions:
+ SBNEO: SES24
+ input_folder: "{{ .Values.spell_server.mission }}/InputFiles"
+ output_folder: "{{ .Values.spell_server.mission }}/OutputFiles"
+ additionalInitSteps: "cd /etc/pki/tls/private/wrapped_keys/ && unzip -u ses24-keys.zip "
+ additionalVolumeMounts:
+ - mountPath: /etc/pki/tls/private/wrapped_keys/
+ name: ses24-certs-folder
+ - mountPath: /etc/pki/tls/private/wrapped_keys/ses24-keys.zip
+ name: ses24-encryption-keys
+ subPath: ses24-keys.zip
+ - mountPath: /etc/pki/tls/ses24_keys/ses24_rsa.pem
+ name: ses24-encryption-cert
+ subPath: ses24_rsa.pem
+ additionalVolumes:
+ - name: ses24-certs-folder
+ emptyDir:
+ sizeLimit: 100Mi
+ medium: Memory
+ - name: ses24-encryption-cert
+ secret:
+ secretName: ses24-encryption-cert
+ optional: false
+ defaultMode: 0400
+ - name: ses24-encryption-keys
+ secret:
+ secretName: ses24-encryption-keys
+ optional: false
+ defaultMode: 0400
+procedures:
+ size: 5Gi
+ repo_folder: SES24
+ branch: SIM
+ server: prengrcs1.idmz.eng.ses
+ known_hosts: |-
+ bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ==
+ prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT
+
diff --git a/deploy/pfts/missions/ses24/kustomization.yaml b/deploy/pfts/missions/ses24/kustomization.yaml
new file mode 100644
index 0000000..bcd399d
--- /dev/null
+++ b/deploy/pfts/missions/ses24/kustomization.yaml
@@ -0,0 +1,16 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+
+namespace: spell
+resources:
+- kube-ses24-server.yaml
+- ses24cntl.yaml
+
+configMapGenerator:
+- name: kube-ses24-spell-server
+ files:
+ - kube-ses24-values.yaml
+
+
+configurations:
+- kustomizeconfig.yaml
\ No newline at end of file
diff --git a/deploy/pfts/missions/ses24/kustomizeconfig.yaml b/deploy/pfts/missions/ses24/kustomizeconfig.yaml
new file mode 100644
index 0000000..f6b2027
--- /dev/null
+++ b/deploy/pfts/missions/ses24/kustomizeconfig.yaml
@@ -0,0 +1,6 @@
+nameReference:
+- kind: ConfigMap
+ version: v1
+ fieldSpecs:
+ - path: spec/valuesFrom/name
+ kind: HelmRelease
\ No newline at end of file
diff --git a/deploy/pfts/missions/ses24/ses24cntl.yaml b/deploy/pfts/missions/ses24/ses24cntl.yaml
new file mode 100644
index 0000000..371883e
--- /dev/null
+++ b/deploy/pfts/missions/ses24/ses24cntl.yaml
@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: ddcntl
+ labels:
+ app.kubernetes.io/name: spell-cws-scorpio-ses24cntl
+ app.kubernetes.io/instance: spell
+ app.kubernetes.io/version: "v2.6.6.5-dev" # {"$imagepolicy": "spell:spell-server:tag"}
+spec:
+ type: ExternalName
+ externalName: cws-lb.scorpio-ses24.svc.cluster.local
+
diff --git a/deploy/pfts/secretstore.yaml b/deploy/pfts/secretstore.yaml
new file mode 100644
index 0000000..f42d8c6
--- /dev/null
+++ b/deploy/pfts/secretstore.yaml
@@ -0,0 +1,26 @@
+# Expected Structure:
+# spell-git-access: {"id_rsa":"", "id_rsa.pub":""}
+# ldap-access: {}
+#
+#
+#
+apiVersion: external-secrets.io/v1beta1
+kind: SecretStore
+metadata:
+ name: spell-vault-backend
+spec:
+ provider:
+ vault:
+ server: "https://vault.vault:8200"
+ path: "soe/secret/spell"
+ version: "v2"
+ caProvider:
+ type: "Secret"
+ name: "vault-ca"
+ key: "ca.crt"
+ auth:
+ kubernetes:
+ mountPath: "kubernetes"
+ role: "serviceaccount"
+ serviceAccountRef:
+ name: "default"
diff --git a/deploy/spell-registry/deployment.yaml b/deploy/spell-registry/deployment.yaml
new file mode 100644
index 0000000..1cbffe0
--- /dev/null
+++ b/deploy/spell-registry/deployment.yaml
@@ -0,0 +1,60 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: spell-registry
+ labels:
+ app.kubernetes.io/name: spell-registry
+ app.kubernetes.io/instance: spell
+ app.kubernetes.io/version: "v2.6.5.1-dev" # {"$imagepolicy": "spell:spell-registry:tag"}
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app.kubernetes.io/name: spell-registry
+ app.kubernetes.io/instance: spell
+ app.kubernetes.io/version: "v2.6.5.1-dev" # {"$imagepolicy": "spell:spell-registry:tag"}
+ strategy:
+ rollingUpdate:
+ maxSurge: 1
+ maxUnavailable: 0
+ type: RollingUpdate
+ template:
+ metadata:
+ labels:
+ app.kubernetes.io/name: spell-registry
+ app.kubernetes.io/instance: spell
+ app.kubernetes.io/version: "v2.6.5.1-dev" # {"$imagepolicy": "spell:spell-registry:tag"}
+ spec:
+ automountServiceAccountToken: true
+ serviceAccountName: spell-registry-sa
+ securityContext:
+ runAsNonRoot: true
+ runAsUser: 1001
+ containers:
+ - image: bzengnexus1.idmz.eng.ses/spell/spell-registry:v2.6.5.1-dev # {"$imagepolicy": "spell:spell-registry"}
+ name: spell-registry
+ imagePullPolicy: Always
+ securityContext:
+ allowPrivilegeEscalation: false
+ resources:
+ requests:
+ cpu: "20m"
+ memory: "55M"
+ livenessProbe:
+ httpGet:
+ path: /healthz
+ port: 8080
+ initialDelaySeconds: 90
+ timeoutSeconds: 10
+ readinessProbe:
+ httpGet:
+ path: /healthz
+ port: 8080
+ initialDelaySeconds: 30
+ timeoutSeconds: 10
+ env:
+ - name: ENVVARNAME
+ value: ENVVARVALUE
+ ports:
+ - containerPort: 8080
+ name: http
diff --git a/deploy/spell-registry/ingress.yaml b/deploy/spell-registry/ingress.yaml
new file mode 100644
index 0000000..233b19b
--- /dev/null
+++ b/deploy/spell-registry/ingress.yaml
@@ -0,0 +1,26 @@
+# https://kubernetes.io/docs/concepts/services-networking/ingress/#the-ingress-resource
+
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: spell-registry
+ labels:
+ app.kubernetes.io/name: spell-registry
+ app.kubernetes.io/instance: spell
+ app.kubernetes.io/version: "1.0.0"
+spec:
+ rules:
+ - host: spell-registry.ing-lu-s.spo.internal.ses.com
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: spell-registry
+ port:
+ number: 8080
+ tls:
+ - secretName: ingress-tls
+ hosts:
+ - spell-registry.ing-lu-s.spo.internal.ses.com
\ No newline at end of file
diff --git a/deploy/spell-registry/kustomization.yaml b/deploy/spell-registry/kustomization.yaml
new file mode 100644
index 0000000..7a2f5ff
--- /dev/null
+++ b/deploy/spell-registry/kustomization.yaml
@@ -0,0 +1,10 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+namespace: spell
+resources:
+- sa.yaml
+- role.yaml
+- rolebinding.yaml
+- deployment.yaml
+- service.yaml
+- ingress.yaml
diff --git a/deploy/spell-registry/role.yaml b/deploy/spell-registry/role.yaml
new file mode 100644
index 0000000..7ed2865
--- /dev/null
+++ b/deploy/spell-registry/role.yaml
@@ -0,0 +1,11 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+ name: spell-registry
+rules:
+- apiGroups: [""] # "" indicates the core API group
+ resources: ["services"]
+ verbs: ["get", "watch", "list"]
+- apiGroups: ["apps"] # "" indicates the core API group
+ resources: ["deployments"]
+ verbs: ["get", "watch", "list"]
\ No newline at end of file
diff --git a/deploy/spell-registry/rolebinding.yaml b/deploy/spell-registry/rolebinding.yaml
new file mode 100644
index 0000000..c0b5a67
--- /dev/null
+++ b/deploy/spell-registry/rolebinding.yaml
@@ -0,0 +1,12 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+ name: spell-registry
+subjects:
+- name: spell-registry-sa
+ kind: ServiceAccount
+ apiGroup: ""
+roleRef:
+ kind: Role
+ name: spell-registry
+ apiGroup: rbac.authorization.k8s.io
\ No newline at end of file
diff --git a/deploy/spell-registry/sa.yaml b/deploy/spell-registry/sa.yaml
new file mode 100644
index 0000000..39366ef
--- /dev/null
+++ b/deploy/spell-registry/sa.yaml
@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: ServiceAccount
+
+metadata:
+ name: spell-registry-sa
+ labels:
+ app.kubernetes.io/name: spell-registry-sa
+ app.kubernetes.io/instance: spell
+ app.kubernetes.io/version: "1.0.0"
+
+imagePullSecrets:
+- name: bzengnexus-secret
+- name: prengnexus-secret
\ No newline at end of file
diff --git a/deploy/spell-registry/service.yaml b/deploy/spell-registry/service.yaml
new file mode 100644
index 0000000..2e33861
--- /dev/null
+++ b/deploy/spell-registry/service.yaml
@@ -0,0 +1,17 @@
+kind: Service
+apiVersion: v1
+metadata:
+ name: spell-registry
+ labels:
+ app.kubernetes.io/name: spell-registry
+ app.kubernetes.io/instance: spell
+ app.kubernetes.io/version: "1.0.0"
+spec:
+ selector:
+ app.kubernetes.io/name: spell-registry
+ app.kubernetes.io/instance: spell
+ type: ClusterIP
+ ports:
+ - name: http
+ port: 8080
+ targetPort: 8080
\ No newline at end of file
diff --git a/deploy/spell-server/.helmignore b/deploy/spell-server/.helmignore
new file mode 100644
index 0000000..0e8a0eb
--- /dev/null
+++ b/deploy/spell-server/.helmignore
@@ -0,0 +1,23 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/deploy/spell-server/Chart.yaml b/deploy/spell-server/Chart.yaml
new file mode 100644
index 0000000..d7befe4
--- /dev/null
+++ b/deploy/spell-server/Chart.yaml
@@ -0,0 +1,23 @@
+apiVersion: v2
+name: spell-server
+description: Spell Server Helm Chart
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+# Versions are expected to follow Semantic Versioning (https://semver.org/)
+version: 1.0.59
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application. Versions are not expected to
+# follow Semantic Versioning. They should reflect the version the application is using.
+# It is recommended to use it with quotes.
+appVersion: "2.6.10"
diff --git a/deploy/spell-server/configs/context.xml b/deploy/spell-server/configs/context.xml
new file mode 100644
index 0000000..e488817
--- /dev/null
+++ b/deploy/spell-server/configs/context.xml
@@ -0,0 +1,112 @@
+{{- define "spell-server.input-folder" -}}
+{{- if .Values.spell_server.input_folder -}}
+{{ tpl .Values.spell_server.input_folder . }}
+{{- else -}}
+{{ .Values.spell_server.mission }}/InputFiles
+{{- end -}}
+{{- end -}}
+{{- define "spell-server.output-folder" -}}
+{{- if .Values.spell_server.output_folder -}}
+{{ tpl .Values.spell_server.output_folder . }}
+{{- else -}}
+{{ .Values.spell_server.mission }}/OutputFiles
+{{- end -}}
+{{- end }}
+
+
+
+
+
+ {{ .Values.spell_server.mission }} Spacecraft
+ Context for {{ .Values.spell_server.mission }}
+
+
+
+
+
+ {{ .Values.spell_server.driver.name}}
+
+
+
+
+
+ {{ .Values.spell_server.spacecraft | default .Values.spell_server.mission }}
+ {{ .Values.spell_server.mission }}
+ {{ .Values.spell_server.family }}
+ {{ .Values.spell_server.driver.name}}
+
+
+
+
+
+ $SPELL_DATA/{{ .Values.spell_server.mission }}/Procedures
+ $SPELL_DATA/{{ .Values.spell_server.mission }}/UserLib
+
+ $SPELL_DATA/{{- include "spell-server.output-folder" . }}
+ $SPELL_DATA/{{- include "spell-server.input-folder" . }}
+
+
+
+
+
+{{- range $key, $value := .Values.spell_server.driver.settings }}
+ {{ tpl $value $ }}
+{{- end}}
+
+ {{ .Values.spell_server.seat }}
+
+
+
+
+
+
+
+ 0
+ 60
+ True
+ False
+ False
+ 5
+ DISABLED
+ DISABLED
+ ENABLED
+ True
+
+
+
+
+
+
+ {{- include "spell-server.input-folder" . }}/SpacecraftDB
+ {{- include "spell-server.input-folder" . }}/GroundDB
+ {{- include "spell-server.input-folder" . }}/ManeuvreMessage
+ {{- include "spell-server.input-folder" . }}/User
+ {{- include "spell-server.output-folder" . }}/AsRun
+ {{- include "spell-server.output-folder" . }}/Warmstart
+ {{- include "spell-server.input-folder" . }}/User
+ {{- include "spell-server.input-folder" . }}/EphemerisFile
+
+ SCDB
+ GDB
+
+
+
+
+
+
+
+
+ 0.0
+ 140
+
+
+ 600
+ 0.0
+
+
+ False
+ 0.0
+
+
+
+
diff --git a/deploy/spell-server/configs/driver.xml b/deploy/spell-server/configs/driver.xml
new file mode 100644
index 0000000..4e77b25
--- /dev/null
+++ b/deploy/spell-server/configs/driver.xml
@@ -0,0 +1,12 @@
+
+ {{ .Values.spell_server.driver.name | upper}} Driver
+ TM,TC,EV,RSC,TIME,RNG,TASK,MEM
+ {{ .Values.spell_server.maxprocs | default 15}}
+ {{ tpl (.Values.spell_server.driver.lib | default "$SPELL_DRIVER/lib") $ }}
+ {{ tpl (.Values.spell_server.driver.path | default "$SPELL_DRIVER/drivers") $ }}
+
+{{- range $key, $value := .Values.spell_server.driver.properties }}
+ {{ tpl $value $ }}
+{{- end}}
+
+
diff --git a/deploy/spell-server/configs/language.xml b/deploy/spell-server/configs/language.xml
new file mode 100644
index 0000000..e661f57
--- /dev/null
+++ b/deploy/spell-server/configs/language.xml
@@ -0,0 +1,236 @@
+
+
+ ABORT|SKIP|RECHECK|CANCEL
+ True
+ ENG
+ 120
+ 3
+ 0
+ False
+ None
+ True
+ ABORT|SKIP|RECHECK|CANCEL
+ NOACTION
+ False
+ False
+
+
+
+ ABORT|SKIP|RESEND|CANCEL
+ True
+ 0
+ 120
+ 0
+ None
+ False
+ True
+ ABORT|SKIP|RESEND|CANCEL
+ NOACTION
+ False
+ False
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+ True
+ INFORMATION
+ SCOPE_PROC
+ TIME_MODE_LIVE
+ True
+ NOACTION
+ NOACTION
+ ""
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+ True
+ True
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+ True
+ True
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+ True
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+ True
+
+
+
+ ABORT|SKIP|REPEAT
+ False
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+
+
+
+ ABORT|RECHECK|SKIP|CANCEL
+ ABORT|RECHECK|SKIP|CANCEL
+ True
+ None
+ False
+
+
+
+ ABORT|REPEAT|RESEND|RECHECK|SKIP|CANCEL
+ ABORT|REPEAT|RESEND|RECHECK|SKIP|CANCEL
+ True
+ 1
+
+
+
+ ABORT|SKIP|CANCEL|REPEAT
+ None
+
+
+
+ REPEAT|ABORT
+ True
+ OK_CANCEL
+ 60
+
+
+
+ None
+ ABORT|SKIP|CANCEL
+ True
+
+
+
+ ABORT|SKIP|REPEAT
+
+
+
+ ABORT|SKIP|REPEAT
+
+
+
+ ABORT|SKIP|REPEAT
+
+
+
+ 6
+ ABORT|SKIP
+
+
+
+ 6
+ "ps"
+
+
+
+ 3
+
+
+
+ True
+ True
+ True
+ ABORT|SKIP|REPEAT|CANCEL
+ True
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+
+
+
+ ABORT|SKIP|REPEAT
+
+
+
+ ABORT|SKIP|REPEAT
+
+
+
+ ABORT|SKIP|REPEAT
+
+
+
+ ABORT|SKIP|REPEAT
+
+
+
+ ABORT|SKIP|REPEAT
+
+
+
+ ABORT|SKIP|REPEAT
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+
+
+
+ ABORT|SKIP|REPEAT
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+
+
+
+ ABORT|SKIP|REPEAT
+
+
+
+ ABORT|SKIP|REPEAT
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+
+
+
+ ABORT|SKIP|REPEAT|CANCEL
+
+
+
+ ABORT|SKIP|REPEAT
+
+
+
+ ABORT|SKIP|REPEAT
+
+
+
+
diff --git a/deploy/spell-server/configs/log.properties b/deploy/spell-server/configs/log.properties
new file mode 100644
index 0000000..0a2e97d
--- /dev/null
+++ b/deploy/spell-server/configs/log.properties
@@ -0,0 +1,4 @@
+log4cplus.rootLogger=STDOUT
+log4cplus.appender.STDOUT=log4cplus::ConsoleAppender
+log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout
+log4cplus.appender.STDOUT.layout.ConversionPattern=[ %d{ %Y/%m/%d %H:%M:%S.%q} ] [%-5p] [ %h ] [ %30.30l ]: %m%n
diff --git a/deploy/spell-server/configs/scheduler_wasp.xml b/deploy/spell-server/configs/scheduler_wasp.xml
new file mode 100644
index 0000000..35b3fab
--- /dev/null
+++ b/deploy/spell-server/configs/scheduler_wasp.xml
@@ -0,0 +1,13 @@
+
+ WASP activity scheduler
+
+
+{{- range $idx,$value := .Values.spell_addons.pace.pharos }}
+ {{ $value }}
+{{- end }}
+
+
+ 15
+
+ /home/spell/.wasp
+
diff --git a/deploy/spell-server/configs/server.xml b/deploy/spell-server/configs/server.xml
new file mode 100644
index 0000000..968ad6c
--- /dev/null
+++ b/deploy/spell-server/configs/server.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+ ENABLED
+ PROC
+
+ 9
+
+ 20000
+
+ 20000
+
+ 30000
+
+ 10000
+
+ 60000
+
+
+
+
+
+
+ language.xml
+
+
+
+
+
+
+ 19823
+ 19723
+
+
+
+
+
+
+ $SPELL_HOME/bin/SPELL-Executor
+ false
+ {{ .Values.spell_server.context_mission | default .Values.spell_server.mission }}
+
+
+
+
+
+
+ 0
+ 3600
+ True
+ False
+ False
+ 5
+ DISABLED
+ DISABLED
+
+
+
+
+
+
+ driver.xml
+
+
+
+
+
+
+ context.xml
+
+
+
+
+
+
+{{- range $key, $value := .Values.spell_server.applicable_missions }}
+ {{ tpl $value $ }}
+{{- end}}
+
+
+
diff --git a/deploy/spell-server/templates/NOTES.txt b/deploy/spell-server/templates/NOTES.txt
new file mode 100644
index 0000000..d392cdf
--- /dev/null
+++ b/deploy/spell-server/templates/NOTES.txt
@@ -0,0 +1,5 @@
+1. Get the application URL by running these commands:
+ NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+ You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "spell-server.fullname" . }}'
+ export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "spell-server.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+ echo http://$SERVICE_IP:{{ .Values.service.port }}
diff --git a/deploy/spell-server/templates/_helpers.tpl b/deploy/spell-server/templates/_helpers.tpl
new file mode 100644
index 0000000..fd2fab7
--- /dev/null
+++ b/deploy/spell-server/templates/_helpers.tpl
@@ -0,0 +1,60 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "spell-server.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "spell-server.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "spell-server.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels
+*/}}
+{{- define "spell-server.labels" -}}
+helm.sh/chart: {{ include "spell-server.chart" . }}
+{{ include "spell-server.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "spell-server.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "spell-server.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+spell-mission: {{ .Values.spell_server.mission | quote }}
+spell-seat: {{ .Values.spell_server.seat | quote }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "spell-server.serviceAccountName" -}}
+{{- default "spell-sa" .Values.serviceAccountName }}
+{{- end }}
diff --git a/deploy/spell-server/templates/cm.yaml b/deploy/spell-server/templates/cm.yaml
new file mode 100644
index 0000000..1448ccf
--- /dev/null
+++ b/deploy/spell-server/templates/cm.yaml
@@ -0,0 +1,28 @@
+
+kind: ConfigMap
+apiVersion: v1
+metadata:
+ name: {{ include "spell-server.fullname" . }}
+ labels:
+ {{- include "spell-server.labels" . | nindent 4 }}
+data:
+ context.xml : |
+ {{ tpl (.Files.Get "configs/context.xml") . | indent 4 | trim}}
+
+ driver.xml : |
+ {{ tpl (.Files.Get "configs/driver.xml") . | indent 4 | trim}}
+
+ language.xml : |
+ {{ tpl (.Files.Get "configs/language.xml") . | indent 4 | trim}}
+
+ server.xml : |
+ {{ tpl (.Files.Get "configs/server.xml") . | indent 4 | trim}}
+
+ log.properties : |
+ {{ tpl (.Files.Get "configs/log.properties") . | indent 4 | trim}}
+
+ scheduler_wasp.xml: |
+ {{ tpl (.Files.Get "configs/scheduler_wasp.xml") . | indent 4 | trim}}
+
+ known_hosts: |
+ {{ .Values.procedures.known_hosts | default "" | indent 4 | trim }}
\ No newline at end of file
diff --git a/deploy/spell-server/templates/deployment.yaml b/deploy/spell-server/templates/deployment.yaml
new file mode 100644
index 0000000..1162433
--- /dev/null
+++ b/deploy/spell-server/templates/deployment.yaml
@@ -0,0 +1,410 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "spell-server.fullname" . }}
+ labels:
+ {{- include "spell-server.labels" . | nindent 4 }}
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ {{- include "spell-server.selectorLabels" . | nindent 6 }}
+ strategy:
+ rollingUpdate:
+ maxSurge: 1
+ maxUnavailable: 1
+ type: RollingUpdate
+ template:
+ metadata:
+ {{- with .Values.podAnnotations }}
+ annotations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "spell-server.selectorLabels" . | nindent 8 }}
+ spec:
+ serviceAccountName: {{ .Values.serviceAccountName | default "sa-spell" }}
+ securityContext:
+ fsGroup: 1000
+ initContainers:
+ - name: spell-driver-init
+ resources:
+ requests:
+ cpu: "20m"
+ memory: "55M"
+ limits:
+ cpu: "1"
+ memory: "1Gi"
+ image: {{ .Values.image.registry }}/spell/spell-driver-ubuntu-{{ .Values.spell_server.driver.name }}:{{ .Values.spell_server.version }}
+ command: ["cp", "-r", "/home/spell/SPELL/", "/home/spell/SPELL_DRIVER"]
+ imagePullPolicy: {{ .Values.image.pullPolicy | default "Always"}}
+ volumeMounts:
+ - mountPath: /home/spell/SPELL_DRIVER
+ name: spell-driver
+ containers:
+ - image: {{ .Values.image.registry }}/spell/spell-server-ubuntu:{{ .Values.spell_server.version }}
+ name: spell-server
+ imagePullPolicy: {{ .Values.image.pullPolicy | default "Always"}}
+ resources:
+ requests:
+ cpu: "20m"
+ memory: "55M"
+ limits:
+ cpu: "3"
+ memory: "4Gi"
+ args:
+ - {{ .Values.spell_server.mission }}
+ securityContext:
+ capabilities:
+ drop:
+ - all
+ allowPrivilegeEscalation: false
+ runAsNonRoot: true
+ runAsUser: 1001
+ runAsGroup: 1000
+ lifecycle:
+ preStop:
+ exec:
+ command:
+ - /bin/sh
+ - -c
+ - "pgrep SPELL | xargs -I{} /bin/sh -c 'echo \\\\$(ps -p {} -o comm=): >> $SPELL_LOG/SPELL_Restart_$(date +\"%Y%m%d%H%M\").log && gdb -p {} -ex \"thread apply all bt\" >> $SPELL_LOG/SPELL_Restart_$(date +\"%Y%m%d%H%M\").log 2>&1 '"
+
+ postStart:
+ exec:
+ command:
+ - "/bin/sh"
+ - "-c"
+ - "mkdir -p /home/spell/procs/DEPLOYMENT/ && cp /home/spell/SPELL/release.nfo /home/spell/procs/DEPLOYMENT ; {{ .Values.spell_server.additionalInitSteps }}"
+ env:
+ - name: SPELL_MISSION
+ value: {{ .Values.spell_server.mission }}
+ - name: SPELL_DRIVER
+ value: /home/spell/SPELL_DRIVER/SPELL
+ - name: SPELL_DATA
+ value: /home/spell/procs/SPELL_PROCS
+{{- range $key, $value := .Values.spell_server.driver.env }}
+ - name: {{$key}}
+ value: {{$value | quote}}
+{{- end }}
+ startupProbe:
+ exec:
+ command:
+ - /home/spell/SPELL/bin/SPELL-Ping
+ failureThreshold: 20
+ timeoutSeconds: 5
+ initialDelaySeconds: 30
+ periodSeconds: 30
+ livenessProbe:
+ exec:
+ command:
+ - /home/spell/SPELL/bin/SPELL-Ping
+ failureThreshold: 3
+ timeoutSeconds: 15
+ periodSeconds: 15
+ volumeMounts:
+ {{- with .Values.spell_server.additionalVolumeMounts }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ - mountPath: /home/spell/SPELL_DRIVER
+ name: spell-driver
+ - mountPath: /home/spell/SPELL_CONFIG/contexts/context.xml
+ name: {{ include "spell-server.fullname" . }}
+ subPath: context.xml
+ - mountPath: /home/spell/SPELL_CONFIG/server/server_{{ .Values.spell_server.mission }}.xml
+ name: {{ include "spell-server.fullname" . }}
+ subPath: server.xml
+ - mountPath: /home/spell/SPELL_CONFIG/spell/language.xml
+ name: {{ include "spell-server.fullname" . }}
+ subPath: language.xml
+ - mountPath: /home/spell/SPELL_CONFIG/spell/log.properties
+ name: {{ include "spell-server.fullname" . }}
+ subPath: log.properties
+ - mountPath: /home/spell/SPELL_CONFIG/spell/driver.xml
+ name: {{ include "spell-server.fullname" . }}
+ subPath: driver.xml
+ - mountPath: /home/spell/services
+ name: {{ include "spell-server.fullname" . }}
+ subPath: services
+
+ - mountPath: /home/spell/procs
+ name: spell-procs
+
+ - name: fileds
+ image: {{ .Values.image.registry }}/{{ .Values.fileds.image }}:{{ .Values.fileds.version }}
+ imagePullPolicy: {{ .Values.image.pullPolicy | default "Always"}}
+ args:
+ - "{{ .Values.procedures.server }}"
+ - "{{ .Values.spell_server.mission }}"
+ - "{{ .Values.procedures.repo_folder }}"
+ - "{{ .Values.procedures.branch }}"
+ resources:
+ requests:
+ cpu: "20m"
+ memory: "55M"
+ limits:
+ cpu: "1"
+ memory: "2Gi"
+ securityContext:
+ allowPrivilegeEscalation: false
+ runAsNonRoot: true
+ runAsUser: 1001
+ runAsGroup: 1000
+ capabilities:
+ drop: ["all"]
+ startupProbe:
+ exec:
+ command:
+ - sh
+ - -c
+ - test -d /home/spell/SPELL_PROCS/{{ .Values.spell_server.mission }}/Procedures || (echo "Checkout still in Progress" && exit 1)
+ failureThreshold: 20
+ initialDelaySeconds: 30
+ periodSeconds: 30
+ volumeMounts:
+ - name: git-ssh-key
+ mountPath: "/home/dt/.ssh/id_rsa"
+ subPath: "id_rsa"
+ readOnly: true
+ - name: git-ssh-key
+ mountPath: "/home/dt/.ssh/id_rsa.pub"
+ subPath: "id_rsa.pub"
+ readOnly: true
+ - name: git-ssh-key
+ mountPath: "/home/dt/.ssh/config"
+ subPath: "config"
+ readOnly: true
+
+ - mountPath: /home/spell/
+ name: spell-procs
+ - name: dispatch-folder
+ mountPath: /home/dispatch/
+ - name: dispatch-log-folder
+ mountPath: /home/dt/fileds/log/dispatch
+ - image: "{{ .Values.image.registry }}/{{ .Values.auth.ssh.image }}:{{ .Values.auth.ssh.version }}"
+ name: spell-ssh
+ imagePullPolicy: {{ .Values.image.pullPolicy | default "Always"}}
+ resources:
+ requests:
+ cpu: "20m"
+ memory: "55M"
+ limits:
+ cpu: "1"
+ memory: "2Gi"
+ securityContext:
+ capabilities:
+ add: ["SYS_CHROOT", "CAP_AUDIT_WRITE"]
+ readinessProbe:
+ tcpSocket:
+ port: 8422
+ initialDelaySeconds: 5
+ periodSeconds: 10
+
+ env:
+ - name: SPELL_MISSION
+ value: {{ .Values.spell_server.mission }}
+ - name: LDAP_URL
+ value: {{ .Values.auth.ssh.ldap.url }}
+ - name: LDAP_BIND_DN
+ value: {{ .Values.auth.ssh.ldap.binddn }}
+ - name: SSH_PORT
+ value: "8422"
+ - name: SPELL_HOME
+ value: /home/spell/
+ ports:
+ - containerPort: 8422
+ name: ssh
+ volumeMounts:
+ {{- with .Values.procedures.additionalVolumeMounts }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ - name: {{ .Values.auth.ssh.ldap.bindpwSecret }}
+ mountPath: /etc/ldap_password
+ subPath: ldap-secret
+ - mountPath: /home/spell
+ name: spell-procs
+{{- if .Values.spell_addons.logrotate.enabled }}
+ - image: {{ .Values.image.registry }}/{{ .Values.spell_addons.logrotate.image }}:{{ .Values.spell_addons.logrotate.version }}
+ name: logrotate
+ imagePullPolicy: {{ .Values.image.pullPolicy | default "Always"}}
+ resources:
+ requests:
+ cpu: "20m"
+ memory: "55M"
+ limits:
+ cpu: "2"
+ memory: "1000M"
+ securityContext:
+ allowPrivilegeEscalation: false
+ runAsNonRoot: true
+ runAsUser: 1001
+ runAsGroup: 1000
+ capabilities:
+ drop: ["all"]
+ env:
+ - name: SPELL_MISSION
+ value: {{ .Values.spell_server.mission }}
+ - name: SPELL_DRIVER
+ value: /home/spell/SPELL_DRIVER/SPELL
+ - name: SPELL_DATA
+ value: /home/spell/procs/SPELL_PROCS
+{{- range $key, $value := .Values.spell_addons.logrotate.env }}
+ - name: {{$key}}
+ value: {{$value | quote}}
+{{- end }}
+ volumeMounts:
+ {{- with .Values.spell_addons.logrotate.additionalVolumeMounts }}
+ {{- toYaml . | nindent 10 }}
+ {{- end }}
+ - mountPath: /home/spell/SPELL_DRIVER
+ name: spell-driver
+ - mountPath: /home/spell/SPELL_CONFIG/contexts/context_{{ .Values.spell_server.mission }}.xml
+ name: {{ include "spell-server.fullname" . }}
+ subPath: context.xml
+ - mountPath: /home/spell/SPELL_CONFIG/contexts/context.xml
+ name: {{ include "spell-server.fullname" . }}
+ subPath: context.xml
+ - mountPath: /home/spell/SPELL_CONFIG/server/server_{{ .Values.spell_server.mission }}.xml
+ name: {{ include "spell-server.fullname" . }}
+ subPath: server.xml
+ - mountPath: /home/spell/SPELL_CONFIG/spell/language.xml
+ name: {{ include "spell-server.fullname" . }}
+ subPath: language.xml
+ - mountPath: /home/spell/SPELL_CONFIG/spell/log.properties
+ name: {{ include "spell-server.fullname" . }}
+ subPath: log.properties
+ - mountPath: /home/spell/SPELL_CONFIG/spell/scheduler_wasp.xml
+ name: {{ include "spell-server.fullname" . }}
+ subPath: scheduler_wasp.xml
+ - mountPath: /home/spell/SPELL_CONFIG/spell/driver.xml
+ name: {{ include "spell-server.fullname" . }}
+ subPath: driver.xml
+ - mountPath: /home/spell/services
+ name: {{ include "spell-server.fullname" . }}
+ subPath: services
+ - mountPath: /home/spell/procs
+ name: spell-procs
+{{- end }}
+{{- if .Values.spell_addons.pace.enabled }}
+ - image: {{ .Values.image.registry }}/{{ .Values.spell_addons.pace.image }}:{{ .Values.spell_addons.pace.version }}
+ name: pace
+ imagePullPolicy: {{ .Values.image.pullPolicy | default "Always"}}
+ resources:
+ requests:
+ cpu: "20m"
+ memory: "55M"
+ limits:
+ cpu: "1"
+ memory: "500M"
+ securityContext:
+ allowPrivilegeEscalation: false
+ runAsNonRoot: true
+ runAsUser: 1001
+ runAsGroup: 1000
+ capabilities:
+ drop: ["all"]
+ args:
+{{- range $idx,$value := .Values.spell_addons.pace.args }}
+ - {{ $value }}
+{{- end }}
+ env:
+ - name: SPELL_MISSION
+ value: {{ .Values.spell_server.mission }}
+ - name: SPELL_DRIVER
+ value: /home/spell/SPELL_DRIVER/SPELL
+ - name: SPELL_DATA
+ value: /home/spell/procs/SPELL_PROCS
+{{- if .Values.spell_addons.pace.useDriver }}
+{{- range $key, $value := .Values.spell_server.driver.env }}
+ - name: {{$key}}
+ value: {{$value | quote}}
+{{- end }}
+{{- end }}
+{{- range $key, $value := .Values.spell_addons.pace.env }}
+ - name: {{$key}}
+ value: {{$value | quote}}
+{{- end }}
+ volumeMounts:
+ {{- with .Values.spell_addons.pace.additionalVolumeMounts }}
+ {{- toYaml . | nindent 10 }}
+ {{- end }}
+{{- if .Values.spell_addons.pace.useDriver }}
+ - mountPath: /home/spell/SPELL_DRIVER
+ name: spell-driver
+{{- end }}
+ - mountPath: /home/spell/SPELL_CONFIG/contexts/context_{{ .Values.spell_server.mission }}.xml
+ name: {{ include "spell-server.fullname" . }}
+ subPath: context.xml
+ - mountPath: /home/spell/SPELL_CONFIG/contexts/context.xml
+ name: {{ include "spell-server.fullname" . }}
+ subPath: context.xml
+ - mountPath: /home/spell/SPELL_CONFIG/server/server_{{ .Values.spell_server.mission }}.xml
+ name: {{ include "spell-server.fullname" . }}
+ subPath: server.xml
+ - mountPath: /home/spell/SPELL_CONFIG/spell/language.xml
+ name: {{ include "spell-server.fullname" . }}
+ subPath: language.xml
+ - mountPath: /home/spell/SPELL_CONFIG/spell/log.properties
+ name: {{ include "spell-server.fullname" . }}
+ subPath: log.properties
+ - mountPath: /home/spell/SPELL_CONFIG/spell/scheduler_wasp.xml
+ name: {{ include "spell-server.fullname" . }}
+ subPath: scheduler_wasp.xml
+ - mountPath: /home/spell/SPELL_CONFIG/spell/driver.xml
+ name: {{ include "spell-server.fullname" . }}
+ subPath: driver.xml
+ - mountPath: /home/spell/services
+ name: {{ include "spell-server.fullname" . }}
+ subPath: services
+{{- if .Values.spell_addons.pace.mountProcs }}
+ - mountPath: /home/spell/procs
+ name: spell-procs
+{{- end }}
+
+{{- end }}
+ volumes:
+ {{- with .Values.spell_addons.pace.additionalVolumes }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.spell_server.additionalVolumes }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ - name: dispatch-folder
+ emptyDir:
+ sizeLimit: 100Mi
+ - name: dispatch-log-folder
+ emptyDir:
+ sizeLimit: 1Gi
+ - name: sssd-cache-folder
+ emptyDir:
+ sizeLimit: 1Gi
+ - name: git-ssh-key
+ secret:
+ secretName: spell-git-access
+ optional: false
+ defaultMode: 0400
+ - name: spell-procs
+ persistentVolumeClaim:
+ claimName: {{ include "spell-server.fullname" . }}-pvc
+ - name: {{ .Values.auth.ssh.ldap.bindpwSecret }}
+ secret:
+ secretName: {{ .Values.auth.ssh.ldap.bindpwSecret }}
+ optional: false
+ - name: {{ include "spell-server.fullname" . }}
+ configMap:
+ name: {{ include "spell-server.fullname" . }}
+ - name: spell-driver
+ emptyDir: {}
+ restartPolicy: Always
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
\ No newline at end of file
diff --git a/deploy/spell-server/templates/pvc.yaml b/deploy/spell-server/templates/pvc.yaml
new file mode 100644
index 0000000..6503672
--- /dev/null
+++ b/deploy/spell-server/templates/pvc.yaml
@@ -0,0 +1,13 @@
+kind: PersistentVolumeClaim
+apiVersion: v1
+metadata:
+ name: {{ include "spell-server.fullname" . }}-pvc
+ labels:
+ {{- include "spell-server.labels" . | nindent 4 }}
+spec:
+ accessModes:
+ - ReadWriteOnce
+ storageClassName: {{ .Values.procedures.storageClass }}
+ resources:
+ requests:
+ storage: {{ .Values.procedures.size}}
\ No newline at end of file
diff --git a/deploy/spell-server/templates/service.yaml b/deploy/spell-server/templates/service.yaml
new file mode 100644
index 0000000..c27d001
--- /dev/null
+++ b/deploy/spell-server/templates/service.yaml
@@ -0,0 +1,24 @@
+kind: Service
+apiVersion: v1
+metadata:
+ name: {{ include "spell-server.fullname" . }}
+ labels:
+ {{- include "spell-server.labels" . | nindent 4 }}
+ annotations:
+ {{- toYaml .Values.service.annotations | nindent 4 }}
+spec:
+ selector:
+ {{- include "spell-server.selectorLabels" . | nindent 4 }}
+
+ {{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerIP)) }}
+ loadBalancerIP: {{ .Values.service.loadBalancerIP }}
+ {{- end }}
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ nodePort: {{ .Values.service.nodePort }}
+ protocol: TCP
+ name: {{ .Values.service.name }}
+ targetPort: 8422
+
+
\ No newline at end of file
diff --git a/deploy/spell-server/templates/tests/test-connection.yaml b/deploy/spell-server/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..51ab4f6
--- /dev/null
+++ b/deploy/spell-server/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ name: "{{ include "spell-server.fullname" . }}-test-connection"
+ labels:
+ {{- include "spell-server.labels" . | nindent 4 }}
+ annotations:
+ "helm.sh/hook": test
+spec:
+ containers:
+ - name: wget
+ image: busybox
+ command: ['wget']
+ args: ['{{ include "spell-server.fullname" . }}:{{ .Values.service.port }}']
+ restartPolicy: Never
diff --git a/deploy/spell-server/values.yaml b/deploy/spell-server/values.yaml
new file mode 100644
index 0000000..0bbdbef
--- /dev/null
+++ b/deploy/spell-server/values.yaml
@@ -0,0 +1,99 @@
+# Default values for spell-server.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+serviceAccountName: spell-sa
+
+image:
+ registry: bzengnexus1.idmz.eng.ses
+
+# tolerations:
+# - key: agentpool
+# operator: Equal
+# value: escorpio
+# effect: NoSchedule
+
+service:
+ annotations: {}
+ type: LoadBalancer
+ port: 22
+ name: ssh
+
+spell_addons:
+ logrotate:
+ image: spell/logrotate-ubuntu
+ version: 2.6.10
+ enabled: true
+ env:
+ LOGROTATE_INTERVAL: "daily"
+ DELAYED_START: 30
+ additionalVolumeMounts: []
+ additionalVolumes: []
+ pace:
+ image: spell/pace
+ enabled: false
+ version: 2.0.7
+ useDriver: true
+ mountProcs: true
+ env: {}
+ additionalVolumeMounts: []
+ # - mountPath: /home/spell/.wasp
+ # name: wasp-secret
+ # subPath: ".wasp"
+ # readonly: true
+ additionalVolumes: []
+ # - name: wasp-secret
+ # secret:
+ # secretName: wasp-secret
+ # optional: true
+ # defaultMode: 0400
+ args: []
+ # - "ZMP01"
+ pharos: []
+
+auth:
+ mode: ssh #clear/ssh
+ ssh:
+ version: v2.6.8-dev
+ image: spell/ssh-server-ubuntu
+ ldap:
+ url: ldaps://beacdc1.xeneng.ses
+ binddn: CN=ldap,OU=G_SYS,OU=ses-users,DC=xeneng,DC=ses
+ bindpwSecret: ldap-secret
+
+fileds:
+ version: 1.3.7-dev
+ image: spell/fileds-ubuntu
+
+spell_server:
+ version: v2.6.8-dev # {"$imagepolicy": "spell:spell-server:tag"}
+ driver:
+ name: scorpio
+ lib: "$SPELL_DRIVER/drivers/{{ .Values.spell_server.driver.name }}/interface"
+ env: {}
+ properties: {}
+ settings: {}
+ #cws: "{{ .Values.spell_server.seat | lower }}cntl.scorpio.eng.ses"
+ #archiva: "{{ .Values.spell_server.seat | lower }}dbs01.scorpio.eng.ses"
+ #obus: bfts-ob.eng.ses:54407
+ maxprocs: 15
+ mission: ZMP01
+ spacecraft: null
+ family: BSS702SP
+ seat: S3
+ applicable_missions: {}
+ input_folder: "{{ .Values.spell_server.mission }}/InputFiles/{{ .Values.spell_server.mission }}"
+ output_folder: "{{ .Values.spell_server.mission }}/OutputFiles/{{ .Values.spell_server.mission }}"
+ additionalVolumeMounts: []
+ additionalVolumes: []
+ additionalInitSteps: ""
+procedures:
+ additionalVolumeMounts: []
+ storageClass: null
+ size: 5Gi
+ repo_folder: MPOWER
+ branch: SIM
+ server: bzengrcs1.idmz.eng.ses
+ known_hosts: |-
+ bzengrcs1.idmz.eng.ses,10.35.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3Hjvq/uZqY8nxGeB8sQiq5sLaq4T8h3BTnHkElLjq1C6lJ+5hV9OgiYdf9NCMwZuES5ENQAFqB2GnHjDc0X4sz6K/tk3pqGXQ/wdwVA+ZylBunpv5CJqKyQO+mu+pbke9yhZNuGZeGi7x8cmhQgZ5xOYQdW2ijMecQ/hxO2+598hiIB1nsCWcVnX4zV07cpgViRkZd/cA8J/TekYG3058fDekPTtVwOVVnG25W1jSVzY/wuV0pSwraRCesiLkE4XSF59RDMn0HEqLgy6iy0Gj5nWY4cJ3Fct/VyDjqZhVM/Lr6d6avo3Io7c7rUM055fKfu2Xh8iMluYMK7PSrwMDQ==
+ prengrcs1.idmz.eng.ses,10.113.65.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkcQiI+f8S43Yy8lyZ+mbCbJdMi4sH19yXXJ6BKemsm2wiVcX/q+cYrsjYLCayd8/AJdS4tBzGZegXgQ3YSnhzuoNlKFg4UqRnnsU4ynwa+VU38dbxrSTZKUhumFYvZ749d55GIwHZnardMb0ZROYO+mga8beYRbe7bWLlqCUpRgsNkz8wuzS2fd/u+J9T+I7Z7iYNpD91IIeqlch6EXPix4piD/beoD4W+1tXSd6UKDEARANqAsF+mdv6OfOVsfzV06A65+XuoR8gZn0W6ieojm6CdlIU/8i+q7EyVf0q9TMjPCVEvZOdNI1x9a06fezQdQpETDtVuVJDbr/TpDRT
\ No newline at end of file
diff --git a/docker/.dockerignore b/docker/.dockerignore
new file mode 100644
index 0000000..e69de29
diff --git a/docker/Makefile b/docker/Makefile
new file mode 100644
index 0000000..41f481e
--- /dev/null
+++ b/docker/Makefile
@@ -0,0 +1,14 @@
+# default: all
+
+REPO := bzengnexus1.idmz.eng.ses/
+# TAG := 1.0.0
+
+TOPTARGETS := all push
+
+SUBDIRS := $(wildcard */.)
+
+$(TOPTARGETS): $(SUBDIRS)
+$(SUBDIRS):
+ $(MAKE) -C $@ $(MAKECMDGOALS) REPO=$(REPO)
+
+.PHONY: $(TOPTARGETS) $(SUBDIRS)
diff --git a/docker/drivers/Makefile b/docker/drivers/Makefile
new file mode 100644
index 0000000..bc563b8
--- /dev/null
+++ b/docker/drivers/Makefile
@@ -0,0 +1,13 @@
+# default: all
+
+REPO := bzengnexus1.idmz.eng.ses/
+
+TOPTARGETS := all push
+
+SUBDIRS := $(wildcard */.)
+
+$(TOPTARGETS): $(SUBDIRS)
+$(SUBDIRS):
+ $(MAKE) -C $@ $(MAKECMDGOALS) REPO=$(REPO)
+
+.PHONY: $(TOPTARGETS) $(SUBDIRS)
diff --git a/docker/drivers/example/Dockerfile b/docker/drivers/example/Dockerfile
new file mode 100644
index 0000000..79391d2
--- /dev/null
+++ b/docker/drivers/example/Dockerfile
@@ -0,0 +1,26 @@
+ARG BUILD_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0
+ARG RUNTIME_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0
+
+FROM ${BUILD_IMAGE} as builder
+USER spell
+WORKDIR /home/spell/SPELL_BUILD
+
+COPY --chown=spell . .
+RUN mkdir -p /home/spell/SPELL && chown spell:spell /home/spell/SPELL
+ENV SPELL_COTS=/home/spell/SPELL_COTS
+
+RUN ./build_driver.sh /home/spell/SPELL example "" "-DWITH_DEBUG -DWITH_KUBERNETES"
+
+FROM ${RUNTIME_IMAGE}
+
+COPY --chown=spell --from=builder /home/spell/SPELL /home/spell/SPELL
+
+ENV SPELL_HOME=/home/spell/SPELL
+ENV SPELL_CONFIG=/home/spell/SPELL_CONFIG
+ENV SPELL_DATA=/home/spell/procs/SPELL_PROCS
+ENV SPELL_LOG=/home/spell/procs/SPELL_LOG
+ENV PATH=$SPELL_HOME/bin:$SPELL_COTS/bin:$PATH
+ENV SPELL_DRIVER=/home/spell/SPELL_DRIVER/SPELL
+ENV LD_LIBRARY_PATH=$SPELL_HOME/lib:$SPELL_DRIVER/lib:$SPELL_COTS/lib
+
+USER spell
diff --git a/docker/drivers/example/Makefile b/docker/drivers/example/Makefile
new file mode 100644
index 0000000..47e3d50
--- /dev/null
+++ b/docker/drivers/example/Makefile
@@ -0,0 +1,20 @@
+default: build
+
+REPO := bzengnexus1.idmz.eng.ses/
+NAME := spell/spell-driver-ubuntu-example
+COMMIT := $(shell git rev-parse --short HEAD)
+TAG := $(shell git describe --abbrev=0 --tags ${COMMIT} 2>/dev/null || true)
+TAG_COMMIT := $(shell git rev-list -n 1 --abbrev-commit ${TAG})
+
+VERSION := $(TAG:v%=%)
+ifneq ($(COMMIT), $(TAG_COMMIT))
+ VERSION := $(VERSION)-dev
+endif
+TAG := $(VERSION)
+
+build:
+ docker build --build-arg http_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg https_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg no_proxy=10.113.66.135,10.35.66.136,localhost,eng.ses,xeneng.ses,az.ses -t $(REPO)$(NAME):v$(TAG) ../../../ -f ./Dockerfile
+
+push:
+ docker push $(REPO)$(NAME):v$(TAG)
+
diff --git a/docker/drivers/fuzzer/Dockerfile b/docker/drivers/fuzzer/Dockerfile
new file mode 100644
index 0000000..ff3de18
--- /dev/null
+++ b/docker/drivers/fuzzer/Dockerfile
@@ -0,0 +1,25 @@
+ARG BUILD_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0
+ARG RUNTIME_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0
+
+FROM ${BUILD_IMAGE} as builder
+USER spell
+WORKDIR /home/spell/SPELL_BUILD
+
+COPY --chown=spell . .
+RUN mkdir -p /home/spell/SPELL && chown spell:spell /home/spell/SPELL
+ENV SPELL_COTS=/home/spell/SPELL_COTS
+
+RUN ./build_driver.sh /home/spell/SPELL fuzzer "" "-DWITH_DEBUG -DWITH_KUBERNETES"
+
+FROM ${RUNTIME_IMAGE}
+COPY --chown=spell --from=builder /home/spell/SPELL /home/spell/SPELL
+
+ENV SPELL_HOME=/home/spell/SPELL
+ENV SPELL_CONFIG=/home/spell/SPELL_CONFIG
+ENV SPELL_DATA=/home/spell/procs/SPELL_PROCS
+ENV SPELL_LOG=/home/spell/procs/SPELL_LOG
+ENV PATH=$SPELL_HOME/bin:$SPELL_COTS/bin:$PATH
+ENV SPELL_DRIVER=/home/spell/SPELL_DRIVER/SPELL
+ENV LD_LIBRARY_PATH=$SPELL_HOME/lib:$SPELL_DRIVER/lib:$SPELL_COTS/lib
+
+USER spell
diff --git a/docker/drivers/fuzzer/Makefile b/docker/drivers/fuzzer/Makefile
new file mode 100644
index 0000000..d44ccf0
--- /dev/null
+++ b/docker/drivers/fuzzer/Makefile
@@ -0,0 +1,20 @@
+default: build
+
+REPO := bzengnexus1.idmz.eng.ses/
+NAME := spell/spell-driver-ubuntu-fuzzer
+COMMIT := $(shell git rev-parse --short HEAD)
+TAG := $(shell git describe --abbrev=0 --tags ${COMMIT} 2>/dev/null || true)
+TAG_COMMIT := $(shell git rev-list -n 1 --abbrev-commit ${TAG})
+
+VERSION := $(TAG:v%=%)
+ifneq ($(COMMIT), $(TAG_COMMIT))
+ VERSION := $(VERSION)-dev
+endif
+TAG := $(VERSION)
+
+build:
+ docker build --build-arg http_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg https_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg no_proxy=10.113.66.135,10.35.66.136,localhost,eng.ses,xeneng.ses,az.ses -t $(REPO)$(NAME):v$(TAG) ../../../ -f ./Dockerfile
+
+push:
+ docker push $(REPO)$(NAME):v$(TAG)
+
diff --git a/docker/drivers/hifly2/Dockerfile b/docker/drivers/hifly2/Dockerfile
new file mode 100644
index 0000000..9e053f9
--- /dev/null
+++ b/docker/drivers/hifly2/Dockerfile
@@ -0,0 +1,39 @@
+ARG BUILD_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0
+ARG RUNTIME_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0
+
+FROM ${BUILD_IMAGE} as builder
+USER root
+RUN apt-get update && apt-get install -y omniidl libomniorb4-dev && rm -rf /var/cache/apt/archives /var/lib/apt/lists/*
+
+USER spell
+
+RUN mkdir -p /home/spell/SPELL_BUILD
+WORKDIR /home/spell/SPELL_BUILD
+
+COPY --chown=spell . .
+RUN mkdir -p /home/spell/SPELL
+ENV SPELL_COTS=/home/spell/SPELL_COTS
+
+#RUN ./build_spell.sh /home/spell/SPELL "none" "-DWITH_DEBUG -DWITH_KUBERNETES"
+
+RUN cd drivers/hifly2 && ./generate_stubs.sh 6 && cd ../.. && ./build_driver.sh /home/spell/SPELL hifly "SPELL_SYN SPELL_UTIL SPELL_WRP" "-DWITH_DEBUG -DWITH_KUBERNETES"
+
+FROM ${RUNTIME_IMAGE}
+
+USER spell
+COPY --from=builder --chown=spell /home/spell/SPELL /home/spell/SPELL
+
+ENV SPELL_HOME=/home/spell/SPELL
+ENV SPELL_CONFIG=/home/spell/SPELL_CONFIG
+ENV SPELL_DATA=/home/spell/procs/SPELL_PROCS
+ENV SPELL_LOG=/home/spell/procs/SPELL_LOG
+ENV PATH=$SPELL_HOME/bin:$SPELL_COTS/bin:$PATH
+ENV SPELL_DRIVER=/home/spell/SPELL_DRIVER/SPELL
+ENV LD_LIBRARY_PATH=$SPELL_HOME/lib:$SPELL_DRIVER/lib:$SPELL_COTS/lib
+
+RUN chmod u+rwx -R /home/spell && chmod g+rx -R /home/spell
+
+USER root
+COPY drivers/scorpio/services /services
+RUN cat /services >> /etc/services && rm /services
+USER spell
diff --git a/docker/drivers/hifly2/Makefile b/docker/drivers/hifly2/Makefile
new file mode 100644
index 0000000..8825538
--- /dev/null
+++ b/docker/drivers/hifly2/Makefile
@@ -0,0 +1,21 @@
+default: build
+
+REPO := bzengnexus1.idmz.eng.ses/
+NAME := spell/spell-driver-ubuntu-hifly2
+COMMIT := $(shell git rev-parse --short HEAD)
+TAG := $(shell git describe --abbrev=0 --tags ${COMMIT} 2>/dev/null || true)
+TAG_COMMIT := $(shell git rev-list -n 1 --abbrev-commit ${TAG})
+
+VERSION := $(TAG:v%=%)
+ifneq ($(COMMIT), $(TAG_COMMIT))
+ VERSION := $(VERSION)-dev
+endif
+TAG := $(VERSION)
+
+
+build:
+ docker build --build-arg http_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg https_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg no_proxy=10.113.66.135,10.35.66.136,localhost,eng.ses,xeneng.ses,az.ses -t $(REPO)$(NAME):v$(TAG) ../../../ -f ./Dockerfile
+
+push:
+ docker push $(REPO)$(NAME):v$(TAG)
+
diff --git a/docker/drivers/scorpio/Dockerfile b/docker/drivers/scorpio/Dockerfile
new file mode 100644
index 0000000..f01a1aa
--- /dev/null
+++ b/docker/drivers/scorpio/Dockerfile
@@ -0,0 +1,30 @@
+ARG BUILD_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0
+ARG RUNTIME_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0
+
+FROM ${BUILD_IMAGE} as builder
+USER spell
+WORKDIR /home/spell/SPELL_BUILD
+
+COPY --chown=spell . .
+RUN mkdir -p /home/spell/SPELL && chown spell:spell /home/spell/SPELL
+ENV SPELL_COTS=/home/spell/SPELL_COTS
+
+RUN ./build_driver.sh /home/spell/SPELL scorpio "" "-DWITH_DEBUG -DWITH_KUBERNETES"
+
+FROM ${RUNTIME_IMAGE}
+
+COPY --chown=spell --from=builder /home/spell/SPELL /home/spell/SPELL
+COPY --chown=spell --from=builder /home/spell/SPELL_BUILD/build/drivers/scorpio/ITC_wrap* /home/spell/SPELL/drivers/scorpio/interface/
+
+ENV SPELL_HOME=/home/spell/SPELL
+ENV SPELL_CONFIG=/home/spell/SPELL_CONFIG
+ENV SPELL_DATA=/home/spell/procs/SPELL_PROCS
+ENV SPELL_LOG=/home/spell/procs/SPELL_LOG
+ENV PATH=$SPELL_HOME/bin:$SPELL_COTS/bin:$PATH
+ENV SPELL_DRIVER=/home/spell/SPELL_DRIVER/SPELL
+ENV LD_LIBRARY_PATH=$SPELL_HOME/lib:$SPELL_DRIVER/lib:$SPELL_COTS/lib
+
+USER root
+COPY drivers/scorpio/services /services
+RUN cat /services >> /etc/services && rm /services
+USER spell
diff --git a/docker/drivers/scorpio/Makefile b/docker/drivers/scorpio/Makefile
new file mode 100644
index 0000000..21800e9
--- /dev/null
+++ b/docker/drivers/scorpio/Makefile
@@ -0,0 +1,20 @@
+default: build
+
+REPO := bzengnexus1.idmz.eng.ses/
+NAME := spell/spell-driver-ubuntu-scorpio
+COMMIT := $(shell git rev-parse --short HEAD)
+TAG := $(shell git describe --abbrev=0 --tags ${COMMIT} 2>/dev/null || true)
+TAG_COMMIT := $(shell git rev-list -n 1 --abbrev-commit ${TAG})
+
+VERSION := $(TAG:v%=%)
+ifneq ($(COMMIT), $(TAG_COMMIT))
+ VERSION := $(VERSION)-dev
+endif
+TAG := $(VERSION)
+
+build:
+ docker build --build-arg http_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg https_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg no_proxy=10.113.66.135,10.35.66.136,localhost,eng.ses,xeneng.ses,az.ses -t $(REPO)$(NAME):v$(TAG) ../../../ -f ./Dockerfile
+
+push:
+ docker push $(REPO)$(NAME):v$(TAG)
+
diff --git a/docker/logrotate/Dockerfile b/docker/logrotate/Dockerfile
new file mode 100644
index 0000000..37cd20e
--- /dev/null
+++ b/docker/logrotate/Dockerfile
@@ -0,0 +1,37 @@
+ARG UBUNTU_VERSION=22.04
+ARG NEXUS_REPO=docker-weu.spo.internal.ses.com/
+
+FROM ${NEXUS_REPO}ubuntu:${UBUNTU_VERSION} as base
+
+# permissions
+ARG CONTAINER_UID=1001
+ARG CONTAINER_GID=1000
+
+COPY ./go-cron.tar.gz /tmp/go-cron.tar.gz
+
+# install dev tools
+RUN export CONTAINER_USER=logrotate && \
+ export CONTAINER_GROUP=logrotate && \
+ addgroup --group --gid $CONTAINER_GID logrotate && \
+ adduser --uid $CONTAINER_UID --ingroup logrotate --home /usr/bin/logrotate.d --shell /bin/bash --system logrotate && \
+ apt-get update && apt-get install -y \
+ tini \
+ tar \
+ gzip \
+ tzdata \
+ logrotate && \
+ mkdir -p /usr/bin/logrotate.d && \
+ tar xvf /tmp/go-cron.tar.gz -C /usr/bin && \
+ rm -rf /var/cache/apt/archives /var/lib/apt/lists/*
+
+COPY docker-entrypoint.sh /usr/bin/logrotate.d/docker-entrypoint.sh
+COPY logrotate.conf /usr/bin/logrotate.d/logrotate.conf
+
+# environment variable for this container
+ENV LOGROTATE_INTERVAL= \
+ LOG_PATHS=
+
+
+ENTRYPOINT ["/bin/tini","--","/usr/bin/logrotate.d/docker-entrypoint.sh"]
+VOLUME ["/logrotate-status"]
+CMD ["cron"]
\ No newline at end of file
diff --git a/docker/logrotate/Makefile b/docker/logrotate/Makefile
new file mode 100644
index 0000000..6d17139
--- /dev/null
+++ b/docker/logrotate/Makefile
@@ -0,0 +1,21 @@
+default: build
+
+REPO := bzengnexus1.idmz.eng.ses/
+NAME := spell/logrotate-ubuntu
+COMMIT := $(shell git rev-parse --short HEAD)
+TAG := $(shell git describe --abbrev=0 --tags ${COMMIT} 2>/dev/null || true)
+TAG_COMMIT := $(shell git rev-list -n 1 --abbrev-commit ${TAG})
+
+VERSION := $(TAG:v%=%)
+ifneq ($(COMMIT), $(TAG_COMMIT))
+ VERSION := $(VERSION)-dev
+endif
+TAG := $(VERSION)
+
+
+build:
+ docker build --build-arg NEXUS_REPO= --build-arg VERSION_TAG=2.6.10 --build-arg http_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg https_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg no_proxy=10.113.66.135,10.35.66.136,localhost,eng.ses,xeneng.ses,az.ses -t $(REPO)$(NAME):v$(TAG) ./ -f ./Dockerfile
+
+push:
+ docker push $(REPO)$(NAME):v$(TAG)
+
diff --git a/docker/logrotate/docker-entrypoint.sh b/docker/logrotate/docker-entrypoint.sh
new file mode 100644
index 0000000..5054085
--- /dev/null
+++ b/docker/logrotate/docker-entrypoint.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+#
+
+
+if [ -n "${DELAYED_START}" ]; then
+ sleep ${DELAYED_START}
+fi
+
+logrotate_croninterval="@daily"
+
+if [ -n "${LOGROTATE_INTERVAL}" ]; then
+ case "$LOGROTATE_INTERVAL" in
+ hourly)
+ logrotate_croninterval='@hourly'
+ ;;
+ daily)
+ logrotate_croninterval='@daily'
+ ;;
+ weekly)
+ logrotate_croninterval='@weekly'
+ ;;
+ monthly)
+ logrotate_croninterval='@monthly'
+ ;;
+ yearly)
+ logrotate_croninterval='@yearly'
+ ;;
+ *)
+ logrotate_croninterval="$LOGROTATE_INTERVAL"
+ ;;
+ esac
+fi
+
+logrotate_cron_timetable="/usr/sbin/logrotate --state=/tmp/logrotate.status /usr/bin/logrotate.d/logrotate.conf"
+
+if [ "$1" = 'cron' ]; then
+ exec /usr/bin/go-cron "${logrotate_croninterval}" /bin/bash -c "${logrotate_cron_timetable}"
+else
+ exec "$@"
+fi
+
diff --git a/docker/logrotate/go-cron.tar.gz b/docker/logrotate/go-cron.tar.gz
new file mode 100644
index 0000000..8133551
Binary files /dev/null and b/docker/logrotate/go-cron.tar.gz differ
diff --git a/docker/logrotate/logrotate.conf b/docker/logrotate/logrotate.conf
new file mode 100644
index 0000000..c7b1772
--- /dev/null
+++ b/docker/logrotate/logrotate.conf
@@ -0,0 +1,12 @@
+/home/spell/procs/SPELL_LOG/*.log {
+ daily
+ su logrotate logrotate
+ rotate 4
+ size 10M
+ compress
+ missingokq
+ copytruncate
+ notifempty
+}
+
+
diff --git a/docker/spell-registry/.gitignore b/docker/spell-registry/.gitignore
new file mode 100644
index 0000000..9e79245
--- /dev/null
+++ b/docker/spell-registry/.gitignore
@@ -0,0 +1,32 @@
+# macOS
+.DS_Store
+
+# sbt specific
+dist/*
+target/
+lib_managed/
+src_managed/
+project/boot/
+project/plugins/project/
+project/local-plugins.sbt
+.history
+.ensime
+.ensime_cache/
+.sbt-scripted/
+local.sbt
+
+# Bloop
+.bsp
+
+# VS Code
+.vscode/
+
+# Metals
+.bloop/
+.metals/
+metals.sbt
+
+# IDEA
+.idea
+.idea_modules
+/.worksheet/
diff --git a/docker/spell-registry/.scalafmt.conf b/docker/spell-registry/.scalafmt.conf
new file mode 100644
index 0000000..8cd9640
--- /dev/null
+++ b/docker/spell-registry/.scalafmt.conf
@@ -0,0 +1,2 @@
+version = "3.5.3"
+runner.dialect = scala3
\ No newline at end of file
diff --git a/docker/spell-registry/Makefile b/docker/spell-registry/Makefile
new file mode 100644
index 0000000..d2d433e
--- /dev/null
+++ b/docker/spell-registry/Makefile
@@ -0,0 +1,23 @@
+default: build
+
+REPO := bzengnexus1.idmz.eng.ses/
+NAME := spell/spell-registry
+COMMIT := $(shell git rev-parse --short HEAD)
+TAG := $(shell git describe --abbrev=0 --tags ${COMMIT} 2>/dev/null || true)
+TAG_COMMIT := $(shell git rev-list -n 1 --abbrev-commit ${TAG})
+
+VERSION := $(TAG:v%=%)
+ifneq ($(COMMIT), $(TAG_COMMIT))
+ VERSION := $(VERSION)-dev
+endif
+TAG := $(VERSION)
+
+
+build:
+# docker run -it --rm -e http_proxy=http://bzengpx1.idmz.eng.ses:8080 -e https_proxy=http://bzengpx1.idmz.eng.ses:8080 -e no_proxy=10.113.66.135,10.35.66.136,localhost,eng.ses,xeneng.ses,az.ses -v $(PWD):/app -w /app sbtscala/scala-sbt:eclipse-temurin-19_36_1.8.0_3.2.1 sbt docker:publishLocal
+ VERSION=$(TAG) sbt docker:publishLocal
+
+push:
+ docker tag spell-registry:$(TAG) $(REPO)$(NAME):v$(TAG)
+ docker push $(REPO)$(NAME):v$(TAG)
+
diff --git a/docker/spell-registry/README.md b/docker/spell-registry/README.md
new file mode 100644
index 0000000..6999c4f
--- /dev/null
+++ b/docker/spell-registry/README.md
@@ -0,0 +1,85 @@
+# openapi-client
+
+Swagger Spell Registry - OpenAPI 3.0
+- API version: 1.0.0
+
+Spell Registry Interface
+
+
+*Automatically generated by the [OpenAPI Generator](https://openapi-generator.tech)*
+
+## Requirements
+
+Building the API client library requires:
+1. Java 1.7+
+2. Maven/Gradle/SBT
+
+## Installation
+
+To install the API client library to your local Maven repository, simply execute:
+
+```shell
+mvn clean install
+```
+
+To deploy it to a remote Maven repository instead, configure the settings of the repository and execute:
+
+```shell
+mvn clean deploy
+```
+
+Refer to the [OSSRH Guide](http://central.sonatype.org/pages/ossrh-guide.html) for more information.
+
+### Maven users
+
+Add this dependency to your project's POM:
+
+```xml
+
+ org.openapitools
+ openapi-client
+ 1.0.0
+ compile
+
+```
+
+### Gradle users
+
+Add this dependency to your project's build file:
+
+```groovy
+compile "org.openapitools:openapi-client:1.0.0"
+```
+
+### SBT users
+
+```scala
+libraryDependencies += "org.openapitools" % "openapi-client" % "1.0.0"
+```
+
+## Getting Started
+
+## Documentation for API Endpoints
+
+All URIs are relative to *http://spell-registry.bftd-kube.eng.ses/api/v1*
+
+Class | Method | HTTP request | Description
+------------ | ------------- | ------------- | -------------
+*RegistryApi* | **listSpellServers** | **GET** /list | Finds SPELL servers and return their status and connection infos
+*ServerApi* | **listSpellServers** | **GET** /list | Finds SPELL servers and return their status and connection infos
+
+
+## Documentation for Models
+
+ - [SpellServer](SpellServer.md)
+
+
+## Documentation for Authorization
+
+All endpoints do not require authorization.
+Authentication schemes defined for the API:
+
+## Author
+
+juergen.gall@ses.com
+
diff --git a/docker/spell-registry/build.sbt b/docker/spell-registry/build.sbt
new file mode 100644
index 0000000..4e652fe
--- /dev/null
+++ b/docker/spell-registry/build.sbt
@@ -0,0 +1,33 @@
+val scala3Version = "3.2.1"
+
+Global / onChangedBuildSource := ReloadOnSourceChanges
+
+val artifactVersion = sys.env.getOrElse("VERSION", "1.0.0")
+
+lazy val root = project
+ .in(file("."))
+ .settings(
+ name := "spell-registry",
+ inThisBuild(List(
+ version := artifactVersion,
+ organization := "com.ses",
+ )),
+
+ scalaVersion := scala3Version,
+ dockerExposedPorts ++= Seq(8080),
+ dockerBaseImage := "docker-weu.spo.internal.ses.com/eclipse-temurin:19.0.1_10-jre-alpine",
+
+ libraryDependencies += "org.scalameta" %% "munit" % "0.7.29" % Test,
+ libraryDependencies ++= Seq(
+ "com.goyeau" %% "kubernetes-client" % "0.9.0",
+ "com.typesafe" % "config" % "1.4.2",
+ "org.http4s" %% "http4s-ember-server" % "0.23.16"
+ ),
+ dockerUsername := Some("spell"),
+ dockerAutoremoveMultiStageIntermediateImages := false,
+ dockerAliases := Seq(
+ dockerAlias.value.withTag(Option("latest")).withRegistryHost(Option("docker-weu.spo.internal.ses.com")),
+ dockerAlias.value.withRegistryHost(Option("docker-weu.spo.internal.ses.com"))
+ ),
+ )
+ .enablePlugins(JavaAppPackaging).enablePlugins(AshScriptPlugin).enablePlugins(DockerPlugin)
diff --git a/docker/spell-registry/project/build.properties b/docker/spell-registry/project/build.properties
new file mode 100644
index 0000000..8b9a0b0
--- /dev/null
+++ b/docker/spell-registry/project/build.properties
@@ -0,0 +1 @@
+sbt.version=1.8.0
diff --git a/docker/spell-registry/project/plugins.sbt b/docker/spell-registry/project/plugins.sbt
new file mode 100644
index 0000000..edc9886
--- /dev/null
+++ b/docker/spell-registry/project/plugins.sbt
@@ -0,0 +1,2 @@
+
+addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.9.4")
diff --git a/docker/spell-registry/src/main/resources/application.conf b/docker/spell-registry/src/main/resources/application.conf
new file mode 100644
index 0000000..12e57b8
--- /dev/null
+++ b/docker/spell-registry/src/main/resources/application.conf
@@ -0,0 +1,2 @@
+apiserver="https://kubernetes.default"
+server_port=8080
\ No newline at end of file
diff --git a/docker/spell-registry/src/main/scala/KubeAPI.scala b/docker/spell-registry/src/main/scala/KubeAPI.scala
new file mode 100644
index 0000000..85c29fd
--- /dev/null
+++ b/docker/spell-registry/src/main/scala/KubeAPI.scala
@@ -0,0 +1,78 @@
+package com.ses
+
+import cats.effect.IO
+import com.goyeau.kubernetes.client.*
+import org.typelevel.log4cats.Logger
+import org.typelevel.log4cats.slf4j.Slf4jLogger
+import java.io.File
+import org.http4s.AuthScheme
+import org.http4s.Credentials.Token
+import org.http4s.headers.Authorization
+import org.http4s.implicits.*
+import scala.concurrent.ExecutionContext
+import scala.io.Source
+import com.typesafe.config.Config
+import com.typesafe.config.ConfigFactory
+import org.http4s.Uri
+import org.http4s.ParseFailure
+import io.k8s.api.core.v1.Service
+import io.k8s.api.core.v1.ServiceList
+import cats.effect.unsafe.implicits.global
+import io.k8s.api.core.v1.Pod
+import io.k8s.api.apps.v1.Deployment
+
+
+object KubeAPI {
+ implicit val config: Config = ConfigFactory.load("application")
+
+ val apiServer = Uri.fromString(config.getString("apiserver")) match {
+ case Left(ParseFailure(sanitized, details)) => {
+ uri"https://kubernetes.default"
+ }
+ case Right(uri) => uri
+ }
+ lazy val namespace = Source
+ .fromFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace")
+ .mkString
+
+ lazy val kubernetesClient =
+ KubernetesClient[IO](
+ KubeConfig.of[IO](
+ server = apiServer,
+ authorization = Option(
+ Authorization(
+ Token(
+ AuthScheme.Bearer,
+ Source
+ .fromFile("/var/run/secrets/kubernetes.io/serviceaccount/token")
+ .mkString
+ )
+ )
+ ),
+ caCertFile = Option(
+ new File("/var/run/secrets/kubernetes.io/serviceaccount/ca.crt")
+ )
+ )
+ )
+ def requestHealth() =
+ KubeAPI.kubernetesClient != null
+
+ def requestServices(): ServiceList =
+ KubeAPI.kubernetesClient.use { client =>
+ {
+ for {
+ serviceList <- client.services.namespace(namespace).list(Map("app.kubernetes.io/name" -> "spell-server"))
+ } yield (serviceList)
+ }
+ }.unsafeRunSync()
+
+ def getDeployment(name : String) : Deployment =
+ KubeAPI.kubernetesClient.use { client =>
+ {
+ for {
+ serviceList <- client.deployments.namespace(namespace).get(name)
+ } yield (serviceList)
+ }
+ }.unsafeRunSync()
+
+}
diff --git a/docker/spell-registry/src/main/scala/Main.scala b/docker/spell-registry/src/main/scala/Main.scala
new file mode 100644
index 0000000..533da32
--- /dev/null
+++ b/docker/spell-registry/src/main/scala/Main.scala
@@ -0,0 +1,34 @@
+package com.ses
+
+import cats.effect.IO
+import com.goyeau.kubernetes.client.*
+import org.typelevel.log4cats.Logger
+import org.typelevel.log4cats.slf4j.Slf4jLogger
+import java.io.File
+import org.http4s._
+import org.http4s.AuthScheme
+import org.http4s.Credentials.Token
+import org.http4s.headers.Authorization
+import org.http4s.implicits.*
+import scala.concurrent.ExecutionContext
+import scala.io.Source
+import com.typesafe.config.Config
+import com.typesafe.config.ConfigFactory
+import org.http4s.Uri
+import org.http4s.ParseFailure
+import org.http4s.HttpRoutes
+import cats.effect.ExitCode
+import com.ses.SpellServerService
+import cats.effect.IOApp
+
+implicit val logger: Logger[IO] = Slf4jLogger.getLogger[IO]
+implicit val config: Config = ConfigFactory.load("application")
+
+
+object Main extends IOApp {
+
+ override def run(args: List[String]): IO[ExitCode] = {
+ SpellServerService.serverStream[IO].useForever.as(ExitCode.Success)
+ }
+
+}
diff --git a/docker/spell-registry/src/main/scala/SpellServerService.scala b/docker/spell-registry/src/main/scala/SpellServerService.scala
new file mode 100644
index 0000000..9111802
--- /dev/null
+++ b/docker/spell-registry/src/main/scala/SpellServerService.scala
@@ -0,0 +1,121 @@
+package com.ses
+
+import com.comcast.ip4s._
+import org.http4s.dsl.Http4sDsl
+import org.http4s.ember.server.EmberServerBuilder
+import cats.effect._
+import cats.syntax.all._
+import fs2.Stream
+import io.circe.Json
+import org.http4s._
+import org.http4s.circe._
+import org.http4s.dsl.Http4sDsl
+import org.http4s.headers._
+import org.http4s.multipart.Multipart
+import org.http4s.server._
+import org.http4s.server.middleware.authentication.BasicAuth
+import org.http4s.server.middleware.authentication.BasicAuth.BasicAuthenticator
+import org.http4s.syntax.all._
+import com.typesafe.config.Config
+import scala.util.Try
+
+import io.circe._, io.circe.generic.auto._, io.circe.parser._, io.circe.syntax._
+import org.typelevel.log4cats.Logger
+import org.typelevel.log4cats.slf4j.Slf4jLogger
+
+sealed trait SpellMessage
+case class SpellError(error: String) extends SpellMessage
+
+case class SpellService(
+ name: String,
+ mission: String,
+ seat: String,
+ ip: String,
+ contextPort: Int,
+ sshPort: Int,
+ running: Boolean
+)
+
+object SpellServerService {
+ implicit val logger: Logger[IO] = Slf4jLogger.getLogger[IO]
+
+ def serverStream[F[_]: Async](implicit
+ config: Config
+ ) = {
+ val port = Port.fromString(config.getString("server_port")) match {
+ case None => port"8080"
+ case Some(p) => p
+ }
+
+ EmberServerBuilder.default
+ .withPort(port)
+ .withHost(host"0.0.0.0")
+ .withHttpApp(new SpellServerServiceRoutes[F].routes.orNotFound)
+ .withLogger(Slf4jLogger.getLogger[F])
+ .build
+ }
+
+}
+
+class SpellServerServiceRoutes[F[_]: Sync] extends Http4sDsl[F] {
+
+ val routes: HttpRoutes[F] =
+ HttpRoutes.of[F] {
+ case GET -> Root / "healthz" => {
+ Try {
+ val services = KubeAPI.requestHealth().asJson
+
+ Ok(services)
+ }.handleError { f =>
+ val result = SpellError(s"Failed with ${f}").asJson
+
+ InternalServerError(result)
+ }.get
+ }
+
+ case req @ GET -> Root / "list" =>
+ Try {
+ val services = KubeAPI
+ .requestServices()
+ .items
+ .map[SpellService](kubeService =>
+ val name = kubeService.metadata.get.name.get
+ val labels = kubeService.metadata.get.labels.getOrElse(Map())
+ val ip = kubeService.status.fold(None)(status =>
+ status.loadBalancer.fold(None)(lb =>
+ lb.ingress.fold(None)(lbi =>
+ if (lbi.isEmpty) None
+ else lbi.get(0).fold(None)(f => f.ip)
+ )
+ )
+ )
+ val port = kubeService.spec.get.ports
+ .getOrElse(Seq())
+ .find(f => f.name.getOrElse("") == "ssh")
+ .fold(None)(p => Some(p.port))
+ val deployment = KubeAPI.getDeployment(name)
+ SpellService(
+ name = name,
+ mission = labels
+ .getOrElse("mission", labels.getOrElse("spell-mission", "")),
+ seat =
+ labels.getOrElse("seat", labels.getOrElse("spell-seat", "")),
+ ip = ip.getOrElse(""),
+ contextPort = 19823,
+ sshPort = port.getOrElse(-1),
+ running = ip.isDefined && port.isDefined && (labels.isDefinedAt(
+ "mission"
+ ) || labels.isDefinedAt("spell-mission")) && (labels
+ .isDefinedAt("seat") || labels.isDefinedAt("spell-seat")) && deployment.status.fold(false)(st => st.availableReplicas.fold(false)(_ > 0))
+ )
+ )
+
+ Ok(services.asJson)
+ }.handleError { f =>
+ val result = SpellError(s"Failed with ${f}").asJson
+
+ Ok(result)
+ }.get
+
+ }
+}
diff --git a/docker/spell-registry/src/test/scala/MySuite.scala b/docker/spell-registry/src/test/scala/MySuite.scala
new file mode 100644
index 0000000..621784d
--- /dev/null
+++ b/docker/spell-registry/src/test/scala/MySuite.scala
@@ -0,0 +1,9 @@
+// For more information on writing tests, see
+// https://scalameta.org/munit/docs/getting-started.html
+class MySuite extends munit.FunSuite {
+ test("example test that succeeds") {
+ val obtained = 42
+ val expected = 42
+ assertEquals(obtained, expected)
+ }
+}
diff --git a/docker/spell-server/Dockerfile b/docker/spell-server/Dockerfile
new file mode 100644
index 0000000..7f8b05d
--- /dev/null
+++ b/docker/spell-server/Dockerfile
@@ -0,0 +1,43 @@
+ARG BUILD_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0
+ARG RUNTIME_IMAGE=prengnexus1.idmz.eng.ses/spell/spell-cots-ubuntu-build:v1.0.0
+ARG VERSION_TAG=0.0.1
+
+FROM ${BUILD_IMAGE} as builder
+ARG VERSION_TAG
+
+USER root
+RUN apt-get update && apt-get install -y libbackward-cpp-dev libdw-dev \
+ && rm -rf /var/cache/apt/archives /var/lib/apt/lists/*
+
+USER spell
+RUN mkdir -p /home/spell/SPELL_BUILD
+WORKDIR /home/spell/SPELL_BUILD
+
+COPY --chown=spell . /home/spell/SPELL_BUILD
+RUN mkdir -p /home/spell/SPELL && chown spell /home/spell/SPELL
+ENV SPELL_COTS=/home/spell/SPELL_COTS
+ENV LD_LIBRARY_PATH=$SPELL_HOME/lib:$SPELL_DRIVER/lib:$SPELL_COTS/lib
+
+RUN cd /home/spell/SPELL_BUILD && ./build_spell_ubuntu.sh /home/spell/SPELL "none" "-DBACKWARD_HAS_DW=1 -DWITH_BACKTRACE -DWITH_DEBUG -DWITH_KUBERNETES"
+
+FROM ${RUNTIME_IMAGE}
+USER spell
+COPY --chown=spell --from=builder /home/spell/SPELL /home/spell/SPELL
+
+ENV SPELL_HOME=/home/spell/SPELL
+ENV SPELL_CONFIG=/home/spell/SPELL_CONFIG
+ENV SPELL_DATA=/home/spell/procs/SPELL_PROCS
+ENV SPELL_LOG=/home/spell/procs/SPELL_LOG
+ENV PATH=$SPELL_HOME/bin:$SPELL_COTS/bin:$PATH
+ENV SPELL_DRIVER=/home/spell/SPELL_DRIVER/SPELL
+ENV LD_LIBRARY_PATH=$SPELL_HOME/lib:$SPELL_DRIVER/lib:$SPELL_COTS/lib
+
+WORKDIR /home/spell
+RUN ln -sf /home/spell/procs/SPACECRAFT SPACECRAFT && ln -sf /home/spell/procs/SPELL_PROCS SPELL_PROCS
+
+USER root
+COPY --from=builder /home/spell/SPELL_BUILD/drivers/scorpio/services /services
+RUN cat /services >> /etc/services && rm /services
+USER spell
+
+ENTRYPOINT ["SPELL-Server-Docker"]
diff --git a/docker/spell-server/Makefile b/docker/spell-server/Makefile
new file mode 100644
index 0000000..aa5649b
--- /dev/null
+++ b/docker/spell-server/Makefile
@@ -0,0 +1,21 @@
+default: build
+
+REPO := bzengnexus1.idmz.eng.ses/
+NAME := spell/spell-server-ubuntu
+COMMIT := $(shell git rev-parse --short HEAD)
+TAG := $(shell git describe --abbrev=0 --tags ${COMMIT} 2>/dev/null || true)
+TAG_COMMIT := $(shell git rev-list -n 1 --abbrev-commit ${TAG})
+
+VERSION := $(TAG:v%=%)
+ifneq ($(COMMIT), $(TAG_COMMIT))
+ VERSION := $(VERSION)-dev
+endif
+TAG := $(VERSION)
+
+
+build:
+ docker build --build-arg VERSION_TAG=2.6.10 --build-arg http_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg https_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg no_proxy=10.113.66.135,10.35.66.136,localhost,eng.ses,xeneng.ses,az.ses -t $(REPO)$(NAME):v$(TAG) ../../ -f ./Dockerfile
+
+push:
+ docker push $(REPO)$(NAME):v$(TAG)
+
diff --git a/docker/ssh-server/Dockerfile b/docker/ssh-server/Dockerfile
new file mode 100644
index 0000000..8ef7a57
--- /dev/null
+++ b/docker/ssh-server/Dockerfile
@@ -0,0 +1,22 @@
+ARG UBUNTU_VERSION=22.04
+
+FROM docker-weu.spo.internal.ses.com/ubuntu:${UBUNTU_VERSION} as base
+
+RUN apt-get update && apt-get install -y openssh-server net-tools sssd nscd libnss-ldap libpam-ldap ldap-auth-config libpam-sss libnss-sss sssd-tools \
+ && rm -rf /var/cache/apt/archives /var/lib/apt/lists/*
+RUN apt-get update && apt-get install -y rxvt-unicode \
+ && rm -rf /var/cache/apt/archives /var/lib/apt/lists/*
+
+RUN groupadd spell && useradd -rm -d /home/spell -s /sbin/nologin -g spell -G spell -u 1001 spell
+
+RUN mkdir -p /var/run/sshd
+ADD init.sh /init.sh
+RUN chmod u+x /init.sh
+
+
+EXPOSE 8422
+RUN chmod u+rwx -R /home/ && mkdir -p /usr/libexec/openssh/ && ln -s /usr/lib/sftp-server /usr/libexec/openssh/sftp-server && ln -s /usr/lib/sftp-server /bin/sftp-server && chmod g+rx -R /home/ && touch /etc/services && pam-auth-update --enable mkhomedir
+
+ENV TERM=xterm
+
+CMD /init.sh
\ No newline at end of file
diff --git a/docker/ssh-server/Dockerfile.centos b/docker/ssh-server/Dockerfile.centos
new file mode 100644
index 0000000..0fc489d
--- /dev/null
+++ b/docker/ssh-server/Dockerfile.centos
@@ -0,0 +1,25 @@
+
+FROM centos:7 as base
+
+RUN yum-config-manager --save --disable base && rm /etc/yum.repos.d/*
+COPY etc/yum.repos.d/* /etc/yum.repos.d/
+
+RUN yum makecache fast && yum update -y
+RUN yum-config-manager --save --disable base --disable extras --disable updates
+RUN yum clean all && yum install -y \
+ openssl net-tools \
+ nss-pam-ldapd nscd openldap-clients openssh-server openssh-clients rsyslog authconfig \
+ && yum clean all
+
+RUN groupadd spell && useradd -rm -d /home/spell -s /sbin/nologin -g spell -G spell -u 1001 spell
+
+RUN mkdir -p /var/run/sshd
+ADD init.sh /init.sh
+RUN chmod u+x /init.sh
+
+
+EXPOSE 8422
+RUN chmod u+rwx -R /home/ && chmod g+rx -R /home/
+
+CMD /init.sh
+
diff --git a/docker/ssh-server/Makefile b/docker/ssh-server/Makefile
new file mode 100644
index 0000000..93fa37d
--- /dev/null
+++ b/docker/ssh-server/Makefile
@@ -0,0 +1,20 @@
+default: build
+
+REPO := bzengnexus1.idmz.eng.ses/
+NAME := spell/ssh-server-ubuntu
+COMMIT := $(shell git rev-parse --short HEAD)
+TAG := $(shell git describe --abbrev=0 --tags ${COMMIT} 2>/dev/null || true)
+TAG_COMMIT := $(shell git rev-list -n 1 --abbrev-commit ${TAG})
+
+VERSION := $(TAG:v%=%)
+ifneq ($(COMMIT), $(TAG_COMMIT))
+ VERSION := $(VERSION)-dev
+endif
+TAG := $(VERSION)
+
+build:
+ docker build --build-arg http_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg https_proxy=http://bzengpx1.idmz.eng.ses:8080 --build-arg no_proxy=10.113.66.135,10.35.66.136,localhost,eng.ses,xeneng.ses,az.ses -t $(REPO)$(NAME):v$(TAG) .
+
+push:
+ docker push $(REPO)$(NAME):v$(TAG)
+
diff --git a/docker/ssh-server/etc/yum.repos.d/bzenginst1.repo b/docker/ssh-server/etc/yum.repos.d/bzenginst1.repo
new file mode 100644
index 0000000..08ec4e9
--- /dev/null
+++ b/docker/ssh-server/etc/yum.repos.d/bzenginst1.repo
@@ -0,0 +1,7 @@
+[bzenginst1]
+name=YUM repo on bzenginst1.idmz.eng.ses
+baseurl=http://10.35.66.136/centos/$releasever/$basearch
+enabled=1
+gpgcheck=0
+proxy=_none_
+
diff --git a/docker/ssh-server/init.sh b/docker/ssh-server/init.sh
new file mode 100644
index 0000000..bfa26ba
--- /dev/null
+++ b/docker/ssh-server/init.sh
@@ -0,0 +1,237 @@
+#!/bin/bash
+#
+
+#LDAP_PASSWORD=
+
+[ -z "${LDAP_PASSWORD}" ] && LDAP_PASSWORD=$(cat /etc/ldap_password)
+[ -z "${LDAP_URL}" ] && LDAP_URL=$(cat /etc/ldap_url)
+[ -z "${LDAP_URL}" ] && LDAP_URL="ldaps://beacdc1.xeneng.ses"
+[ -z "${SSH_PORT}" ] && SSH_PORT=8422
+[ -z "${LDAP_BIND_DN}" ] && LDAP_BIND_DN="CN=ldap,OU=G_SYS,OU=ses-users,DC=xeneng,DC=ses"
+[ -z "${LDAP_SEARCH_BASE}" ] && LDAP_SEARCH_BASE="OU=ses-users,DC=xeneng,DC=ses"
+
+[ -f /etc/ssh/ssh_host_rsa_key ] || ssh-keygen -f /etc/ssh/ssh_host_rsa_key -q -N ''
+
+mkdir -p /var/lib/sss/db/
+cat > /etc/sssd/sssd.conf < /sshd_config < /home/spell/groups/\" \$7 \" &\"
+ system(cmd)
+ print substr(\$4,p+1) \"=\" \$7
+ }' > /home/spell/users"
+# id -G -n \$7
\ No newline at end of file
diff --git a/drivers/Makefile.am b/drivers/Makefile.am
index 03a1e42..ab61088 100644
--- a/drivers/Makefile.am
+++ b/drivers/Makefile.am
@@ -1,5 +1,41 @@
-SUBDIRS=
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
-if WITH_DRIVER_STD
-SUBDIRS+=standalone
+SUBDIRS = example
+
+if WITH_DRIVER_HIFLY
+SUBDIRS += hifly2
+endif
+
+if WITH_DRIVER_SCORPIO
+SUBDIRS += scorpio
endif
+
+SERVICE=${top_srcdir}/drivers/service
+SERVICE_DST=${exec_prefix}/drivers/service
+
+all-local:
+ find ${SERVICE} -type f -name "*.py" -print0 | xargs -0 -n1 sh -c LD_LIBRARY_PATH=${SPELL_COTS}/lib ${PYTHON2} ${top_srcdir}/scripts/src/SPELL-Compile
+ find ${SERVICE} -type f -name "*.py" -print0 | xargs -0 -n1 sh -c LD_LIBRARY_PATH=${SPELL_COTS}/lib ${PYTHON3} ${top_srcdir}/scripts/src/SPELL-Compile
+
+install-exec-hook:
+ mkdir -p ${SERVICE_DST}
+ cp -ur ${SERVICE}/*.py ${SERVICE_DST}
diff --git a/drivers/example/Makefile.am b/drivers/example/Makefile.am
index db5e249..fe55830 100644
--- a/drivers/example/Makefile.am
+++ b/drivers/example/Makefile.am
@@ -1,53 +1,36 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
DRIVER=example
-DRIVER_SRC=src
-DRIVER_CFG=config
+DRIVER_SRC=${srcdir}/python
+DRIVER_CFG=${srcdir}/config
+DRIVER_DST=${exec_prefix}/drivers/${DRIVER}
+CONFIG_DST=${exec_prefix}/config/spell
all-local:
- if [[ ! -d ${DRIVER_SRC} ]] ;\
- then \
- cp -r ${top_srcdir}/drivers/${DRIVER}/${DRIVER_SRC} . > /dev/null ;\
- fi
- ${top_srcdir}/py-compiledir ${DRIVER_SRC}
-
-clean-local:
- find ${DRIVER_SRC} -name "*.pyc" | xargs rm -f
- find ${DRIVER_SRC} -name "*.pyo" | xargs rm -f
- rm -f ${DRIVER_SRC}/build.date
+ find ${DRIVER_SRC} -type f -name "*.py" -print0 | xargs -0 -n1 sh -c LD_LIBRARY_PATH=${SPELL_COTS}/lib ${PYTHON2} ${top_srcdir}/scripts/src/SPELL-Compile
+ find ${DRIVER_SRC} -type f -name "*.py" -print0 | xargs -0 -n1 sh -c LD_LIBRARY_PATH=${SPELL_COTS}/lib ${PYTHON3} ${top_srcdir}/scripts/src/SPELL-Compile
install-exec-hook:
- if [[ ! -d ${exec_prefix}/drivers ]] ;\
- then \
- mkdir ${exec_prefix}/drivers ;\
- fi
- rm -rf ${exec_prefix}/drivers/${DRIVER}
- cp -r ${DRIVER_SRC} ${exec_prefix}/drivers/${DRIVER}
- find ${exec_prefix}/drivers/${DRIVER} -name ".svn" | xargs rm -rf
- find ${exec_prefix}/drivers/${DRIVER} -name ".py" | xargs rm -f
- mkdir -p ${exec_prefix}/config/spell
- cp -f ${DRIVER_CFG}/driver_${DRIVER}.xml ${exec_prefix}/config/spell/.
+ mkdir -p ${DRIVER_DST}
+ cp -ur ${DRIVER_SRC}/* ${DRIVER_DST}
+ mkdir -p ${CONFIG_DST}
+ cp -u ${DRIVER_CFG}/driver_${DRIVER}.xml ${exec_prefix}/config/spell
diff --git a/drivers/example/config/driver_example.xml b/drivers/example/config/driver_example.xml
index ddb841d..a579dc3 100644
--- a/drivers/example/config/driver_example.xml
+++ b/drivers/example/config/driver_example.xml
@@ -1,6 +1,6 @@
Example SPELL driver
- TM,TC,EV,TIME,TASK,RSC,USR
+ TM,TC,EV,TIME,TASK,RSC,USER
5
$SPELL_HOME/drivers
diff --git a/drivers/example/python/__init__.py b/drivers/example/python/__init__.py
new file mode 100644
index 0000000..c37d2df
--- /dev/null
+++ b/drivers/example/python/__init__.py
@@ -0,0 +1,25 @@
+###################################################################################
+## MODULE : __init__
+## DATE : Mar 18, 2011
+## PROJECT : SPELL
+## DESCRIPTION: Module initialization
+## --------------------------------------------------------------------------------
+##
+## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+##
+## This file is part of SPELL.
+##
+## This component is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This software is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with SPELL. If not, see .
+##
+###################################################################################
diff --git a/drivers/example/python/config.py b/drivers/example/python/config.py
new file mode 100644
index 0000000..b8d933e
--- /dev/null
+++ b/drivers/example/python/config.py
@@ -0,0 +1,100 @@
+###################################################################################
+## MODULE : config
+## DATE : Mar 18, 2011
+## PROJECT : SPELL
+## DESCRIPTION:
+## --------------------------------------------------------------------------------
+##
+## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+##
+## This file is part of SPELL.
+##
+## This component is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This software is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with SPELL. If not, see .
+##
+###################################################################################
+
+#*******************************************************************************
+# SPELL Imports
+#*******************************************************************************
+from spell.lib.exception import DriverException
+
+#*******************************************************************************
+# Local Imports
+#*******************************************************************************
+
+#*******************************************************************************
+# System Imports
+#*******************************************************************************
+import os,sys
+
+###############################################################################
+# Module import definition
+
+__all__ = ['CONFIG']
+
+INTERFACE_DEFAULTS = {}
+
+###############################################################################
+# Superclass
+import spell.lib.adapter.config.ConfigInterface as superClass
+
+###############################################################################
+# The configuration interface is typically in charge of managing resources and
+# mechanisms that have nothing to do with specific services like TM, TC and EV.
+# This interface normally prepares the ground so that the service interfaces
+# like TM can initialize properly. The configuration interface is the first
+# on being initialized.
+###############################################################################
+class ConfigInterface(superClass):
+
+ #==========================================================================
+ def __init__(self):
+ """
+ Perform the initialization of your data here, after the superClass
+ initialization.
+ """
+ superClass.__init__(self)
+ # TODO Your initialization stuff here
+
+ #==========================================================================
+ def setup(self, ctxConfig, drvConfig):
+ """
+ Start the internal driver mechanisms (typically, start a centralized
+ internal service that manages all driver capabilities)
+
+ ctxConfig : provides the current context information (S/C name and others)
+ drvConfig : provides the configuration parameters for this driver according
+ to the xml config file.
+ """
+ superClass.setup(self, ctxConfig, drvConfig)
+ # TODO Initialize here the driver internal mechanisms
+ # Throw DriverException in case of fatal errors
+
+ #==========================================================================
+ def cleanup(self, shutdown = False):
+ """
+ Perform the cleanup of the internal driver resources.
+
+ shutdown: when true, the SPELL executor is shutting down so every resource
+ should be released. When false, it means that the driver is being unloaded
+ but the executor keeps running. That is, it is possible that the driver
+ will be loaded again later on (e.g. on a RELOAD command). In this case
+ it may be interesting to keep some resources ready when 'shutdown' is false.
+ """
+ superClass.cleanup(self, shutdown)
+ # TODO Release resources and cleanup stuff here
+
+###############################################################################
+# Interface instance
+CONFIG = ConfigInterface()
diff --git a/drivers/example/python/constants.py b/drivers/example/python/constants.py
new file mode 100644
index 0000000..f393547
--- /dev/null
+++ b/drivers/example/python/constants.py
@@ -0,0 +1,30 @@
+###################################################################################
+## MODULE : constants
+## DATE : Mar 18, 2011
+## PROJECT : SPELL
+## DESCRIPTION: Definition of driver specific constants
+## --------------------------------------------------------------------------------
+##
+## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+##
+## This file is part of SPELL.
+##
+## This component is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This software is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with SPELL. If not, see .
+##
+###################################################################################
+
+#: Example constant
+MY_CONSTANT = 'MY_CONSTANT'
+#: Example constant
+MY_FLAG = 1
diff --git a/drivers/example/python/ev.py b/drivers/example/python/ev.py
new file mode 100644
index 0000000..e29f903
--- /dev/null
+++ b/drivers/example/python/ev.py
@@ -0,0 +1,104 @@
+###################################################################################
+## MODULE : ev
+## DATE : Mar 18, 2011
+## PROJECT : SPELL
+## DESCRIPTION: Event interface of the driver connection layer
+## --------------------------------------------------------------------------------
+##
+## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+##
+## This file is part of SPELL.
+##
+## This component is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This software is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with SPELL. If not, see .
+##
+###################################################################################
+
+################################################################################
+
+#*******************************************************************************
+# SPELL imports
+#*******************************************************************************
+from spell.lib.exception import DriverException
+from spell.lang.modifiers import *
+from spell.lang.constants import *
+
+#*******************************************************************************
+# Local imports
+#*******************************************************************************
+
+#*******************************************************************************
+# System imports
+#*******************************************************************************
+import sys,os
+
+###############################################################################
+# Module import definition
+
+__all__ = ['EV']
+
+###############################################################################
+# Superclass
+import spell.lib.adapter.ev.EvInterface as superClass
+
+###############################################################################
+# The events interface is in charge of managing GCS events.
+###############################################################################
+class EvInterface(superClass):
+
+ #==========================================================================
+ def __init__(self):
+ """
+ Perform the initialization of Event Handling data here, after the
+ superclass initialization
+ """
+ superClass.__init__(self)
+ # TODO Your initialization stuff here
+
+ #==========================================================================
+ def setup(self, ctxConfig, drvConfig):
+ """
+ Start the internal driver EV mechanisms
+
+ ctxConfig : provides the current context information (S/C name and others)
+ drvConfig : provides the configuration parameters for this driver according
+ to the xml config file.
+ """
+ superClass.setup(self, ctxConfig, drvConfig)
+ # TODO Your startup stuff here
+
+ #==========================================================================
+ def cleanup(self):
+ """
+ Perform the cleanup of the internal driver EV resources.
+ """
+ superClass.cleanup(self)
+ # TODO Release resources and cleanup stuff here
+
+ #==========================================================================
+ def _raiseEvent(self, message, config):
+ """
+ Invoked by the system in order to inject an event into the GCS.
+
+ message: string containing the event message
+ config: dictionary containing the event parameters:
+ - Severity modifier (INFORMATION/WARNING/ERROR/FATAL)
+ - Scope (SCOPE_PROC,SCOPE_SYS,SCOPE_CFG)
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the event injection
+
+################################################################################
+# Interface instance
+EV = EvInterface()
diff --git a/drivers/example/python/gcstime.py b/drivers/example/python/gcstime.py
new file mode 100644
index 0000000..a0d8f0c
--- /dev/null
+++ b/drivers/example/python/gcstime.py
@@ -0,0 +1,98 @@
+###################################################################################
+## MODULE : gcstime
+## DATE : Mar 18, 2011
+## PROJECT : SPELL
+## DESCRIPTION: Time service interface of the driver connection layer
+## --------------------------------------------------------------------------------
+##
+## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+##
+## This file is part of SPELL.
+##
+## This component is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This software is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with SPELL. If not, see .
+##
+###################################################################################
+
+#*******************************************************************************
+# SPELL imports
+#*******************************************************************************
+from spell.lib.exception import DriverException
+
+#*******************************************************************************
+# Local imports
+#*******************************************************************************
+
+#*******************************************************************************
+# System imports
+#*******************************************************************************
+import datetime
+
+###############################################################################
+# Module import definition
+
+__all__ = ['TIME']
+
+###############################################################################
+# Superclass
+import spell.lib.adapter.gcstime.TimeInterface as superClass
+
+###############################################################################
+# The time interface is in charge of managing GCS time.
+###############################################################################
+class TimeInterface(superClass):
+
+ #==========================================================================
+ def __init__(self):
+ """
+ Perform the initialization of time handling data here, after the
+ superclass initialization
+ """
+ superClass.__init__(self)
+ # TODO Your initialization stuff here
+
+ #==========================================================================
+ def setup(self, ctxConfig, drvConfig):
+ """
+ Start the internal driver TIME mechanisms
+
+ ctxConfig : provides the current context information (S/C name and others)
+ drvConfig : provides the configuration parameters for this driver according
+ to the xml config file.
+ """
+ superClass.setup(self, ctxConfig, drvConfig)
+ # TODO Your startup stuff here
+
+ #==========================================================================
+ def cleanup(self):
+ """
+ Perform the cleanup of the internal driver TIME resources.
+ """
+ superClass.cleanup(self)
+ # TODO Release resources and cleanup stuff here
+
+ #==========================================================================
+ def _getUTC(self, config = {} ):
+ """
+ Obtain the current UTC time according to the GCS time. If the present
+ example is not change, the interface provices the current system local
+ time.
+
+ config: SPELL configuration dictionary.
+ """
+ # Default implementation: get system local time
+ return datetime.datetime.utcnow()
+
+################################################################################
+# Interface handle
+TIME = TimeInterface()
diff --git a/drivers/example/python/modifiers.py b/drivers/example/python/modifiers.py
new file mode 100644
index 0000000..5fc5fc6
--- /dev/null
+++ b/drivers/example/python/modifiers.py
@@ -0,0 +1,29 @@
+###################################################################################
+## MODULE : modifiers
+## DATE : Mar 18, 2011
+## PROJECT : SPELL
+## DESCRIPTION: Driver-specific modifiers
+## --------------------------------------------------------------------------------
+##
+## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+##
+## This file is part of SPELL.
+##
+## This component is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This software is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with SPELL. If not, see .
+##
+###################################################################################
+
+#: Example modifier
+ExampleModifier = 'ExampleModifier'
+# MANDATORY: name and value strings shall match
diff --git a/drivers/example/python/resources.py b/drivers/example/python/resources.py
new file mode 100644
index 0000000..d3303e3
--- /dev/null
+++ b/drivers/example/python/resources.py
@@ -0,0 +1,183 @@
+###################################################################################
+## MODULE : resources
+## DATE : Mar 18, 2011
+## PROJECT : SPELL
+## DESCRIPTION: Resource management interface of the driver connection layer
+## --------------------------------------------------------------------------------
+##
+## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+##
+## This file is part of SPELL.
+##
+## This component is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This software is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with SPELL. If not, see .
+##
+###################################################################################
+
+#*******************************************************************************
+# SPELL imports
+#*******************************************************************************
+from spell.lib.exception import DriverException
+from spell.lang.constants import *
+from spell.lang.modifiers import *
+
+#*******************************************************************************
+# Local imports
+#*******************************************************************************
+
+#*******************************************************************************
+# System imports
+#*******************************************************************************
+
+###############################################################################
+# Module import definition
+
+__all__ = ['RSC']
+
+###############################################################################
+# Superclass
+import spell.lib.adapter.resources.ResourceInterface as superClass
+
+###############################################################################
+# The resource management driver interface. This class is in charge of
+# managing the underlying GCS resources like configuration parameters.
+###############################################################################
+class ResourceInterface(superClass):
+
+ #==========================================================================
+ def __init__(self):
+ """
+ Perform the initialization of resource handling data here, after the
+ superclass initialization
+ """
+ superClass.__init__(self)
+ # TODO Your initialization stuff here
+
+ #==========================================================================
+ def setup(self, ctxConfig, drvConfig):
+ """
+ Start the internal driver resource mgmt mechanisms
+
+ ctxConfig : provides the current context information (S/C name and others)
+ drvConfig : provides the configuration parameters for this driver according
+ to the xml config file.
+ """
+ superClass.setup(self, ctxConfig, drvConfig)
+ # TODO Your startup stuff here
+
+ #==========================================================================
+ def cleanup(self):
+ """
+ Perform the cleanup of the internal driver mechanisms.
+ """
+ superClass.cleanup(self)
+ # TODO Release resources and cleanup stuff here
+
+ #==========================================================================
+ def _setResource(self, name, value, isLocal, config = {} ):
+ """
+ Assign the value of one resource or configuration parameter in the GCS
+
+ name: resource identifier
+ value: resource value
+ isLocal: decide whether to set local or global instance
+ config: configuration modifiers
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the resource assignment
+
+ #==========================================================================
+ def _getResource(self, name, isLocal, config = {} ):
+ """
+ Acquire the value of one resource or configuration parameter in the GCS
+
+ name: resource identifier
+ isLocal: decide whether to get local or global instance
+ config: configuration modifiers
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the resource acquisition. Return the resource value:
+ # return theValue
+
+ #==========================================================================
+ def _getResources(self, isLocal, config = {} ):
+ """
+ Acquire the name-value map of all resources or configuration parameters
+ in the GCS
+
+ isLocal: decide whether to get local or global instances
+ config: configuration modifiers
+ """
+ raise DriverException("Service not available in this driver")
+
+ #==========================================================================
+ def _getResourceStatus(self, name, config = {} ):
+ """
+ Acquire the current status of one resource or configuration parameter
+ in the GCS
+
+ name: resource identifier
+ config: configuration modifiers
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the resource acquisition.
+ # return theStatus
+
+ #==========================================================================
+ def _isResourceOK(self, name, config = {} ):
+ """
+ Check if the current value of one resource or configuration parameter
+ in the GCS is correct or incorrect
+
+ name: resource identifier
+ config: configuration modifiers
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the resource acquisition.
+ # return True/False
+
+ #==========================================================================
+ def _setLink(self, name, enable, config = {}):
+ """
+ Enable or disable a GCS link (TM, TC or others)
+
+ name: link identifier
+ enable: True/False, indicates if the link needs to be enabled or disabled
+ config: configuration modifiers
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the resource acquisition.
+ # return True/False depending on success
+
+ #==========================================================================
+ def _checkLink(self, name):
+ """
+ Check if a GCS link (TM, TC or others) is enabled or disabled
+
+ name: link identifier
+ config: configuration modifiers
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the resource acquisition.
+ # return True/False if the link is enabled/disabled
+
+
+################################################################################
+# Interface handle
+RSC = ResourceInterface()
diff --git a/drivers/example/python/task.py b/drivers/example/python/task.py
new file mode 100644
index 0000000..9c12219
--- /dev/null
+++ b/drivers/example/python/task.py
@@ -0,0 +1,173 @@
+###################################################################################
+## MODULE : task
+## DATE : Mar 18, 2011
+## PROJECT : SPELL
+## DESCRIPTION: Task management interface of the driver connection layer
+## --------------------------------------------------------------------------------
+##
+## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+##
+## This file is part of SPELL.
+##
+## This component is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This software is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with SPELL. If not, see .
+##
+###################################################################################
+
+#*******************************************************************************
+# SPELL imports
+#*******************************************************************************
+from spell.lib.exception import DriverException
+from spell.lang.constants import *
+from spell.lang.modifiers import *
+
+#*******************************************************************************
+# Local imports
+#*******************************************************************************
+
+#*******************************************************************************
+# System imports
+#*******************************************************************************
+
+###############################################################################
+# Module import definition
+
+__all__ = ['TASK']
+
+###############################################################################
+# Superclass
+import spell.lib.adapter.task.TaskInterface as superClass
+
+###############################################################################
+# Task management library interface. This class is in charge of
+# managing the underlying system applications.
+###############################################################################
+class TaskInterface(superClass):
+
+ #==========================================================================
+ def __init__(self):
+ """
+ Perform the initialization of data here, after the
+ superclass initialization
+ """
+ superClass.__init__(self)
+ # TODO Your initialization stuff here
+
+ #==========================================================================
+ def setup(self, ctxConfig, drvConfig):
+ """
+ Start the internal driver TASK mechanisms
+
+ ctxConfig : provides the current context information (S/C name and others)
+ drvConfig : provides the configuration parameters for this driver according
+ to the xml config file.
+ """
+ superClass.setup(self, ctxConfig, drvConfig)
+ # TODO Your startup stuff here
+
+ #==========================================================================
+ def cleanup(self):
+ """
+ Perform the cleanup of the internal driver TASK resources.
+ """
+ superClass.cleanup(self)
+ # TODO Release resources and cleanup stuff here
+
+ #==========================================================================
+ def _startTask(self, name, config = {} ):
+ """
+ Invoked by the system in order to start a GCS task.
+
+ name: string containing the task name
+ config: configuration dictionary with modifiers.
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the task start. Return True/False.
+
+ #==========================================================================
+ def _stopTask(self, name, config = {} ):
+ """
+ Invoked by the system in order to stop a GCS task.
+
+ name: string containing the task name
+ config: configuration dictionary with modifiers.
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the task stop. Return True/False.
+
+ #==========================================================================
+ def _checkTask(self, name, config = {} ):
+ """
+ Invoked by the system in order to check the status of a GCS task.
+
+ name: string containing the task name
+ config: configuration dictionary with modifiers.
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the task start. Return the status code.
+
+ #==========================================================================
+ def _openDisplay(self, displayName, config = {} ):
+ """
+ Invoked by the system in order to open a telemetry display on the GCS
+
+ displayName: name or identifier of the display
+ config: configuration dictionary with modifiers.
+
+ Relevant modifiers are:
+
+ Host: the machine name where the display should be open.
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the operation. Return True on success.
+
+ #==========================================================================
+ def _printDisplay(self, displayName, config = {} ):
+ """
+ Invoked by the system in order to print a telemetry display from the GCS
+
+ displayName: name or identifier of the display
+ config: configuration dictionary with modifiers.
+
+ Relevant modifiers are:
+
+ Printer: the printer name
+ Format: PS (postcript) or VECTOR (ASCII text, for alphanumeric displays only)
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the operation. Return True on success.
+
+ #==========================================================================
+ def _closeDisplay(self, displayName, config = {} ):
+ """
+ Invoked by the system in order to close a telemetry display on the GCS
+
+ displayName: name or identifier of the display
+ config: configuration dictionary with modifiers.
+
+ Relevant modifiers are:
+
+ Host: the machine name where the display should be closed.
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the operation. Return True on success.
+
+################################################################################
+# Interface handle
+TASK = TaskInterface()
diff --git a/drivers/example/python/tc.py b/drivers/example/python/tc.py
new file mode 100644
index 0000000..d452d2b
--- /dev/null
+++ b/drivers/example/python/tc.py
@@ -0,0 +1,138 @@
+###################################################################################
+## MODULE : tc
+## DATE : Mar 18, 2011
+## PROJECT : SPELL
+## DESCRIPTION: Telecommand interface of the driver connection layer
+## --------------------------------------------------------------------------------
+##
+## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+##
+## This file is part of SPELL.
+##
+## This component is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This software is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with SPELL. If not, see .
+##
+###################################################################################
+
+#*******************************************************************************
+# SPELL imports
+#*******************************************************************************
+from spell.lib.exception import DriverException
+from spell.lang.constants import *
+from spell.lang.modifiers import *
+
+#*******************************************************************************
+# Local imports
+#*******************************************************************************
+
+#*******************************************************************************
+# System imports
+#*******************************************************************************
+
+###############################################################################
+# Module import definition
+
+__all__ = ['TC']
+
+###############################################################################
+# Superclass
+import spell.lib.adapter.tc.TcInterface as superClass
+
+###############################################################################
+# Telecommand injection interface.
+###############################################################################
+class TcInterface(superClass):
+
+ #==========================================================================
+ def __init__(self):
+ """
+ Perform the initialization of data here, after the
+ superclass initialization
+ """
+ superClass.__init__(self)
+ # TODO Your initialization stuff here
+
+ #==========================================================================
+ def setup(self, ctxConfig, drvConfig):
+ """
+ Start the internal driver TC mechanisms
+
+ ctxConfig : provides the current context information (S/C name and others)
+ drvConfig : provides the configuration parameters for this driver according
+ to the xml config file.
+ """
+ superClass.setup(self, ctxConfig, drvConfig)
+ # TODO Your startup stuff here
+
+ #==========================================================================
+ def cleanup(self):
+ """
+ Perform the cleanup of the internal driver TC resources.
+ """
+ superClass.cleanup(self)
+ # TODO Release resources and cleanup stuff here
+
+ #==========================================================================
+ def _createTcItem(self, mnenonic, description = "" ):
+ """
+ Instantiate a telecommand (usually taking the information from GCS)
+
+ The item shall be derived from TcItemClass class.
+
+ If not overriden, the adapter class provides a generic TC item structure.
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the item creation.
+ # return theItem
+
+ #==========================================================================
+ def _sendCommand(self, tcItem, config = {} ):
+ """
+ Inject a TC item into the GCS.
+
+ tcItem : TcItemClass instance with the command information.
+ config : configuration dictionary
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the command injection. Return True/False
+
+ #==========================================================================
+ def _sendList(self, tcItemList, config = {} ):
+ """
+ Inject a group of TC items into the GCS.
+
+ tcItemList : list of TcItemClass instance with the command information.
+ config : configuration dictionary
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the command list injection. Return True/False
+
+ #==========================================================================
+ def _sendBlock(self, tcItemList, config = {} ):
+ """
+ Inject a block of TC items into the GCS. Blocked items are injected
+ and transmitted as a single TC frame.
+
+ tcItemList : list of TcItemClass instance with the command information.
+ config : configuration dictionary
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the block injection. Return True/False
+
+################################################################################
+# Interface handle
+TC = TcInterface()
diff --git a/drivers/example/python/tm.py b/drivers/example/python/tm.py
new file mode 100644
index 0000000..5e6cd83
--- /dev/null
+++ b/drivers/example/python/tm.py
@@ -0,0 +1,269 @@
+###################################################################################
+## MODULE : tm
+## DATE : Mar 18, 2011
+## PROJECT : SPELL
+## DESCRIPTION: Telemetry interface of the driver connection layer
+## --------------------------------------------------------------------------------
+##
+## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+##
+## This file is part of SPELL.
+##
+## This component is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This software is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with SPELL. If not, see .
+##
+###################################################################################
+
+#*******************************************************************************
+# SPELL imports
+#*******************************************************************************
+from spell.lib.exception import DriverException
+from spell.lang.constants import *
+from spell.lang.modifiers import *
+
+#*******************************************************************************
+# Local imports
+#*******************************************************************************
+
+#*******************************************************************************
+# System imports
+#*******************************************************************************
+import sys,os
+
+###############################################################################
+# Module import definition
+
+__all__ = ['TM']
+
+###############################################################################
+# Superclass
+import spell.lib.adapter.tm.TmInterface as superClass
+
+###############################################################################
+###############################################################################
+class TmInterface( superClass ):
+
+ #==========================================================================
+ def __init__(self):
+ """
+ Perform the initialization of data here, after the
+ superclass initialization
+ """
+ superClass.__init__(self)
+ # TODO Your initialization stuff here
+
+ #==========================================================================
+ def setup(self, ctxConfig, drvConfig):
+ """
+ Start the internal driver TM mechanisms
+
+ ctxConfig : provides the current context information (S/C name and others)
+ drvConfig : provides the configuration parameters for this driver according
+ to the xml config file.
+ """
+ superClass.setup(self, ctxConfig, drvConfig)
+ # TODO Your startup stuff here
+
+ #==========================================================================
+ def cleanup(self):
+ """
+ Perform the cleanup of the internal driver TM resources.
+ """
+ superClass.cleanup(self)
+ # TODO Release resources and cleanup stuff here
+
+ #===========================================================================
+ def _createTmItem(self, mnemonic, description = ""):
+ """
+ Instantiate a telemetry parameter (usually taking the information from GCS)
+
+ The item shall be derived from TmItemClass class.
+
+ If not overriden, the adapter class provides a generic TM item structure.
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the item creation.
+ # return theItem
+
+ #==========================================================================
+ def _injectItem(self, tmItem, value, config = {} ):
+ """
+ Inject a ground value for a TM parameter.
+
+ tmItem : instance of TmItemClass with the parameter information
+ value : contains the required value
+ config : configuration dictionary with modifiers.
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the item injection.
+ # return True/False
+
+ #==========================================================================
+ def _refreshItem(self, tmItem, config = {} ):
+ """
+ Acquire the value for a TM parameter.
+
+ tmItem : instance of TmItemClass with the parameter information
+ config : configuration dictionary with modifiers.
+
+ Relevant modifiers are
+
+ - Wait=True/False: when True, the system shall block the caller until
+ a new sample of the required parameter arrives to the GCS. If False,
+ the last recorded value of the parameter shall be returned immediately.
+
+ - ValueFormat=RAW/ENG: if RAW is given, the raw or uncalibrated value
+ of the parameter shall be given. If ENG is used, the engineering or
+ calibrated value shall be returned.
+
+ - Timeout=(TIME): maximum amount of time to wait for new samples,
+ before the parameter is declared as impossible to acquire. It only
+ makes sense when Wait=True.
+
+ Returned value: a list with the value and True/False indicating the validity
+ of the parameter
+ """
+ raise DriverException("Service not available in this driver")
+ # return [ theValue, theValidity ]
+
+ #===========================================================================
+ def _setLimit(self, param, limit, value, config ):
+ """
+ Modify an Out Of Limits definition for a given telemetry parameter
+
+ param: the telemetry parameter name
+ limit: the limit to be modified
+ value: the limit value
+ config: configuration dictionary with modifiers
+
+ Relevant modifiers are:
+
+ - Select=ACTIVE/ALL/: indicates which definitions should be affected
+ (all, only the active ones, or the one indicated by
+ the string)
+
+ The limit to be modified may be one of the following:
+
+ LoRed,LoYel,HiRed,HiYel: indicate the hard and soft limit values
+
+ Nominal,Earning,Error,Ignore: the values are lists containing the values
+ assigned to each category, e.g. Nominal:['ValueA','ValueB']
+
+ Delta: set a step or spike limit
+ """
+ raise DriverException("Service not available in this driver")
+ # return True/False
+
+ #===========================================================================
+ def _getLimit(self, param, limit, config ):
+ """
+ Obtain an Out Of Limits definition for a given telemetry parameter
+
+ param: the telemetry parameter name
+ limit: the limit to be modified
+ config: configuration dictionary with modifiers
+
+ Relevant modifiers are:
+
+ - Select=ACTIVE/ALL/: indicates which definitions should be considered
+ (all, only the active ones, or the one indicated by
+ the string)
+
+ The limit to be obtained may be one of the following:
+
+ LoRed,LoYel,HiRed,HiYel: indicate the hard and soft limit values
+
+ Nominal,Earning,Error,Ignore: the values are lists containing the values
+ assigned to each category, e.g. Nominal:['ValueA','ValueB']
+
+ Delta: step or spike limit
+ """
+ raise DriverException("Service not available in this driver")
+ # return the limit value or raise exception
+
+ #===========================================================================
+ def _getLimits(self, param, config ):
+ """
+ Obtain an Out Of Limits definition for a given telemetry parameter
+
+ param: the telemetry parameter name
+ config: configuration dictionary with modifiers
+
+ Relevant modifiers are:
+
+ - Select=ACTIVE/ALL/: indicates which definitions should be considered
+ (all, only the active ones, or the one indicated by
+ the string)
+
+ The limit definition to be returned may be one of the following:
+
+ {LoRed,LoYel,HiRed,HiYel}: indicate the hard and soft limit values
+
+ {Nominal,Earning,Error,Ignore}: the values are lists containing the values
+ assigned to each category, e.g. Nominal:['ValueA','ValueB']
+
+ {Delta}: step or spike limit
+ """
+ raise DriverException("Service not available in this driver")
+ # return the limit values or raise exception
+
+ #===========================================================================
+ def _setLimits(self, param, limits, config ):
+ """
+ Modify an Out Of Limits definition for a given telemetry parameter
+
+ param: the telemetry parameter name
+ limits: dictionary containing the limit parameters
+ config: configuration dictionary with modifiers
+
+ Relevant modifiers are:
+
+ - Select=ACTIVE/ALL/: indicates which definitions should be affected
+ (all, only the active ones, or the one indicated by
+ the string)
+
+ Limit parameters dictionary may contain the following:
+
+ LoRed,LoYel,HiRed,HiYel: indicate the hard and soft limit values
+
+ Midpoint,Tolerance: indicate a middle limit point and a tolerance that is
+ used to calculate the upper and lower limits (M+T, M-T)
+ Hard and soft limits are considered equal.
+
+ Nominal,Earning,Error,Ignore: the values are lists containing the values
+ assigned to each category, e.g. Nominal:['ValueA','ValueB']
+
+ Delta: set a step or spike limit
+ """
+ raise DriverException("Service not available in this driver")
+ # return True/False
+
+ #===========================================================================
+ def _loadLimits(self, param, limits, config ):
+ """
+ Load a set of limits definitions for a given parameter, from a given file.
+
+ param: telemetry parameter name
+ limits: file with limit definitions
+ config: configuration parameters
+
+ TBD
+ """
+ raise DriverException("Service not available in this driver")
+ # return True/False
+
+################################################################################
+# Interface handle
+TM = TmInterface()
diff --git a/drivers/example/python/usr.py b/drivers/example/python/usr.py
new file mode 100644
index 0000000..a5e3b23
--- /dev/null
+++ b/drivers/example/python/usr.py
@@ -0,0 +1,130 @@
+###################################################################################
+## MODULE : usr
+## DATE : Mar 18, 2011
+## PROJECT : SPELL
+## DESCRIPTION: User management interface of the driver connection layer
+## --------------------------------------------------------------------------------
+##
+## Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+##
+## This file is part of SPELL.
+##
+## This component is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This software is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with SPELL. If not, see .
+##
+###################################################################################
+
+#*******************************************************************************
+# SPELL imports
+#*******************************************************************************
+from spell.lib.exception import DriverException
+from spell.lang.constants import *
+from spell.lang.modifiers import *
+
+#*******************************************************************************
+# Local imports
+#*******************************************************************************
+
+#*******************************************************************************
+# System imports
+#*******************************************************************************
+
+###############################################################################
+# Module import definition
+
+__all__ = ['USER']
+
+###############################################################################
+# Superclass
+import spell.lib.adapter.usr.UserInterface as superClass
+
+###############################################################################
+# User management interface.
+###############################################################################
+class UserInterface(superClass):
+
+ #==========================================================================
+ def __init__(self):
+ """
+ Perform the initialization of data here, after the
+ superclass initialization
+ """
+ superClass.__init__(self)
+ # TODO Your initialization stuff here
+
+ #==========================================================================
+ def setup(self, ctxConfig, drvConfig):
+ """
+ Start the internal driver user mechanisms
+
+ ctxConfig : provides the current context information (S/C name and others)
+ drvConfig : provides the configuration parameters for this driver according
+ to the xml config file.
+ """
+ superClass.setup(self, ctxConfig, drvConfig)
+ # TODO Your startup stuff here
+
+ #==========================================================================
+ def cleanup(self):
+ """
+ Perform the cleanup of the internal driver user resources.
+ """
+ superClass.cleanup(self)
+ # TODO Release resources and cleanup stuff here
+
+ #==========================================================================
+ def _login(self, username, password, config = {} ):
+ """
+ Login the given user in the GCS system.
+
+ username: user name
+ password: the user password
+ config: configuration dictionary with modifiers.
+
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the user login
+ # return True/False
+
+ #==========================================================================
+ def _logout(self, username, config = {}):
+ """
+ Logout the given user from the GCS system.
+
+ username: user name
+ config: configuration dictionary with modifiers.
+
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the user logout
+ # return True/False
+
+ #==========================================================================
+ def _isLoggedIn(self, username, config = {}):
+ """
+ Check if the given user is logged in the GCS system.
+
+ username: user name
+ config: configuration dictionary with modifiers.
+
+ """
+ raise DriverException("Service not available in this driver")
+ # TODO if the service is supported remove the exception raise and
+ # implement the user login check
+ # return True/False
+
+###############################################################################
+# Interface instance
+USER = UserInterface()
diff --git a/drivers/service/__init__.py b/drivers/service/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/drivers/service/cif_client.py b/drivers/service/cif_client.py
new file mode 100644
index 0000000..3a25d59
--- /dev/null
+++ b/drivers/service/cif_client.py
@@ -0,0 +1,47 @@
+
+from spell.lib.registry import REGISTRY
+from spell.utils.log import LOG
+
+debugOn = False
+def debug(msg):
+ if debugOn: print(msg)
+
+# CIF interface
+class CIF_Client():
+
+ def __init__(self):
+ self._ready = False
+
+ def _setup(self, channel=None, options=None):
+ self._ready = True
+ LOG.setRedirectMethod(self.remoteLog)
+
+ # Change CIF verbosity
+ def setVerbosity(self, *arg):
+ debug('CIF setVerbosity: %s' % repr(arg))
+
+ # Reset CIF verbosity
+ def resetVerbosity(self, *arg):
+ debug('CIF resetVerbosity: %s' % repr(arg))
+
+ # Write a message
+ def write(self, *arg):
+ debug('CIF write: %s' % repr(arg))
+
+ # Send a notification
+ def notify(self, notifyType = None, name = None, value = None,
+ status = None, reason = None, time = None, stack = None):
+ debug('CIF Notify: %s %s=%s (%s) %s' \
+ % (notifyType, name, value, status, reason))
+
+ # Send a prompt
+ def prompt(self, *arg):
+ debug('CIF prompt: %s' % repr(arg))
+
+ def remoteLog(self, message, severity, level):
+ # return False: To prevent the LoggerClass from handling the logging itself (prevent double output in log file and console log)
+ # return True: Append log entry to configured log file and/or console output as configured
+ return True
+
+# init
+REGISTRY['CIF'] = CIF_Client()
diff --git a/drivers/service/driverserver.py b/drivers/service/driverserver.py
new file mode 100644
index 0000000..fb57dd1
--- /dev/null
+++ b/drivers/service/driverserver.py
@@ -0,0 +1,130 @@
+
+from spell.lib.registry import REGISTRY
+from spell.stubs.SPELLExecutor_pb2_grpc import SPELLExecutorStub
+from spell.stubs.SPELLDriver_pb2 import Interfaces
+import spell.stubs.SPELLDriver_pb2 as SPELLDriver_pb2
+import spell.stubs.SPELLDriver_pb2_grpc as SPELLDriver_pb2_grpc
+
+from info_service import DriverService
+from tm_service import SPELLDriverTMInterfaceServicer
+from tc_service import SPELLDriverTCInterfaceServicer
+from ev_service import SPELLDriverEVInterfaceServicer
+from rsc_service import SPELLDriverRSCInterfaceServicer
+from time_service import SPELLDriverTIMEInterfaceServicer
+from task_service import SPELLDriverTASKInterfaceServicer
+from user_service import SPELLDriverUSERInterfaceServicer
+from rng_service import SPELLDriverRNGInterfaceServicer
+from mem_service import SPELLDriverMEMInterfaceServicer
+try:
+ from pcs_service import SPELLDriverPCSInterfaceServicer
+except:
+ pass
+
+from spell.utils.grpc_utils import GRPCThreadPool
+from spell.utils.log import LOG
+
+from concurrent import futures
+from contextlib import closing
+import grpc
+from grpc import RpcError
+import socket
+import time
+import signal
+
+KNOWN_INTERFACES = {
+ 'TM' : lambda server: (Interfaces.TM , SPELLDriverTMInterfaceServicer(server)), # @UndefinedVariable
+ 'TC' : lambda server: (Interfaces.TC , SPELLDriverTCInterfaceServicer(server)), # @UndefinedVariable
+ 'EV' : lambda server: (Interfaces.EV , SPELLDriverEVInterfaceServicer(server)), # @UndefinedVariable
+ 'RSC' : lambda server: (Interfaces.RSC , SPELLDriverRSCInterfaceServicer(server)), # @UndefinedVariable
+ 'TIME' : lambda server: (Interfaces.TIME , SPELLDriverTIMEInterfaceServicer(server)), # @UndefinedVariable
+ 'TASK' : lambda server: (Interfaces.TASK , SPELLDriverTASKInterfaceServicer(server)), # @UndefinedVariable
+ 'USER' : lambda server: (Interfaces.USER , SPELLDriverUSERInterfaceServicer(server)), # @UndefinedVariable
+# 'CONFIG': lambda server: (Interfaces.CONFIG , SPELLDriverCONFIGInterfaceServicer(server)), # @UndefinedVariable
+ 'RNG' : lambda server: (Interfaces.RNG , SPELLDriverRNGInterfaceServicer(server)), # @UndefinedVariable
+ 'MEM' : lambda server: (Interfaces.MEM , SPELLDriverMEMInterfaceServicer(server)), # @UndefinedVariable
+ 'PCS' : lambda server: (Interfaces.PCS , SPELLDriverPCSInterfaceServicer(server)) # @UndefinedVariable
+ }
+
+# Global for signal handling
+server = None
+
+def signal_handler(signal, frame):
+ global server
+ log('signal received: %s' % str(signal))
+ if server != None:
+ server.stop(0)
+ server = None
+ REGISTRY['EXEC']._close()
+
+def log(msg):
+ LOG('[driverserver]: ' + msg)
+
+def find_free_port():
+ with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
+ s.bind(('', 0))
+ return s.getsockname()[1]
+
+def serve(executorHost = None, executorPort = None):
+ global server
+ server = grpc.server(GRPCThreadPool('DRIVER', max_workers=50))
+ port = find_free_port()
+ service = DriverService(port)
+ SPELLDriver_pb2_grpc.add_SPELLDriverInterfaceServicer_to_server(service, server)
+ endpoint = '[::]:' + str(port)
+ port = server.add_insecure_port(endpoint)
+ service._setPort(port)
+
+ # install signal handler
+ signal.signal(signal.SIGINT, signal_handler)
+ signal.signal(signal.SIGTERM, signal_handler)
+
+ log('starting gRPC server at ' + endpoint)
+ server.start()
+
+ if executorHost and executorPort:
+ log('connecting to SPELL Executor')
+
+ driverName = REGISTRY['CTX'].getDriver()
+ driverLogin = SPELLDriver_pb2.DriverInfo(driverName = driverName,
+ host =socket.getfqdn(),
+ port = port)
+
+ driverInterfaces = REGISTRY['CONFIG'].getDriverConfig().getInterfaces()
+ log('registering the following interfaces for driver %s:' % driverName)
+ log(driverInterfaces)
+ for interface in driverInterfaces.split(','):
+ interface = interface.strip()
+ if interface in list(KNOWN_INTERFACES.keys()):
+ try:
+ log('creating driver interface %s' % interface)
+ ifcId, ifcService = KNOWN_INTERFACES[interface](server)
+ if ifcService:
+ driverLogin.interfaces.append(ifcId)
+ log('created driver interface %s for id %s ' \
+ % (interface, ifcId))
+ except:
+ log('could not create interface service for %s!' % interface)
+ import traceback
+ traceback.print_exc()
+ del traceback
+
+ channel = grpc.insecure_channel('%s:%d' % (executorHost, executorPort))
+ stub = SPELLExecutorStub(channel)
+ try:
+ response = stub.DriverLogin(driverLogin)
+ REGISTRY['CIF']._setup(channel, response)
+ REGISTRY['EXEC']._setup(channel, response)
+ log('login to SPELL Executor succeeded')
+ except RpcError as e:
+ log('login to SPELL Executor failed with error code %s' % e.code())
+ log(e)
+ server.stop(0)
+ REGISTRY['EXEC']._close()
+ return
+ else:
+ REGISTRY['CIF']._setup()
+ REGISTRY['EXEC']._setup()
+
+ log('started to serve requests, hit ctrl-c to stop')
+ while server != None:
+ time.sleep(1)
diff --git a/drivers/service/ev_service.py b/drivers/service/ev_service.py
new file mode 100644
index 0000000..bbcea53
--- /dev/null
+++ b/drivers/service/ev_service.py
@@ -0,0 +1,37 @@
+
+from spell.lib.registry import REGISTRY
+from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_EVServicer,\
+ add_SPELLDriverInterface_EVServicer_to_server
+from spell.utils.grpc_utils import UnpackValue, LogFunctionInput
+
+from google.protobuf.empty_pb2 import Empty
+
+class SPELLDriverEVInterfaceServicer(SPELLDriverInterface_EVServicer):
+
+ def __init__(self, server):
+ add_SPELLDriverInterface_EVServicer_to_server(self, server)
+
+ def Setup(self, request, context):
+ from spell.lib.drivermgr import DriverManager
+ mgr = DriverManager.instance()
+ REGISTRY['EV'].setup(mgr.contextConfig,mgr.driverConfig)
+ del DriverManager
+ return request
+
+ def Cleanup(self, request, context):
+ REGISTRY['EV'].cleanup()
+ return Empty()
+
+ def Ping(self, request, context):
+ return Empty()
+
+ def Close(self, request, context):
+ return Empty()
+
+ def RaiseEvent(self, request, context):
+ msg = str(request.message)
+ config = UnpackValue(request.config)
+
+ REGISTRY['EV']._raiseEvent(msg, config)
+
+ return Empty()
diff --git a/drivers/service/exec_client.py b/drivers/service/exec_client.py
new file mode 100644
index 0000000..4486f95
--- /dev/null
+++ b/drivers/service/exec_client.py
@@ -0,0 +1,130 @@
+
+from spell.lib.registry import REGISTRY
+from spell.stubs.SPELLExecutor_pb2_grpc import SPELLExecutorStub
+from spell.utils.timing import RepeatingThread
+
+from google.protobuf.empty_pb2 import Empty
+from grpc import RpcError
+import os
+from spell.config.reader import Config
+
+debugOn = False
+def debug(msg):
+ if debugOn: print(msg)
+
+# EXEC interface
+class EXEC_Client(SPELLExecutorStub):
+
+ def __init__(self):
+ self._ready = False
+ self._ping = None
+ self._retryCount = 0
+ self._spellAccess = False
+
+ def _setup(self, channel=None, options=None):
+ self._ready = True
+ if not channel:
+ return
+ SPELLExecutorStub.__init__(self, channel)
+ self.createPingThread()
+
+ def _close(self):
+ if self._ping is None:
+ return
+ self._ping.cancel()
+ self._ping = None
+
+ def createPingThread(self):
+ self._ping = RepeatingThread(REGISTRY['CONFIG'].getDriverConfig().getGRPCPingTime(),
+ self.checkConnectionAlive)
+ self._ping.start()
+
+ def checkConnectionAlive(self):
+ try:
+ self.Ping(Empty(),
+ timeout = REGISTRY['CONFIG'].getDriverConfig().getGRPCTimeout())
+ self._retryCount = 0
+ debug('[DRIVER] SPELL Executor is alive!')
+ except RpcError as e:
+ import traceback
+ excMsg = traceback.format_exception_only(RpcError, e)
+ self._retryCount += 1
+ if self._retryCount <= REGISTRY['CONFIG'].getDriverConfig().getGRPCRetry():
+ debug('[DRIVER] SPELL Executor does not react anymore! Retry %s/%s' \
+ % (self._retryCount, REGISTRY['CONFIG'].getDriverConfig().getGRPCRetry()))
+ debug(str(excMsg))
+ else:
+ debug('[DRIVER] SPELL Executor stopped reacting! Exiting SPELL Driver')
+ os._exit(0)
+ del traceback
+
+ # Obtain executor status
+ def getStatus(self, *arg):
+ debug('EXEC: getStatus: %s' % repr(arg))
+
+ # Obtain execution environment
+ def getEnvironment(self, *arg):
+ debug('EXEC: getEnvironment: %s' % repr(arg))
+
+ # Set the language lock
+ def processLock(self, *arg):
+ debug('EXEC: processLock: %s' % repr(arg))
+
+ # Unset the language lock
+ def processUnlock(self, *arg):
+ debug('EXEC: processUnlock: %s' % repr(arg))
+
+ # Start waiting process
+ def startWait(self, *arg):
+ debug('EXEC: startWait: %s' % repr(arg))
+
+ # End waiting process
+ def finishWait(self, *arg):
+ debug('EXEC: finishWait: %s' % repr(arg))
+
+ # Start prompt
+ def startPrompt(self, *arg):
+ debug('EXEC: startPrompt: %s' % repr(arg))
+
+ # End prompt
+ def endPrompt(self, *arg):
+ debug('EXEC: endPrompt: %s' % repr(arg))
+
+ # Wait for event
+ def wait(self, *arg):
+ debug('EXEC: wait: %s' % repr(arg))
+
+ # Open child procedure
+ def openSubProcedure(self, *arg):
+ debug('EXEC: openSubProcedure: %s' % repr(arg))
+
+ # Close child procedure
+ def closeSubProcedure(self, *arg):
+ debug('EXEC: closeSubProcedure: %s' % repr(arg))
+
+ # Kill child procedure
+ def killSubProcedure(self, *arg):
+ debug('EXEC: killSubProcedure: %s' % repr(arg))
+
+ # Get child procedure status
+ def getChildStatus(self, *arg):
+ debug('EXEC: getChildStatus: %s' % repr(arg))
+
+ # Get child procedure error info
+ def getChildError(self, *arg):
+ debug('EXEC: getChildError: %s' % repr(arg))
+
+ # Is subprocedure in error
+ def isChildError(self, *arg):
+ debug('EXEC: isChildError: %s' % repr(arg))
+
+ # Is subprocedure finished
+ def isChildFinished(self, *arg):
+ debug('EXEC: isChildFinished: %s' % repr(arg))
+
+ # Abort execution
+ def abort(self, *arg):
+ debug('EXEC: abort: %s' % repr(arg))
+
+# init
+REGISTRY['EXEC'] = EXEC_Client()
diff --git a/drivers/service/info_service.py b/drivers/service/info_service.py
new file mode 100644
index 0000000..d725c59
--- /dev/null
+++ b/drivers/service/info_service.py
@@ -0,0 +1,35 @@
+
+from spell.lib.registry import REGISTRY
+import spell.stubs.SPELLDriver_pb2 as SPELLDriver_pb2
+import spell.stubs.SPELLDriver_pb2_grpc as SPELLDriver_pb2_grpc
+
+from google.protobuf.empty_pb2 import Empty
+import socket
+from threading import Timer
+
+class DriverService(SPELLDriver_pb2_grpc.SPELLDriverInterfaceServicer):
+
+ def __init__(self, port):
+ self.driverName = REGISTRY['CTX'].getDriver()
+ self.host = socket.getfqdn()
+ self.port = port
+
+ def _setPort(self, port):
+ self.port = port
+
+ def GetDriverInfo(self, request, context):
+ return SPELLDriver_pb2.DriverInfo(driverName = self.driverName,
+ host = self.host, port = self.port)
+
+ def Cleanup(self, request, context):
+ return request
+
+ def Ping(self, request, context):
+ return Empty()
+
+ def Close(self, request, context):
+ # TODO: test
+ def doExit():
+ exit(0)
+ exitTimer = Timer(2,doExit,[]).start()
+ return Empty()
diff --git a/drivers/service/mem_service.py b/drivers/service/mem_service.py
new file mode 100644
index 0000000..6cd15bb
--- /dev/null
+++ b/drivers/service/mem_service.py
@@ -0,0 +1,103 @@
+
+from spell.lib.registry import REGISTRY
+from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_MEMServicer,\
+ add_SPELLDriverInterface_MEMServicer_to_server
+from spell.utils.grpc_utils import UnpackValue, LogFunctionInput, PackValue
+
+from google.protobuf.empty_pb2 import Empty
+from google.protobuf.wrappers_pb2 import BoolValue
+
+class SPELLDriverMEMInterfaceServicer(SPELLDriverInterface_MEMServicer):
+
+ def __init__(self, server):
+ add_SPELLDriverInterface_MEMServicer_to_server(self, server)
+
+ def Setup(self, request, context):
+ from spell.lib.drivermgr import DriverManager
+ mgr = DriverManager.instance()
+ REGISTRY['MEM'].setup(mgr.contextConfig,mgr.driverConfig)
+ del DriverManager
+ return request
+
+ def Cleanup(self, request, context):
+ REGISTRY['MEM'].cleanup()
+ return Empty()
+
+ def Ping(self, request, context):
+ return Empty()
+
+ def Close(self, request, context):
+ return Empty()
+
+ def GenerateReport(self, request, context):
+ image = request.image
+ report_type = request.report_type
+ begin = request.begin
+ end = request.end
+ source = request.source
+ config = UnpackValue(request.config)
+
+ result = REGISTRY['MEM']._generateReport(image, report_type, begin,
+ end, source, config)
+
+ return BoolValue(value = result)
+
+ def CompareImages(self, request, context):
+ image1 = request.image1
+ image2 = request.image2
+ report_type = request.report_type
+ begin = request.begin
+ end = request.end
+ source = request.source
+ config = UnpackValue(request.config)
+
+ result = REGISTRY['MEM']._compareImages(image1, image2, report_type,
+ begin, end, source, config)
+
+ return BoolValue(value = result)
+
+
+ def CreateGoldenImage(self, request, context):
+ scp = request.scp
+ filename = request.filename
+ config = UnpackValue(request.config)
+
+ result = REGISTRY['MEM']._createGoldenImage(self, scp, filename, config)
+
+ return BoolValue(value = result)
+
+
+ def MemoryLookup(self, request, context):
+ name = request.name
+ address = request.address
+ image = request.image
+ report_type = request.report_type
+ source = request.source
+ config = UnpackValue(request.config)
+
+ result = REGISTRY['MEM']._memoryLookup(name, address, image,
+ report_type, source, config)
+
+ return PackValue(result)
+
+
+ def DataObjectLookup(self, request, context):
+ name = request.name
+ ltype = request.type
+ config = UnpackValue(request.config)
+
+ result = REGISTRY['MEM']._dataObjectLookup(name, ltype, config)
+
+ return PackValue(result)
+
+
+ def DataItemLookup(self, request, context):
+ name = request.name
+ ltype = request.type
+ source = request.source
+ valformat = request.valformat
+ config = UnpackValue(request.config)
+
+ result = REGISTRY['MEM']._dataItemLookup(name, ltype, source, valformat, config)
+
+ return PackValue(result)
diff --git a/drivers/service/pcs_service.py b/drivers/service/pcs_service.py
new file mode 100644
index 0000000..7b14e4b
--- /dev/null
+++ b/drivers/service/pcs_service.py
@@ -0,0 +1,166 @@
+
+from spell.lib.registry import REGISTRY
+from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_PCSServicer,\
+ add_SPELLDriverInterface_PCSServicer_to_server
+from spell.stubs.SPELLDriver_pb2 import Names, PtcResult
+from spell.utils.grpc_utils import UnpackValue, LogFunctionInput, PackValue
+
+from google.protobuf.empty_pb2 import Empty
+from google.protobuf.wrappers_pb2 import BoolValue, StringValue
+from spell.lang.functions import PCS_GetStatus
+
+class SPELLDriverPCSInterfaceServicer(SPELLDriverInterface_PCSServicer):
+
+ def __init__(self, server):
+ self._ptcItemRegistry = {}
+ add_SPELLDriverInterface_PCSServicer_to_server(self, server)
+
+ #==========================================================================
+ def Setup(self, request, context):
+ from spell.lib.drivermgr import DriverManager
+ mgr = DriverManager.instance()
+ REGISTRY['PCS'].setup(mgr.contextConfig,mgr.driverConfig)
+ del DriverManager
+ return request
+
+ #==========================================================================
+ def Cleanup(self, request, context):
+ REGISTRY['PCS'].cleanup()
+ return Empty()
+
+ #==========================================================================
+ def Ping(self, request, context):
+ return Empty()
+
+ #==========================================================================
+ def Close(self, request, context):
+ return Empty()
+
+ #==========================================================================
+
+ def CreatePtcItem(self, request, context):
+ ptcId = request.id
+ if not ptcId or ptcId not in list(self._ptcItemRegistry.keys()):
+ ptcItem = REGISTRY['PCS']._createPtcItem(str(request.mnemonic),
+ str(request.description))
+ ptcId = request.mnemonic
+ self._ptcItemRegistry[str(ptcId)] = ptcItem
+ request.id = ptcId
+
+ return request
+
+ #==========================================================================
+ def _findItem(self, request):
+ # RSA: do we need all these str conversions?
+ # strings coming from grpc are all in unicode.
+ # str and unicode have different hashes even if they got the same content.
+ # That's why we have to convert all values to str when using dicts.
+ if str(request.item.id) in self._ptcItemRegistry:
+ ptcItem = self._ptcItemRegistry[str(request.item.id)]
+ else:
+ ptcItem = REGISTRY['PCS']._createPtcItem(str(request.item.mnemonic),
+ str(request.item.description))
+ request.item.id = str(request.item.mnemonic)
+
+ return ptcItem
+
+ #==========================================================================
+ def PCS_GetStatus(self, request, context):
+ answer = REGISTRY['PCS']._PCS_GetStatus(UnpackValue(request))
+
+ return PackValue(answer)
+
+ #==========================================================================
+ def PCS_IsArqEnabled(self, request, context):
+ answer = REGISTRY['PCS']._PCS_IsArqEnabled(UnpackValue(request))
+
+ return answer.value
+
+ #==========================================================================
+ def PCS_IsVerifyModeEnabled(self, request, context):
+ answer = REGISTRY['PCS']._PCS_IsVerifyModeEnabled(UnpackValue(request))
+
+ return answer.value
+
+ #==========================================================================
+ def PCS_ReadyToCommand(self, request, context):
+ answer = REGISTRY['PCS']._PCS_ReadyToCommand(UnpackValue(request))
+
+ return answer.value
+
+ #==========================================================================
+ def PCS_AbortPtc(self, request, context):
+ answer = REGISTRY['PCS']._PCS_AbortPtc(UnpackValue(request))
+
+ return answer.value
+
+ #==========================================================================
+ def _extractPtc(self, request):
+ ptcItem = self._ptcItemRegistry[str(request.command.id)]
+ if request.HasField('config'):
+ config = UnpackValue(request.config)
+ else:
+ config = {}
+
+ args = UnpackValue(request.args)
+ self._addArgsToPTC(ptcItem, args, config)
+
+ return ptcItem
+
+ #==========================================================================
+ def _addArgsToPTC(self, ptcItem, args, config):
+ ptcItem.clear()
+ # RSA: Is this correct?
+ for arg in args:
+ ptcItem[arg[0]] = arg[1:]
+ ptcItem.configure(config)
+
+ #==========================================================================
+ def _createPtcResultAnswer(self,result):
+ answer = PtcResult(code = result['code'],
+ success = result['success'],
+ stage = result['stage'],
+ data = result['data'],
+ error = result['error'])
+
+ return answer
+
+ #==========================================================================
+ def PCS_Control(self, request, context):
+ ptcItem = self._extractPtc(request)
+
+ if request.HasField('config'):
+ config = UnpackValue(request.config)
+ else:
+ config = {}
+
+ result = REGISTRY['PCS']._PCS_Control(ptcItem, config)
+
+ return self._createPtcResultAnswer(result)
+ #==========================================================================
+ def SendPtcCommand(self, request, context):
+ ptcItem = self._extractPtc(request)
+
+ if request.HasField('config'):
+ config = UnpackValue(request.config)
+ else:
+ config = {}
+
+ result = REGISTRY['PCS']._sendPtcCommand(ptcItem, config)
+
+ return self._createPtcResultAnswer(result)
+
+ #==========================================================================
+ def SendPtcList(self, request, context):
+ cmdList = []
+ for cmd in request.commands:
+ cmdList += [self._extractPtc(cmd)]
+
+ if request.HasField('config'):
+ config = UnpackValue(request.config)
+ else:
+ config = {}
+
+ result = REGISTRY['PCS']._sendPtcList(cmdList, config)
+
+ return self._createPtcResultAnswer(result)
diff --git a/drivers/service/rng_service.py b/drivers/service/rng_service.py
new file mode 100644
index 0000000..96f1246
--- /dev/null
+++ b/drivers/service/rng_service.py
@@ -0,0 +1,128 @@
+
+from spell.lib.registry import REGISTRY
+from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_RNGServicer,\
+ add_SPELLDriverInterface_RNGServicer_to_server
+from spell.stubs.SPELLDriver_pb2 import Names
+from spell.utils.grpc_utils import UnpackValue, LogFunctionInput
+
+from google.protobuf.empty_pb2 import Empty
+from google.protobuf.wrappers_pb2 import BoolValue, StringValue
+
+class SPELLDriverRNGInterfaceServicer(SPELLDriverInterface_RNGServicer):
+
+ def __init__(self, server):
+ add_SPELLDriverInterface_RNGServicer_to_server(self, server)
+
+ def Setup(self, request, context):
+ from spell.lib.drivermgr import DriverManager
+ mgr = DriverManager.instance()
+ REGISTRY['RNG'].setup(mgr.contextConfig,mgr.driverConfig)
+ del DriverManager
+ return request
+
+ def Cleanup(self, request, context):
+ REGISTRY['RNG'].cleanup()
+ return Empty()
+
+ def Ping(self, request, context):
+ return Empty()
+
+ def Close(self, request, context):
+ return Empty()
+
+ def EnableRanging(self, request, context):
+ config = UnpackValue(request.config)
+
+ result = REGISTRY['RNG']._enableRanging(config)
+
+ return BoolValue(value = result)
+
+ def DisableRanging(self, request, context):
+ config = UnpackValue(request.config)
+
+ result = REGISTRY['RNG']._disableRanging(config)
+
+ return BoolValue(value = result)
+
+ def AbortRanging(self, request, context):
+ config = UnpackValue(request.config)
+
+ result = REGISTRY['RNG']._abortRanging(config)
+
+ return BoolValue(value = result)
+
+
+ def StartRanging(self, request, context):
+ config = UnpackValue(request.config)
+ bbe = request.bbe
+ antenna = request.antenna
+
+ result = REGISTRY['RNG']._startRanging(bbe, antenna, config)
+
+ return BoolValue(value = result)
+
+
+ def StartCalibration(self, request, context):
+ config = UnpackValue(request.config)
+ bbe = request.bbe
+ antenna = request.antenna
+
+ result = REGISTRY['RNG']._startCalibration(bbe, antenna, config)
+
+ return BoolValue(value = result)
+
+ def GetBasebandConfig(self, request, context):
+ config = UnpackValue(request.config)
+ bbe = request.bbe
+ param = request.param
+
+ result = REGISTRY['RNG']._getBasebandConfig(bbe, param, config)
+
+ request.value = str(result)
+
+ return request
+
+ def SetBasebandConfig(self, request, context):
+ config = UnpackValue(request.config)
+ bbe = request.bbe
+ param = request.param
+ value = request.value
+
+ result = REGISTRY['RNG']._setBasebandConfig(bbe, param, value, config)
+
+ return BoolValue(value = result)
+
+ def GetAntennaNames(self, request, context):
+ config = UnpackValue(request)
+
+ result = REGISTRY['RNG']._getAntennaNames(config)
+
+ return Names(names = result)
+
+ def GetRangingPaths(self, request, context):
+ config = UnpackValue(request)
+
+ result = REGISTRY['RNG']._getRangingPaths(config)
+
+ return Names(names = result)
+
+ def GetBasebandNames(self, request, context):
+ config = UnpackValue(request)
+
+ result = REGISTRY['RNG']._getBasebandNames(config)
+
+ return Names(names = result)
+
+ def GetRangingStatus(self, request, context):
+ config = UnpackValue(request)
+
+ result = REGISTRY['RNG']._getRangingStatus(config)
+
+ return StringValue(value = result)
+
+ def UpdateCortexConf(self, request, context):
+ config = UnpackValue(request)
+
+ result = REGISTRY['RNG']._updateCortexConf(config)
+
+ return BoolValue(value = result)
diff --git a/drivers/service/rsc_service.py b/drivers/service/rsc_service.py
new file mode 100644
index 0000000..4e139c7
--- /dev/null
+++ b/drivers/service/rsc_service.py
@@ -0,0 +1,76 @@
+
+from spell.lib.registry import REGISTRY
+from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_RSCServicer,\
+ add_SPELLDriverInterface_RSCServicer_to_server
+from spell.stubs.SPELLDriver_pb2 import ResourceRequest
+from spell.utils.grpc_utils import UnpackValue, PackValue, unicode2string,\
+ LogFunctionInput
+
+from google.protobuf.empty_pb2 import Empty
+from google.protobuf.wrappers_pb2 import BoolValue
+
+class SPELLDriverRSCInterfaceServicer(SPELLDriverInterface_RSCServicer):
+
+ def __init__(self, server):
+ self._tmItemRegistry = {}
+ add_SPELLDriverInterface_RSCServicer_to_server(self, server)
+
+ def SetLink(self, request, context):
+ REGISTRY['RSC'].setLink(str(request.name), unicode2string(request.status),
+ UnpackValue(request.config))
+ return BoolValue(value = True)
+
+ def CheckLink(self, request, context):
+ result = REGISTRY['RSC'].checkLink(str(request.name))
+
+ return BoolValue(value = result)
+
+ def SetResource(self, request, context):
+ result = REGISTRY['RSC']._setResource(str(request.name),
+ UnpackValue(request.value),
+ UnpackValue(request.config))
+
+ return BoolValue(value = result)
+
+ def GetResource(self, request, context):
+ result = REGISTRY['RSC']._getResource(str(request.name),
+ UnpackValue(request.config))
+
+ return ResourceRequest(value = PackValue(result))
+
+ def GetResources(self, request, context):
+ # FIXME: What about isLocal?
+ result = REGISTRY['RSC']._getResources(UnpackValue(request.config))
+
+ return ResourceRequest(value = PackValue(result))
+
+ def GetResourceStatus(self, request, context):
+ result = REGISTRY['RSC']._getResourceStatus(str(request.name),
+ UnpackValue(request.config))
+
+ return ResourceRequest(value = PackValue(result))
+
+ def IsResourceOK(self, request, context):
+ result = REGISTRY['RSC']._isResourceOK(str(request.name),
+ UnpackValue(request.config))
+
+ return BoolValue(value = result)
+
+ def Setup(self, request, context):
+ from spell.lib.drivermgr import DriverManager
+ mgr = DriverManager.instance()
+ REGISTRY['RSC'].setup(mgr.contextConfig,mgr.driverConfig)
+ del DriverManager
+ return request
+
+ def Cleanup(self, request, context):
+ REGISTRY['RSC'].cleanup()
+
+ return Empty()
+
+ def Ping(self, request, context):
+ return Empty()
+
+ def Close(self, request, context):
+ # TODO
+ return Empty()
diff --git a/drivers/service/task_service.py b/drivers/service/task_service.py
new file mode 100644
index 0000000..6dea479
--- /dev/null
+++ b/drivers/service/task_service.py
@@ -0,0 +1,74 @@
+
+from spell.lib.registry import REGISTRY
+from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_TASKServicer,\
+ add_SPELLDriverInterface_TASKServicer_to_server
+from spell.utils.grpc_utils import UnpackValue, LogFunctionInput
+
+from google.protobuf.empty_pb2 import Empty
+from google.protobuf.wrappers_pb2 import BoolValue
+
+class SPELLDriverTASKInterfaceServicer(SPELLDriverInterface_TASKServicer):
+
+ def __init__(self, server):
+ add_SPELLDriverInterface_TASKServicer_to_server(self, server)
+
+ def Setup(self, request, context):
+ from spell.lib.drivermgr import DriverManager
+ mgr = DriverManager.instance()
+ REGISTRY['TASK'].setup(mgr.contextConfig,mgr.driverConfig)
+ del DriverManager
+ return request
+
+ def Cleanup(self, request, context):
+ REGISTRY['TASK'].cleanup()
+
+ return Empty()
+
+ def Ping(self, request, context):
+ return Empty()
+
+ def Close(self, request, context):
+ return Empty()
+
+ def StartTask(self, request, context):
+ name = request.name
+ args = UnpackValue(request.args)
+ config = UnpackValue(request.config)
+ answer = REGISTRY['TASK']._startTask(name, args, config)
+
+ return BoolValue(value = answer)
+
+ def StopTask(self, request, context):
+ name = request.name
+ config = UnpackValue(request.config)
+ answer = REGISTRY['TASK']._stopTask(name, config)
+
+ return BoolValue(value = answer)
+
+ def CheckTask(self, request, context):
+ name = request.name
+ config = UnpackValue(request.config)
+ answer = REGISTRY['TASK']._checkTask(name, config)
+
+ return BoolValue(value = answer)
+
+ def OpenDisplay(self, request, context):
+ name = request.name
+ config = UnpackValue(request.config)
+ REGISTRY['TASK']._openDisplay(name, config)
+
+ return Empty()
+
+ def CloseDisplay(self, request, context):
+ name = request.name
+ config = UnpackValue(request.config)
+ REGISTRY['TASK']._closeDisplay(name, config)
+
+ return Empty()
+
+ def PrintDisplay(self, request, context):
+ name = request.name
+ config = UnpackValue(request.config)
+ REGISTRY['TASK']._printDisplay(name, config)
+
+ return Empty()
diff --git a/drivers/service/tc_service.py b/drivers/service/tc_service.py
new file mode 100644
index 0000000..2b06272
--- /dev/null
+++ b/drivers/service/tc_service.py
@@ -0,0 +1,102 @@
+
+from spell.lib.registry import REGISTRY
+from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_TCServicer,\
+ add_SPELLDriverInterface_TCServicer_to_server
+from spell.utils.grpc_utils import UnpackValue, LogFunctionInput
+
+from google.protobuf.empty_pb2 import Empty
+from google.protobuf.wrappers_pb2 import BoolValue
+
+class SPELLDriverTCInterfaceServicer(SPELLDriverInterface_TCServicer):
+
+ def __init__(self, server):
+ self._tcItemRegistry = {}
+ add_SPELLDriverInterface_TCServicer_to_server(self, server)
+
+ def CreateTcItem(self, request, context):
+ tcId = request.id
+ if not tcId or tcId not in list(self._tcItemRegistry.keys()):
+ tcItem = REGISTRY['TC']._createTcItem(str(request.mnemonic),
+ str(request.description))
+ tcId = id(tcItem)
+ self._tcItemRegistry[str(tcId)] = tcItem
+ request.id = tcId
+
+ return request
+
+ def _extractCommand(self, request):
+ tcItem = self._tcItemRegistry[str(request.command.id)]
+ if request.HasField('config'):
+ config = UnpackValue(request.config)
+ else:
+ config = {}
+
+ args = UnpackValue(request.args)
+ self._addArgsToTC(tcItem, args, config)
+
+ return tcItem
+
+ def _addArgsToTC(self, tcItem, args, config):
+ tcItem.clear()
+ # RSA: Is this correct?
+ for arg in args:
+ tcItem[arg[0]] = arg[1:]
+ tcItem.configure(config)
+
+ def SendCommand(self, request, context):
+ tcItem = self._extractCommand(request)
+
+ if request.HasField('config'):
+ config = UnpackValue(request.config)
+ else:
+ config = {}
+
+ result = REGISTRY['TC']._sendCommand(tcItem, config)
+
+ return BoolValue(value = result)
+
+ def SendList(self, request, context):
+ cmdList = []
+ for cmd in request.commands:
+ cmdList += [self._extractCommand(cmd)]
+
+ if request.HasField('config'):
+ config = UnpackValue(request.config)
+ else:
+ config = {}
+
+ result = REGISTRY['TC']._sendList(cmdList, config)
+
+ return BoolValue(value = result)
+
+ def SendBlock(self, request, context):
+ cmdList = []
+ for cmd in request.commands:
+ cmdList += [self._extractCommand(cmd)]
+
+ if request.HasField('config'):
+ config = UnpackValue(request.config)
+ else:
+ config = {}
+
+ result = REGISTRY['TC']._sendBlock(cmdList, config)
+
+ return BoolValue(value = result)
+
+ def Setup(self, request, context):
+ from spell.lib.drivermgr import DriverManager
+ mgr = DriverManager.instance()
+ REGISTRY['TC'].setup(mgr.contextConfig,mgr.driverConfig)
+ del DriverManager
+ return request
+
+ def Cleanup(self, request, context):
+ REGISTRY['TC'].cleanup()
+ return Empty()
+
+ def Ping(self, request, context):
+ return Empty()
+
+ def Close(self, request, context):
+ # TODO
+ return Empty()
diff --git a/drivers/service/time_service.py b/drivers/service/time_service.py
new file mode 100644
index 0000000..78648ef
--- /dev/null
+++ b/drivers/service/time_service.py
@@ -0,0 +1,37 @@
+
+from spell.lib.registry import REGISTRY
+from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_TIMEServicer,\
+ add_SPELLDriverInterface_TIMEServicer_to_server
+from spell.stubs.SPELLDriver_pb2 import Time
+from spell.utils.grpc_utils import UnpackValue, LogFunctionInput
+
+from google.protobuf.empty_pb2 import Empty
+
+class SPELLDriverTIMEInterfaceServicer(SPELLDriverInterface_TIMEServicer):
+
+ def __init__(self, server):
+ add_SPELLDriverInterface_TIMEServicer_to_server(self, server)
+
+ def Setup(self, request, context):
+ from spell.lib.drivermgr import DriverManager
+ mgr = DriverManager.instance()
+ REGISTRY['TIME'].setup(mgr.contextConfig,mgr.driverConfig)
+ del DriverManager
+ return request
+
+ def Cleanup(self, request, context):
+ REGISTRY['TIME'].cleanup()
+
+ return Empty()
+
+ def Ping(self, request, context):
+ return Empty()
+
+ def Close(self, request, context):
+ return Empty()
+
+ def GetUTC(self, request, context):
+ config = UnpackValue(request)
+ answer = REGISTRY['TIME']._getUTC(config)
+
+ return Time(timeMsg = str(answer))
diff --git a/drivers/service/tm_service.py b/drivers/service/tm_service.py
new file mode 100644
index 0000000..747ad62
--- /dev/null
+++ b/drivers/service/tm_service.py
@@ -0,0 +1,142 @@
+
+from spell.lib.registry import REGISTRY
+from spell.stubs.SPELLDriver_pb2 import LookupAnswer, LimitSet
+from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_TMServicer,\
+ add_SPELLDriverInterface_TMServicer_to_server
+from spell.utils.grpc_utils import UnpackValue, PackValue, LogFunctionInput
+
+from google.protobuf.empty_pb2 import Empty
+from google.protobuf.wrappers_pb2 import BoolValue
+
+class SPELLDriverTMInterfaceServicer(SPELLDriverInterface_TMServicer):
+
+ def __init__(self, server):
+ self._tmItemRegistry = {}
+ add_SPELLDriverInterface_TMServicer_to_server(self, server)
+
+ def CreateTmItem(self, request, context):
+ tmId = request.id
+ if not tmId or tmId not in list(self._tmItemRegistry.keys()):
+ tmItem = REGISTRY['TM']._createTmItem(str(request.mnemonic),
+ str(request.description))
+ tmId = request.mnemonic
+ self._tmItemRegistry[str(tmId)] = tmItem
+ request.id = tmId
+
+ return request
+
+ def _findItem(self, request):
+ # RSA: do we need all these str conversions?
+ if str(request.item.id) in self._tmItemRegistry:
+ tmItem = self._tmItemRegistry[str(request.item.id)]
+ else:
+ tmItem = REGISTRY['TM']._createTmItem(str(request.item.mnemonic),
+ str(request.item.description))
+ request.item.id = str(request.item.mnemonic)
+
+ return tmItem
+
+ def RefreshItem(self, request, context):
+ tmItem = self._findItem(request)
+ if request.HasField('config'):
+ config = UnpackValue(request.config)
+ else:
+ config = {}
+ _, validity = REGISTRY['TM']._refreshItem(tmItem, config)
+
+ timestamp = str(tmItem.time())
+ request.engValue.CopyFrom(PackValue(tmItem.eng()))
+ request.rawValue.CopyFrom(PackValue(tmItem.raw()))
+
+ if timestamp and tmItem.time() is not None:
+ request.timestamp = timestamp
+
+ request.validity = bool(validity)
+
+ return request
+
+ def DatabaseLookup(self, request, context):
+ answer = REGISTRY['TM']._databaseLookup(str(request.name),
+ str(request.type),
+ str(request.source))
+
+ return LookupAnswer(lookup = PackValue(answer))
+
+ def GetLimits(self, request, context):
+ tmItem = self._findItem(request)
+ if request.HasField('config'):
+ config = UnpackValue(request.config)
+ else:
+ config = {}
+
+ answer = REGISTRY['TM']._getLimits(tmItem,config)
+
+ return LimitSet(limitset = PackValue(answer))
+
+ def SetLimits(self, request, context):
+ tmItem = self._findItem(request)
+ if request.HasField('set'):
+ limitset = UnpackValue(request.set.limitset)
+ else:
+ limitset = {}
+
+ answer = REGISTRY['TM']._setLimits(tmItem,limitset)
+ if answer is None:
+ answer = True
+
+ return BoolValue(value = answer)
+
+ def IsAlarmed(self, request, context):
+ tmItem = self._findItem(request)
+ if request.HasField('config'):
+ config = UnpackValue(request.config)
+ else:
+ config = {}
+
+ answer = REGISTRY['TM']._isAlarmed(tmItem, config)
+ if answer is None:
+ answer = False
+
+ return BoolValue(value = answer)
+
+ def InjectItem(self, request, context):
+ tmItem = self._findItem(request)
+ if request.HasField('config'):
+ config = UnpackValue(request.config)
+ else:
+ config = {}
+ value = UnpackValue(request.engValue)
+
+ answer = REGISTRY['TM']._injectItem(tmItem, value, config)
+
+ if answer is None:
+ answer = False
+
+ return BoolValue(value = answer)
+
+ def RestoreNormalLimits(self, request, context):
+ answer = REGISTRY['TM']._restoreNormalLimits(UnpackValue(request))
+
+ if answer is None:
+ answer = False
+
+ return BoolValue(value = answer)
+
+ def Setup(self, request, context):
+ from spell.lib.drivermgr import DriverManager
+ mgr = DriverManager.instance()
+ REGISTRY['TM'].setup(mgr.contextConfig,mgr.driverConfig)
+ del DriverManager
+ return request
+
+ def Cleanup(self, request, context):
+ REGISTRY['TM'].cleanup()
+
+ return Empty()
+
+ def Ping(self, request, context):
+ return Empty()
+
+ def Close(self, request, context):
+ # TODO
+ return Empty()
diff --git a/drivers/service/user_service.py b/drivers/service/user_service.py
new file mode 100644
index 0000000..8d0338b
--- /dev/null
+++ b/drivers/service/user_service.py
@@ -0,0 +1,57 @@
+
+from spell.stubs.SPELLDriver_pb2_grpc import SPELLDriverInterface_USERServicer,\
+ add_SPELLDriverInterface_USERServicer_to_server
+from spell.lib.registry import REGISTRY
+from spell.utils.grpc_utils import UnpackValue, LogFunctionInput
+
+from google.protobuf.empty_pb2 import Empty
+from google.protobuf.wrappers_pb2 import BoolValue
+
+class SPELLDriverUSERInterfaceServicer(SPELLDriverInterface_USERServicer):
+
+ def __init__(self, server):
+ add_SPELLDriverInterface_USERServicer_to_server(self, server)
+
+ def Setup(self, request, context):
+ from spell.lib.drivermgr import DriverManager
+ mgr = DriverManager.instance()
+ REGISTRY['USER'].setup(mgr.contextConfig,mgr.driverConfig)
+ del DriverManager
+ return request
+
+ def Cleanup(self, request, context):
+ REGISTRY['USER'].cleanup()
+
+ return Empty()
+
+ def Ping(self, request, context):
+ return Empty()
+
+ def Close(self, request, context):
+ return Empty()
+
+ def Login(self, request, context):
+ name = request.username
+ pwd = request.password
+ config = UnpackValue(request.config)
+
+ result = REGISTRY['USER']._login(name, pwd, config)
+
+ return BoolValue(value = result)
+
+ def Logout(self, request, context):
+ name = request.username
+ config = UnpackValue(request.config)
+
+ result = REGISTRY['USER']._logout(name, config)
+
+ return BoolValue(value = result)
+
+
+ def IsLoggedIn(self, request, context):
+ name = request.username
+ config = UnpackValue(request.config)
+
+ result = REGISTRY['USER']._isLoggedIn(name, config)
+
+ return BoolValue(value = result)
diff --git a/include/SPELL_CFG/SPELLbrowsableLibMode.H b/include/SPELL_CFG/SPELLbrowsableLibMode.H
index f85ca7f..49e2d19 100644
--- a/include/SPELL_CFG/SPELLbrowsableLibMode.H
+++ b/include/SPELL_CFG/SPELLbrowsableLibMode.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Browsable modes
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CFG/SPELLconfiguration.H b/include/SPELL_CFG/SPELLconfiguration.H
index b758501..1f51510 100644
--- a/include/SPELL_CFG/SPELLconfiguration.H
+++ b/include/SPELL_CFG/SPELLconfiguration.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Wrapper to configuration reader instance
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CFG/SPELLcontextConfig.H b/include/SPELL_CFG/SPELLcontextConfig.H
index 7d8500f..0cf6571 100644
--- a/include/SPELL_CFG/SPELLcontextConfig.H
+++ b/include/SPELL_CFG/SPELLcontextConfig.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Wrapper for context configuration
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -76,6 +76,7 @@ public: //--------------------------------------------------------------------
// STATIC ////////////////////////////////////////////////////////////////
static const std::string ExecutorProgram;
+ static const std::string ServiceProgram;
static const std::string ExecutorStartTimeout;
static const std::string ExecutorLoginTimeout;
static const std::string UseDriverTime;
@@ -137,6 +138,12 @@ public: //--------------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
std::string getProcPath() const { return m_procPath; };
+ /** Obtain the current procedure path.
+ *
+ * \returns The procedure search path.
+ **////////////////////////////////////////////////////////////////////
+ std::string getServicePath() const { return m_servicePath; };
+
//////////////////////////////////////////////////////////////////////
/** Obtain the current library path.
*
@@ -292,6 +299,8 @@ private: //-------------------------------------------------------------------
std::string m_procPath;
/** Holds the library path */
std::string m_libPath;
+ /** Holds the service path */
+ std::string m_servicePath;
/** Holds the output data directory */
std::string m_outputDir;
/** Holds the input data directory */
diff --git a/include/SPELL_CFG/SPELLdriverConfig.H b/include/SPELL_CFG/SPELLdriverConfig.H
index a6f60dd..cee0254 100644
--- a/include/SPELL_CFG/SPELLdriverConfig.H
+++ b/include/SPELL_CFG/SPELLdriverConfig.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Wrapper for driver configuration
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CFG/SPELLexecutorDefaults.H b/include/SPELL_CFG/SPELLexecutorDefaults.H
index e92022b..a59b9cf 100644
--- a/include/SPELL_CFG/SPELLexecutorDefaults.H
+++ b/include/SPELL_CFG/SPELLexecutorDefaults.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Context default values for Executors
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -32,7 +32,7 @@
// Project includes ----------------------------------------------------------
#include "SPELL_WRP/SPELLconstants.H"
#include "SPELL_CFG/SPELLbrowsableLibMode.H"
-
+#include "SPELL_UTIL/SPELLutils.H"
/** \addtogroup SPELL_CFG */
/*@{*/
@@ -59,7 +59,20 @@ public: //--------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////
/** Constructor.
**////////////////////////////////////////////////////////////////////
- SPELLexecutorDefaults() {};
+ SPELLexecutorDefaults()
+ {
+ m_browsableLib = OFF;
+ m_byStep = false;
+ m_execDelay = 0;
+ m_watchVariables = false;
+ m_resourcesDisplay = false;
+ m_localResourceSupport = false;
+ m_forcePromptConfirm = false;
+ m_forceTcConfirm = false;
+ m_maxVerbosity = 0;
+ m_runInto = false;
+ m_promptWarningDelay = 0;
+ };
//////////////////////////////////////////////////////////////////////
/** Destructor.
@@ -74,58 +87,71 @@ public: //--------------------------------------------------------------------
// METHODS ///////////////////////////////////////////////////////////////
// Member variables getters
- int getExecDelay()
+ int getExecDelay() const
{
return m_execDelay;
}
- int getPromptWarningDelay()
+ int getPromptWarningDelay() const
{
return m_promptWarningDelay;
}
- bool isRunInto()
+ bool isRunInto() const
{
return m_runInto;
}
- bool isByStep()
+ bool isByStep() const
{
return m_byStep;
}
- SPELLbrowsableLibMode getBrowsableLib()
+ SPELLbrowsableLibMode getBrowsableLib() const
{
return m_browsableLib;
}
- std::string getBrowsableLibStr()
+ std::string getBrowsableLibStr() const
{
return browsableLibModeToString(m_browsableLib);
}
- int getMaxVerbosity()
+ int getMaxVerbosity() const
{
return m_maxVerbosity;
}
- bool isForceTcConfirm()
+ bool isForceTcConfirm() const
{
return m_forceTcConfirm;
}
-
- std::string getSaveStateMode()
+ bool isForcePromptConfirm() const
+ {
+ return m_forcePromptConfirm;
+ }
+ std::string getSaveStateMode() const
{
return m_saveStateMode;
} //getSaveStateMode
- bool isWatchVariables()
+ bool isWatchVariables() const
{
return m_watchVariables;
}
- std::string getCtxName()
+ bool isResourcesDisplay() const
+ {
+ return m_resourcesDisplay;
+ }
+
+ bool isLocalResourcesSupported() const
+ {
+ return m_localResourceSupport;
+ }
+
+ std::string getCtxName() const
{
return m_ctxName;
}
@@ -173,7 +199,10 @@ public: //--------------------------------------------------------------------
{
m_forceTcConfirm = forceTcConfirm;
}
-
+ void setForcePromptConfirm(bool forcePromptConfirm)
+ {
+ m_forcePromptConfirm = forcePromptConfirm;
+ }
void setSaveStateMode(std::string saveModeStr)
{
m_saveStateMode = saveModeStr;
@@ -184,6 +213,16 @@ public: //--------------------------------------------------------------------
m_watchVariables = watchVariables;
}
+ void setResourcesDisplay(bool resourcesDisplay)
+ {
+ m_resourcesDisplay = resourcesDisplay;
+ }
+
+ void setLocalResourcesSupported(bool localResourceSupport)
+ {
+ m_localResourceSupport = localResourceSupport;
+ }
+
void setCtxName( std::string ctxName)
{
m_ctxName = ctxName;
@@ -199,7 +238,10 @@ public: //--------------------------------------------------------------------
str.append("BrowsableLib: ").append( browsableLibModeToString(m_browsableLib) ).append("\n");
str.append("MaxVerbosity: ").append(ISTR(m_maxVerbosity)).append("\n");
str.append("ForceTcConfirm: ").append(BSTR(m_forceTcConfirm)).append("\n");
+ str.append("ForcePromptConfirm: ").append(BSTR(m_forcePromptConfirm)).append("\n");
str.append("WatchVariables: ").append(BSTR(m_watchVariables)).append("\n");
+ str.append("ResourcesDisplay: ").append(BSTR(m_resourcesDisplay)).append("\n");
+ str.append("LocalResourcesSupported: ").append(BSTR(m_localResourceSupport)).append("\n");
str.append("SaveStateMode: ").append(m_saveStateMode).append("\n");
return str;
@@ -218,15 +260,18 @@ private: //-------------------------------------------------------------------
// DATA MEMBERS //////////////////////////////////////////////////////////
int m_execDelay;
- int m_promptWarningDelay;
+ int m_promptWarningDelay;
bool m_runInto;
bool m_byStep;
//bool m_browsableLib;
SPELLbrowsableLibMode m_browsableLib;
int m_maxVerbosity;
bool m_forceTcConfirm;
+ bool m_forcePromptConfirm;
std::string m_saveStateMode;
bool m_watchVariables;
+ bool m_resourcesDisplay;
+ bool m_localResourceSupport;
std::string m_ctxName;
};
diff --git a/include/SPELL_CFG/SPELLxmlConfigReader.H b/include/SPELL_CFG/SPELLxmlConfigReader.H
index 7131b89..eedf53c 100644
--- a/include/SPELL_CFG/SPELLxmlConfigReader.H
+++ b/include/SPELL_CFG/SPELLxmlConfigReader.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Wrapper for the XML configuration reader
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CFG/SPELLxmlConfigReaderFactory.H b/include/SPELL_CFG/SPELLxmlConfigReaderFactory.H
index 6f6f0da..50c3251 100644
--- a/include/SPELL_CFG/SPELLxmlConfigReaderFactory.H
+++ b/include/SPELL_CFG/SPELLxmlConfigReaderFactory.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Factory for XML configuration readers
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CFG/SPELLxmlConfigReaderXC.H b/include/SPELL_CFG/SPELLxmlConfigReaderXC.H
index bc3074c..c012458 100644
--- a/include/SPELL_CFG/SPELLxmlConfigReaderXC.H
+++ b/include/SPELL_CFG/SPELLxmlConfigReaderXC.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Xerces-C based implementation of the XML config. reader
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CFG/SPELLxmlNode.H b/include/SPELL_CFG/SPELLxmlNode.H
index 993fd65..eaf6f2e 100644
--- a/include/SPELL_CFG/SPELLxmlNode.H
+++ b/include/SPELL_CFG/SPELLxmlNode.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Wrapper for XML configuration node
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CIF/SPELLasRun.H b/include/SPELL_CIF/SPELLasRun.H
index e27df9f..6245b32 100644
--- a/include/SPELL_CIF/SPELLasRun.H
+++ b/include/SPELL_CIF/SPELLasRun.H
@@ -5,7 +5,7 @@
// DESCRIPTION: As-Run file interface
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CIF/SPELLcif.H b/include/SPELL_CIF/SPELLcif.H
index 8eb3d0c..809a0b0 100644
--- a/include/SPELL_CIF/SPELLcif.H
+++ b/include/SPELL_CIF/SPELLcif.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Main CIF object interface
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -37,6 +37,7 @@
#include "SPELL_CIF/SPELLcifStartupInfo.H"
// Project includes --------------------------------------------------------
#include "SPELL_EXC/SPELLvarInfo.H"
+#include "SPELL_EXC/SPELLresourceInfo.H"
#include "SPELL_PRD/SPELLprocedureSourceCode.H"
#include "SPELL_SYN/SPELLevent.H"
@@ -226,6 +227,8 @@ public: //--------------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
void setVerbosity( int verbosity );
+ void setForcePromptConfirm( bool force );
+
//////////////////////////////////////////////////////////////////////
/** Set the current verbosity to the maximum allowed value
**////////////////////////////////////////////////////////////////////
@@ -344,7 +347,7 @@ public: //--------------------------------------------------------------------
* \param definition IN: prompt parameters
**////////////////////////////////////////////////////////////////////
//virtual std::string prompt( const SPELLpromptDefinition& definition ) = 0;
- virtual std::string prompt( const SPELLpromptDefinition& definition );
+ virtual std::string prompt( const SPELLpromptDefinition& definition,bool doPromptConfirm = true );
//////////////////////////////////////////////////////////////////////
/** Notify a variable change.
@@ -360,6 +363,18 @@ public: //--------------------------------------------------------------------
const std::vector& globals,
const std::vector& locals );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Notify a resource change.
+ **////////////////////////////////////////////////////////////////////
+ virtual void notifyResourceChange( const std::vector& changed );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Notify a resource list.
+ **////////////////////////////////////////////////////////////////////
+ virtual void notifyResourceList( const std::vector& resources );
+
+
//////////////////////////////////////////////////////////////////////
/** Substitute the current ASRUN file by the given one
*
@@ -535,6 +550,16 @@ protected: //-----------------------------------------------------------------
const std::vector& locals ) {;};
+ //////////////////////////////////////////////////////////////////////
+ /** See Notify a resource change.
+ **////////////////////////////////////////////////////////////////////
+ virtual void specificNotifyResourceChange( const std::vector& changed ) {;};
+
+ //////////////////////////////////////////////////////////////////////
+ /** See Notify a resource list.
+ **////////////////////////////////////////////////////////////////////
+ virtual void specificNotifyResourceList( const std::vector& resources ) {;};
+
//////////////////////////////////////////////////////////////////////
/** See OpenSubprocedure
**////////////////////////////////////////////////////////////////////
@@ -595,6 +620,8 @@ private: //-------------------------------------------------------------------
std::string m_procId;
/** True if manual mode is enabled */
bool m_manualMode;
+
+ bool m_forcePromptConfirm;
/** Current verbosity level */
int m_verbosity;
diff --git a/include/SPELL_CIF/SPELLcifHelper.H b/include/SPELL_CIF/SPELLcifHelper.H
index eeeef63..8c58a17 100644
--- a/include/SPELL_CIF/SPELLcifHelper.H
+++ b/include/SPELL_CIF/SPELLcifHelper.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Utilities for CIF
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CIF/SPELLcifStartupInfo.H b/include/SPELL_CIF/SPELLcifStartupInfo.H
index 298bf7a..31126d1 100644
--- a/include/SPELL_CIF/SPELLcifStartupInfo.H
+++ b/include/SPELL_CIF/SPELLcifStartupInfo.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Information for CIF startup
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CIF/SPELLnotifications.H b/include/SPELL_CIF/SPELLnotifications.H
index 8d5e09a..aa4471d 100644
--- a/include/SPELL_CIF/SPELLnotifications.H
+++ b/include/SPELL_CIF/SPELLnotifications.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Notification data structures
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CIF/SPELLpromptDefinition.H b/include/SPELL_CIF/SPELLpromptDefinition.H
index c81a9ab..ca4246f 100644
--- a/include/SPELL_CIF/SPELLpromptDefinition.H
+++ b/include/SPELL_CIF/SPELLpromptDefinition.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Parameters defining a prompt
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CIF/SPELLstatusInfo.H b/include/SPELL_CIF/SPELLstatusInfo.H
index fb23a21..a54c545 100644
--- a/include/SPELL_CIF/SPELLstatusInfo.H
+++ b/include/SPELL_CIF/SPELLstatusInfo.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Executor status information structure
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CIFC/SPELLautomaticCif.H b/include/SPELL_CIFC/SPELLautomaticCif.H
index 7d66e6b..97fa047 100644
--- a/include/SPELL_CIFC/SPELLautomaticCif.H
+++ b/include/SPELL_CIFC/SPELLautomaticCif.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Automatic (non-interactive) client interface implementation
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -146,6 +146,16 @@ public: //--------------------------------------------------------------------
const std::vector& locals );
+ //////////////////////////////////////////////////////////////////////
+ /** Notify a resource change.
+ **////////////////////////////////////////////////////////////////////
+ void specificNotifyResourceChange( const std::vector& changed );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Notify a resource list.
+ **////////////////////////////////////////////////////////////////////
+ void specificNotifyResourceList( const std::vector& resources );
+
//////////////////////////////////////////////////////////////////////
/** Open subprocedure.
*
diff --git a/include/SPELL_CIFC/SPELLncursesShell.H b/include/SPELL_CIFC/SPELLncursesShell.H
index e992f27..1c87c3e 100644
--- a/include/SPELL_CIFC/SPELLncursesShell.H
+++ b/include/SPELL_CIFC/SPELLncursesShell.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Command line shell for standalone execution (NCurses)
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -31,8 +31,7 @@
// System includes ---------------------------------------------------------
#include
#include
-#include
-#include
+#include
// Local includes ----------------------------------------------------------
// Project includes --------------------------------------------------------
#include "SPELL_SYN/SPELLthread.H"
diff --git a/include/SPELL_CIFC/SPELLstandaloneCif.H b/include/SPELL_CIFC/SPELLstandaloneCif.H
index 31a56b9..b6346b2 100644
--- a/include/SPELL_CIFC/SPELLstandaloneCif.H
+++ b/include/SPELL_CIFC/SPELLstandaloneCif.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Standalone execution client interface
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CIFS/SPELLcifPromptHelper.H b/include/SPELL_CIFS/SPELLcifPromptHelper.H
index 17f7711..559e757 100644
--- a/include/SPELL_CIFS/SPELLcifPromptHelper.H
+++ b/include/SPELL_CIFS/SPELLcifPromptHelper.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Helper for prompt processing
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CIFS/SPELLdisplayBuffer.H b/include/SPELL_CIFS/SPELLdisplayBuffer.H
index 8b3bd1b..2d8432b 100644
--- a/include/SPELL_CIFS/SPELLdisplayBuffer.H
+++ b/include/SPELL_CIFS/SPELLdisplayBuffer.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Buffer for Display() messages
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CIFS/SPELLrequestProcessor.H b/include/SPELL_CIFS/SPELLrequestProcessor.H
index 6df9f83..2bade15 100644
--- a/include/SPELL_CIFS/SPELLrequestProcessor.H
+++ b/include/SPELL_CIFS/SPELLrequestProcessor.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Processing code for client requests
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -161,6 +161,33 @@ protected: //-----------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
void processCheckVariablesEnabled( const SPELLipcMessage& msg, SPELLipcMessage& response );
+ //////////////////////////////////////////////////////////////////////
+ /** Process a request to get current resource names.
+ *
+ * \param msg IN: IPC request.
+ * \param response INOUT: IPC response to complete.
+ *
+ **////////////////////////////////////////////////////////////////////
+ void processGetResources( const SPELLipcMessage& msg, SPELLipcMessage& response );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Process a request to change a resource value
+ *
+ * \param msg IN: IPC request.
+ * \param response INOUT: IPC response to complete.
+ *
+ **////////////////////////////////////////////////////////////////////
+ void processChangeResource( const SPELLipcMessage& msg, SPELLipcMessage& response );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Process a request to check if resource analysis is enabled
+ *
+ * \param msg IN: IPC request.
+ * \param response INOUT: IPC response to complete.
+ *
+ **////////////////////////////////////////////////////////////////////
+ void processCheckResourcesEnabled( const SPELLipcMessage& msg, SPELLipcMessage& response );
+
//////////////////////////////////////////////////////////////////////
/** Process a request to get global dictionary contents
*
diff --git a/include/SPELL_CIFS/SPELLresourceBuffer.H b/include/SPELL_CIFS/SPELLresourceBuffer.H
new file mode 100644
index 0000000..6950743
--- /dev/null
+++ b/include/SPELL_CIFS/SPELLresourceBuffer.H
@@ -0,0 +1,146 @@
+// ################################################################################
+// FILE : SPELLresourceBuffer.H
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Buffer for Resource Display of TC Options (RDOTCO) messages
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+#ifndef __SPELL_RESOURCE_BUFFER_H__
+#define __SPELL_RESOURCE_BUFFER_H__
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// System includes ---------------------------------------------------------
+// Local includes ----------------------------------------------------------
+// Project includes --------------------------------------------------------
+#include "SPELL_EXC/SPELLresourceInfo.H"
+#include "SPELL_SYN/SPELLthread.H"
+#include "SPELL_SYN/SPELLthread.H"
+#include "SPELL_IPC/SPELLipcMessage.H"
+#include "SPELL_SYN/SPELLmutex.H"
+
+/** \addtogroup SPELL_CIFS */
+/*@{*/
+
+
+// FORWARD REFERENCES //////////////////////////////////////////////////////
+class SPELLserverCif;
+// TYPES ///////////////////////////////////////////////////////////////////
+// DEFINES /////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+/**
+ ** \brief Buffer for RDOTCO messages
+ **
+**////////////////////////////////////////////////////////////////////////////
+class SPELLresourceBuffer : public SPELLthread
+{
+public: //--------------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Constructor.
+ **////////////////////////////////////////////////////////////////////
+ SPELLresourceBuffer( const std::string& procId, SPELLserverCif& cif );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Destructor.
+ **////////////////////////////////////////////////////////////////////
+ ~SPELLresourceBuffer();
+
+ // METHODS ///////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Main thread method
+ **////////////////////////////////////////////////////////////////////
+ void run();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Stop the buffer
+ **////////////////////////////////////////////////////////////////////
+ void stop();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Send a resource update message
+ **////////////////////////////////////////////////////////////////////
+ void resourceChange( const std::vector& changed );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Send a resource list message
+ **////////////////////////////////////////////////////////////////////
+ void resourceList( const std::vector& resources );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Collect the accumulated information and send the IPC message.
+ **////////////////////////////////////////////////////////////////////
+ void flush();
+
+protected: //-----------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // STATIC ////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+
+private: //-------------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // STATIC ////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Check if data available
+ **////////////////////////////////////////////////////////////////////
+ bool hasDataToSend();
+
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+
+ /** Holds the reference to the CIF */
+ SPELLserverCif& m_cif;
+ /** Working flag */
+ bool m_working;
+ /** Synchronization lock */
+ SPELLmutex m_lock;
+ /** Notification message skeletons */
+ SPELLipcMessage m_resourceMessage;
+ /** List of added, updated and removed resources
+ * Note that it is a map, so updates overwrite:
+ * if a resource is added, then right away modified, then right away removed,
+ * only the removal effect will remain
+ * */
+ std::map m_resources;
+ /** Accumulation of notifications */
+ unsigned int m_total;
+ /** state whether the flush contain result of GetResources */
+ bool m_bufferHasListResources;
+};
+
+/*@}*/
+#endif
diff --git a/include/SPELL_CIFS/SPELLserverCif.H b/include/SPELL_CIFS/SPELLserverCif.H
index 115ebea..d69a900 100644
--- a/include/SPELL_CIFS/SPELLserverCif.H
+++ b/include/SPELL_CIFS/SPELLserverCif.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Client interface for server environment
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -33,6 +33,7 @@
#include "SPELL_CIFS/SPELLrequestProcessor.H"
#include "SPELL_CIFS/SPELLdisplayBuffer.H"
#include "SPELL_CIFS/SPELLvariableBuffer.H"
+#include "SPELL_CIFS/SPELLresourceBuffer.H"
// Project includes --------------------------------------------------------
#include "SPELL_SYN/SPELLthread.H"
#include "SPELL_SYN/SPELLevent.H"
@@ -164,6 +165,16 @@ public: //--------------------------------------------------------------------
const std::vector& globals,
const std::vector& locals );
+ //////////////////////////////////////////////////////////////////////
+ /** Notify a resource change.
+ **////////////////////////////////////////////////////////////////////
+ void specificNotifyResourceChange( const std::vector& changed );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Notify a resource list.
+ **////////////////////////////////////////////////////////////////////
+ void specificNotifyResourceList( const std::vector& resources );
+
//////////////////////////////////////////////////////////////////////
/** See openSubprocedure
**////////////////////////////////////////////////////////////////////
@@ -184,7 +195,9 @@ public: //--------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////
/** Get prompt information if any
**////////////////////////////////////////////////////////////////////
- SPELLpromptDefinition getPromptInfo() { return m_promptDef; }
+ SPELLpromptDefinition getPromptInfo() { return m_promptDef; };
+
+ SPELLipcMessage getPingMessage();
//====================================================================
// Python bindings end
@@ -196,6 +209,7 @@ protected: //-----------------------------------------------------------------
friend class SPELLdisplayBuffer;
friend class SPELLvariableBuffer;
+ friend class SPELLresourceBuffer;
// EXCEPTIONS ////////////////////////////////////////////////////////////
// ENUMS /////////////////////////////////////////////////////////////////
@@ -248,7 +262,7 @@ protected: //-----------------------------------------------------------------
//////////////////////////////////////////////////////////////////////
/** Wait acknowledge from client
*////////////////////////////////////////////////////////////////////
- void waitAcknowledge( const SPELLipcMessage& msg );
+ bool waitAcknowledge( const SPELLipcMessage& msg );
//====================================================================
// Shared data handling
@@ -341,7 +355,6 @@ protected: //-----------------------------------------------------------------
*////////////////////////////////////////////////////////////////////
void prepareMessage( SPELLipcMessage& msg, const std::string dataType, SPELLipcMessageType_ msgType );
-
// DATA MEMBERS //////////////////////////////////////////////////////////
private: //-------------------------------------------------------------------
@@ -408,6 +421,8 @@ private: //-------------------------------------------------------------------
SPELLdisplayBuffer* m_buffer;
/** Buffer to accumulate WOV messages */
SPELLvariableBuffer* m_wovBuffer;
+ /** Buffer to accumulate RDOTCO messages */
+ SPELLresourceBuffer* m_rdotcoBuffer;
/** True when the CIF is ready to work */
@@ -437,6 +452,8 @@ private: //-------------------------------------------------------------------
/** IPC synchronization */
SPELLmutex m_ipcLock;
+ /** Promp synchronization */
+ SPELLmutex m_promptLock;
/** Close synchronization */
SPELLmutex m_closeLock;
/** Closing flag */
diff --git a/include/SPELL_CIFS/SPELLvariableBuffer.H b/include/SPELL_CIFS/SPELLvariableBuffer.H
index d59bd2c..899e7ec 100644
--- a/include/SPELL_CIFS/SPELLvariableBuffer.H
+++ b/include/SPELL_CIFS/SPELLvariableBuffer.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Buffer for WOV messages
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLclient.H b/include/SPELL_CTX/SPELLclient.H
index bf4d23e..3efe632 100644
--- a/include/SPELL_CTX/SPELLclient.H
+++ b/include/SPELL_CTX/SPELLclient.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Client manager and controller
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLclientIPC.H b/include/SPELL_CTX/SPELLclientIPC.H
index c2eaf29..12f6ee4 100644
--- a/include/SPELL_CTX/SPELLclientIPC.H
+++ b/include/SPELL_CTX/SPELLclientIPC.H
@@ -5,7 +5,7 @@
// DESCRIPTION: IPC interface for clients
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLclientInterestList.H b/include/SPELL_CTX/SPELLclientInterestList.H
index 2cef023..7784308 100644
--- a/include/SPELL_CTX/SPELLclientInterestList.H
+++ b/include/SPELL_CTX/SPELLclientInterestList.H
@@ -5,7 +5,7 @@
// DESCRIPTION: List of the entities interested on a given client
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLclientListener.H b/include/SPELL_CTX/SPELLclientListener.H
index 371422a..07b7aa8 100644
--- a/include/SPELL_CTX/SPELLclientListener.H
+++ b/include/SPELL_CTX/SPELLclientListener.H
@@ -5,7 +5,7 @@
// DESCRIPTION: The implementing class is interested on client messages
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLclientManager.H b/include/SPELL_CTX/SPELLclientManager.H
index 74c172e..a2cab8b 100644
--- a/include/SPELL_CTX/SPELLclientManager.H
+++ b/include/SPELL_CTX/SPELLclientManager.H
@@ -5,7 +5,7 @@
// DESCRIPTION: SPELL client manager
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLclientMode.H b/include/SPELL_CTX/SPELLclientMode.H
index f25bf30..1e89cd6 100644
--- a/include/SPELL_CTX/SPELLclientMode.H
+++ b/include/SPELL_CTX/SPELLclientMode.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Client mode definition
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLclientNotifier.H b/include/SPELL_CTX/SPELLclientNotifier.H
index 60c72a1..81222a1 100644
--- a/include/SPELL_CTX/SPELLclientNotifier.H
+++ b/include/SPELL_CTX/SPELLclientNotifier.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Client notifier for monitoring mode
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLclientOperation.H b/include/SPELL_CTX/SPELLclientOperation.H
index dc9e1f1..faca460 100644
--- a/include/SPELL_CTX/SPELLclientOperation.H
+++ b/include/SPELL_CTX/SPELLclientOperation.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Definition of the client operations
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLcontext.H b/include/SPELL_CTX/SPELLcontext.H
index 2571ec0..a4e1073 100644
--- a/include/SPELL_CTX/SPELLcontext.H
+++ b/include/SPELL_CTX/SPELLcontext.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Main class of the context process
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -53,7 +53,9 @@
// FORWARD REFERENCES ////////////////////////////////////////////////////////
// TYPES /////////////////////////////////////////////////////////////////////
// DEFINES ///////////////////////////////////////////////////////////////////
-
+extern "C" {
+ void checkService( std::string& serviceId );
+}
//////////////////////////////////////////////////////////////////////////////
/**
** \brief
@@ -127,6 +129,7 @@ public: //--------------------------------------------------------------------
//====================================================================
SPELLipcMessage openExecutor( const SPELLipcMessage& msg, SPELLclient* controllingClient );
+ bool openService( const std::string serviceName );
SPELLipcMessage getInstanceId(const SPELLipcMessage& msg);
SPELLipcMessage getCurrentTime(const SPELLipcMessage& msg);
SPELLipcMessage closeExecutor(const SPELLipcMessage& msg);
@@ -136,10 +139,12 @@ public: //--------------------------------------------------------------------
SPELLipcMessage setExecutorInBackground( const SPELLipcMessage& msg );
SPELLipcMessage getProcedureList( const SPELLipcMessage& msg );
SPELLipcMessage getExecutorList( const SPELLipcMessage& msg );
+ SPELLipcMessage getServiceList( const SPELLipcMessage& msg );
SPELLipcMessage getProcedureProperties( const SPELLipcMessage& msg );
SPELLipcMessage getProcedureCode( const SPELLipcMessage& msg );
SPELLipcMessage getExecutorInfo(const SPELLipcMessage& msg);
- SPELLipcMessage attachExecutor(const SPELLipcMessage& msg, SPELLclient* client );
+ SPELLipcMessage getServiceInfo(const SPELLipcMessage& msg);
+ SPELLipcMessage attachExecutor(const SPELLipcMessage& msg, SPELLclient* client );
SPELLipcMessage detachExecutor(const SPELLipcMessage& msg, SPELLclient* client );
SPELLipcMessage getClientInfo(const SPELLipcMessage& msg);
SPELLipcMessage getServerFilePath(const SPELLipcMessage& msg);
@@ -169,6 +174,8 @@ public: //--------------------------------------------------------------------
//====================================================================
void clientLost( int clientKey );
void executorLost( const std::string& procId );
+ void serviceLost( const std::string& procId );
+
// STATIC ////////////////////////////////////////////////////////////////
diff --git a/include/SPELL_CTX/SPELLcontextConfiguration.H b/include/SPELL_CTX/SPELLcontextConfiguration.H
index 5ec5c1a..bfc7798 100644
--- a/include/SPELL_CTX/SPELLcontextConfiguration.H
+++ b/include/SPELL_CTX/SPELLcontextConfiguration.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Configuration for the context process
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLdataHelper.H b/include/SPELL_CTX/SPELLdataHelper.H
index 0288af5..d03885d 100644
--- a/include/SPELL_CTX/SPELLdataHelper.H
+++ b/include/SPELL_CTX/SPELLdataHelper.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Utilities for data handling
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLdataTable.H b/include/SPELL_CTX/SPELLdataTable.H
index 223366a..3b64e8f 100644
--- a/include/SPELL_CTX/SPELLdataTable.H
+++ b/include/SPELL_CTX/SPELLdataTable.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Shared data table
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLexecutor.H b/include/SPELL_CTX/SPELLexecutor.H
index 5d60e63..b083f88 100644
--- a/include/SPELL_CTX/SPELLexecutor.H
+++ b/include/SPELL_CTX/SPELLexecutor.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Executor manager and controller
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -46,7 +46,9 @@
// FORWARD REFERENCES ////////////////////////////////////////////////////////
+
class LoginMonitor;
+
// TYPES /////////////////////////////////////////////////////////////////////
// DEFINES ///////////////////////////////////////////////////////////////////
@@ -55,7 +57,7 @@ class LoginMonitor;
** \brief
**
**////////////////////////////////////////////////////////////////////////////
-class SPELLexecutor : public SPELLexecutorListener, SPELLprocessListener
+class SPELLexecutor : public SPELLexecutorListener,public SPELLprocessListener
{
public: //--------------------------------------------------------------------
@@ -79,126 +81,126 @@ public: //--------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////
/** Start the executor process
**////////////////////////////////////////////////////////////////////
- void start();
+ virtual void start();
//////////////////////////////////////////////////////////////////////
/** Close the executor process
**////////////////////////////////////////////////////////////////////
- void close();
+ virtual void close();
//////////////////////////////////////////////////////////////////////
/** Kill the executor process
**////////////////////////////////////////////////////////////////////
- void kill();
+ virtual void kill();
//////////////////////////////////////////////////////////////////////
/** Wait for a given executor status
*
* \returns True on timeout
**////////////////////////////////////////////////////////////////////
- bool waitStatus( const SPELLexecutorStatus& status, unsigned int timeoutSec );
+ virtual bool waitStatus( const SPELLexecutorStatus& status, unsigned int timeoutSec );
//////////////////////////////////////////////////////////////////////
/** Wait for executor login
*
* \returns True if logged in
**////////////////////////////////////////////////////////////////////
- bool waitLogin( unsigned int timeoutMsec );
+ virtual bool waitLogin( unsigned int timeoutMsec );
//////////////////////////////////////////////////////////////////////
/** Check for executor login
*
* \returns True if logged in
**////////////////////////////////////////////////////////////////////
- bool isLoggedIn() { return m_loggedIn; };
+ virtual bool isLoggedIn() { return m_loggedIn; };
//////////////////////////////////////////////////////////////////////
/** Get the status of the executor
*
* \returns The status
**////////////////////////////////////////////////////////////////////
- SPELLexecutorStatus getStatus();
+ virtual SPELLexecutorStatus getStatus();
//////////////////////////////////////////////////////////////////////
/** Check if the executor is active
*
* \returns True if active
**////////////////////////////////////////////////////////////////////
- bool isActive();
+ virtual bool isActive();
//////////////////////////////////////////////////////////////////////
/** Check if the executor has a parent procedure
*
* \returns True if has a parent
**////////////////////////////////////////////////////////////////////
- bool hasParent() { return m_model.getParentInstanceId() != ""; } ;
+ virtual bool hasParent() { return m_model.getParentInstanceId() != ""; } ;
//////////////////////////////////////////////////////////////////////
/** Get the executor parent procedure
*
* \returns The parent procedure id
**////////////////////////////////////////////////////////////////////
- std::string getParentInstanceId() { return m_model.getParentInstanceId(); } ;
+ virtual std::string getParentInstanceId() { return m_model.getParentInstanceId(); } ;
//////////////////////////////////////////////////////////////////////
/** Send a command to the executor
**////////////////////////////////////////////////////////////////////
- void command( const ExecutorCommand& command );
+ virtual void command( const ExecutorCommand& command );
//////////////////////////////////////////////////////////////////////
/** Set the controlling client
**////////////////////////////////////////////////////////////////////
- void setControllingClient( SPELLclient* client );
+ virtual void setControllingClient( SPELLclient* client );
//////////////////////////////////////////////////////////////////////
/** Set the procedure to headless (background) mode
**////////////////////////////////////////////////////////////////////
- void setBackground();
+ virtual void setBackground();
//////////////////////////////////////////////////////////////////////
/** Check whether the procedure is in headless (background) mode
**////////////////////////////////////////////////////////////////////
- bool isBackground() { return m_clientConnection == CLI_BACKGROUND; };
+ virtual bool isBackground() { return m_clientConnection == CLI_BACKGROUND; };
//////////////////////////////////////////////////////////////////////
/** Remove the controlling client
**////////////////////////////////////////////////////////////////////
- void removeControllingClient( bool clientLost );
+ virtual void removeControllingClient( bool clientLost );
//////////////////////////////////////////////////////////////////////
/** Check if it has controlling client
**////////////////////////////////////////////////////////////////////
- bool hasControllingClient();
+ virtual bool hasControllingClient();
//////////////////////////////////////////////////////////////////////
/** Check if it has controlling client
**////////////////////////////////////////////////////////////////////
- SPELLclient* getControllingClient();
+ virtual SPELLclient* getControllingClient();
//////////////////////////////////////////////////////////////////////
/** Send a message to the executor process
**////////////////////////////////////////////////////////////////////
- void sendMessageToExecutor( const SPELLipcMessage& msg );
+ virtual void sendMessageToExecutor( const SPELLipcMessage& msg );
//////////////////////////////////////////////////////////////////////
/** Send a request to the executor process
**////////////////////////////////////////////////////////////////////
- SPELLipcMessage sendRequestToExecutor( const SPELLipcMessage& msg );
+ virtual SPELLipcMessage sendRequestToExecutor( const SPELLipcMessage& msg );
//////////////////////////////////////////////////////////////////////
/** Get the executor model
**////////////////////////////////////////////////////////////////////
- SPELLexecutorModel& getModel() { return m_model; };
+ SPELLexecutorModel& getModel() { return m_model; };
//////////////////////////////////////////////////////////////////////
/** Register executor notifier for monitoring mode
**////////////////////////////////////////////////////////////////////
- void registerNotifier( std::string id, SPELLexecutorListener* listener );
+ virtual void registerNotifier( std::string id, SPELLexecutorListener* listener );
//////////////////////////////////////////////////////////////////////
/** Deregister executor notifier
**////////////////////////////////////////////////////////////////////
- void deregisterNotifier( std::string id );
+ virtual void deregisterNotifier( std::string id );
// DATA MEMBERS //////////////////////////////////////////////////////////
@@ -207,7 +209,7 @@ protected: //-----------------------------------------------------------------
friend class SPELLexecutorInterestList;
friend class SPELLprocessManager;
friend class SPELLexecutorIPC;
-
+ //friend class SPELLservice;
// EXCEPTIONS ////////////////////////////////////////////////////////////
// ENUMS /////////////////////////////////////////////////////////////////
// TYPES /////////////////////////////////////////////////////////////////
@@ -219,9 +221,9 @@ protected: //-----------------------------------------------------------------
// EXECUTOR REQUEST HANDLING
//====================================================================
- SPELLipcMessage executorLogin( const SPELLipcMessage& msg );
+ virtual SPELLipcMessage executorLogin( const SPELLipcMessage& msg );
- void executorNotification( const SPELLipcMessage& msg );
+ virtual void executorNotification( const SPELLipcMessage& msg );
//====================================================================
// INTERNAL IPC METHODS
@@ -230,27 +232,27 @@ protected: //-----------------------------------------------------------------
//////////////////////////////////////////////////////////////////////
/** \see SPELLexecutorListener.
**////////////////////////////////////////////////////////////////////
- void processMessageFromExecutor( SPELLipcMessage msg );
+ virtual void processMessageFromExecutor( SPELLipcMessage msg );
//////////////////////////////////////////////////////////////////////
/** \see SPELLexecutorListener.
**////////////////////////////////////////////////////////////////////
- SPELLipcMessage processRequestFromExecutor( SPELLipcMessage msg );
+ virtual SPELLipcMessage processRequestFromExecutor( SPELLipcMessage msg );
//////////////////////////////////////////////////////////////////////
/** Forward a message from the executor to the client
**////////////////////////////////////////////////////////////////////
- void forwardMessageToClient( const SPELLipcMessage& msg );
+ virtual void forwardMessageToClient( const SPELLipcMessage& msg );
//////////////////////////////////////////////////////////////////////
/** Forward a request from the executor to the client
**////////////////////////////////////////////////////////////////////
- SPELLipcMessage forwardRequestToClient( const SPELLipcMessage& msg );
+ virtual SPELLipcMessage forwardRequestToClient( const SPELLipcMessage& msg );
//////////////////////////////////////////////////////////////////////
/** Force an executor pause
**////////////////////////////////////////////////////////////////////
- void forcePause();
+ virtual void forcePause();
//====================================================================
// INTERNAL PROCESS CONTROL METHODS
@@ -261,36 +263,36 @@ protected: //-----------------------------------------------------------------
*
* \returns True if active
**////////////////////////////////////////////////////////////////////
- bool processOk();
+ virtual bool processOk();
//////////////////////////////////////////////////////////////////////
/** Wait until the executor process has finished
**////////////////////////////////////////////////////////////////////
- void waitFinish();
+ virtual void waitFinish();
//////////////////////////////////////////////////////////////////////
/** \see SPELLprocessListener.
**////////////////////////////////////////////////////////////////////
- void processStarted( const std::string& identifier );
+ virtual void processStarted( const std::string identifier );
//////////////////////////////////////////////////////////////////////
/** \see SPELLprocessListener.
**////////////////////////////////////////////////////////////////////
- void processFinished( const std::string& identifier, const int& retValue );
+ virtual void processFinished( const std::string identifier, const int& retValue );
//////////////////////////////////////////////////////////////////////
/** \see SPELLprocessListener.
**////////////////////////////////////////////////////////////////////
- void processKilled( const std::string& identifier );
+ virtual void processKilled( const std::string identifier );
//////////////////////////////////////////////////////////////////////
/** \see SPELLprocessListener.
**////////////////////////////////////////////////////////////////////
- void processFailed( const std::string& identifier );
+ virtual void processFailed( const std::string identifier );
private: //-------------------------------------------------------------------
-
+ friend class SPELLservice;
// EXCEPTIONS ////////////////////////////////////////////////////////////
// ENUMS /////////////////////////////////////////////////////////////////
// TYPES /////////////////////////////////////////////////////////////////
@@ -347,6 +349,19 @@ private: //-------------------------------------------------------------------
};
+class LoginMonitor : public SPELLthread
+{
+public:
+ LoginMonitor( SPELLexecutor& exec )
+ : SPELLthread("login-" + exec.getModel().getInstanceId() ),
+ m_exec( exec )
+ {}
+
+ void run();
+
+private:
+ SPELLexecutor& m_exec;
+};
/*@}*/
#endif
diff --git a/include/SPELL_CTX/SPELLexecutorIPC.H b/include/SPELL_CTX/SPELLexecutorIPC.H
index ab15f8e..16bf9a7 100644
--- a/include/SPELL_CTX/SPELLexecutorIPC.H
+++ b/include/SPELL_CTX/SPELLexecutorIPC.H
@@ -5,7 +5,7 @@
// DESCRIPTION: IPC interface for executors
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLexecutorListener.H b/include/SPELL_CTX/SPELLexecutorListener.H
index 48d9570..96834fa 100644
--- a/include/SPELL_CTX/SPELLexecutorListener.H
+++ b/include/SPELL_CTX/SPELLexecutorListener.H
@@ -5,7 +5,7 @@
// DESCRIPTION: The implementing class is interested on executor messages
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLexecutorManager.H b/include/SPELL_CTX/SPELLexecutorManager.H
index 7028c58..0fbdc45 100644
--- a/include/SPELL_CTX/SPELLexecutorManager.H
+++ b/include/SPELL_CTX/SPELLexecutorManager.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Manages the executor operations interacts with clients
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -225,8 +225,6 @@ private: //-------------------------------------------------------------------
void addInstanceNumber( const std::string& procId, int instanceNum );
- void removeInstanceNumber( const std::string& procId, int instanceNum );
-
void clearModels();
// DATA MEMBERS //////////////////////////////////////////////////////////
diff --git a/include/SPELL_CTX/SPELLexecutorModel.H b/include/SPELL_CTX/SPELLexecutorModel.H
index 131bce2..ed1bd8b 100644
--- a/include/SPELL_CTX/SPELLexecutorModel.H
+++ b/include/SPELL_CTX/SPELLexecutorModel.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Information of a given executor
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -136,7 +136,8 @@ public: //--------------------------------------------------------------------
protected: //-----------------------------------------------------------------
- friend class SPELLexecutor;
+ friend class SPELLexecutor;
+ friend class SPELLservice;
// EXCEPTIONS ////////////////////////////////////////////////////////////
// ENUMS /////////////////////////////////////////////////////////////////
diff --git a/include/SPELL_CTX/SPELLexecutorOperation.H b/include/SPELL_CTX/SPELLexecutorOperation.H
index 8bd716e..bec7136 100644
--- a/include/SPELL_CTX/SPELLexecutorOperation.H
+++ b/include/SPELL_CTX/SPELLexecutorOperation.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Definition of the executor operations
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLexecutorStartupParams.H b/include/SPELL_CTX/SPELLexecutorStartupParams.H
index cedb0b6..7e241ee 100644
--- a/include/SPELL_CTX/SPELLexecutorStartupParams.H
+++ b/include/SPELL_CTX/SPELLexecutorStartupParams.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Configuration for the executor process
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -126,7 +126,7 @@ public: //--------------------------------------------------------------------
void setRecoveryFile( const std::string& recoveryFile ) { m_recoveryFile = recoveryFile; };
private: //-------------------------------------------------------------------
-
+ friend class SPELLserviceStartupParams;
// EXCEPTIONS ////////////////////////////////////////////////////////////
// ENUMS /////////////////////////////////////////////////////////////////
// TYPES /////////////////////////////////////////////////////////////////
diff --git a/include/SPELL_CTX/SPELLlistenerIPC.H b/include/SPELL_CTX/SPELLlistenerIPC.H
index 1ed02d0..7902e27 100644
--- a/include/SPELL_CTX/SPELLlistenerIPC.H
+++ b/include/SPELL_CTX/SPELLlistenerIPC.H
@@ -5,7 +5,7 @@
// DESCRIPTION: IPC interface for listener
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLopenMode.H b/include/SPELL_CTX/SPELLopenMode.H
index 330e9d7..792390e 100644
--- a/include/SPELL_CTX/SPELLopenMode.H
+++ b/include/SPELL_CTX/SPELLopenMode.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Executor open mode definition
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLpersistencyTable.H b/include/SPELL_CTX/SPELLpersistencyTable.H
index b7912dc..9b59cee 100644
--- a/include/SPELL_CTX/SPELLpersistencyTable.H
+++ b/include/SPELL_CTX/SPELLpersistencyTable.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Keeps persistency of open executors
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLserverFile.H b/include/SPELL_CTX/SPELLserverFile.H
index 9dbcfc8..c5e013c 100644
--- a/include/SPELL_CTX/SPELLserverFile.H
+++ b/include/SPELL_CTX/SPELLserverFile.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Type of server file definition
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_CTX/SPELLservice.H b/include/SPELL_CTX/SPELLservice.H
new file mode 100644
index 0000000..1b8c3d0
--- /dev/null
+++ b/include/SPELL_CTX/SPELLservice.H
@@ -0,0 +1,89 @@
+// ################################################################################
+// FILE : SPELLservice.H
+// DATE : Apr 11, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Executor manager and controller
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+#ifndef __SPELL_SERVICE_H__
+#define __SPELL_SERVICE_H__
+
+// FILES TO INCLUDE //////////////////////////////////////////////////////////
+// Local includes ------------------------------------------------------------
+#include "SPELL_CTX/SPELLserviceListener.H"
+#include "SPELL_CTX/SPELLserviceStartupParams.H"
+#include "SPELL_CTX/SPELLclient.H"
+#include "SPELL_CTX/SPELLexecutor.H"
+// Project includes ----------------------------------------------------------
+#include "SPELL_PRC/SPELLprocessManager.H"
+#include "SPELL_EXC/SPELLcommand.H"
+#include "SPELL_EXC/SPELLexecutorStatus.H"
+#include "SPELL_SYN/SPELLevent.H"
+#include "SPELL_SYN/SPELLmutex.H"
+
+/** \addtogroup SPELL_CTX */
+/*@{*/
+
+
+// FORWARD REFERENCES ////////////////////////////////////////////////////////
+
+// TYPES /////////////////////////////////////////////////////////////////////
+// DEFINES ///////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+/**
+ ** \brief
+ **
+**////////////////////////////////////////////////////////////////////////////
+class SPELLservice : public SPELLexecutor
+{
+public: //--------------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Constructor.
+ **////////////////////////////////////////////////////////////////////
+ SPELLservice( const SPELLserviceStartupParams& config );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Destructor.
+ **////////////////////////////////////////////////////////////////////
+ virtual ~SPELLservice();
+
+ // METHODS ///////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Start the executor process
+ **////////////////////////////////////////////////////////////////////
+ void start();
+
+
+
+};
+
+
+/*@}*/
+#endif
diff --git a/include/SPELL_CTX/SPELLserviceListener.H b/include/SPELL_CTX/SPELLserviceListener.H
new file mode 100644
index 0000000..a2a6b56
--- /dev/null
+++ b/include/SPELL_CTX/SPELLserviceListener.H
@@ -0,0 +1,109 @@
+// ################################################################################
+// FILE : SPELLserviceListener.H
+// DATE : Apr 11, 2011
+// PROJECT : SPELL
+// DESCRIPTION: The implementing class is interested on executor messages
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+#ifndef __SPELL_SERVICE_LISTENER_H__
+#define __SPELL_SERVICE_LISTENER_H__
+
+// FILES TO INCLUDE //////////////////////////////////////////////////////////
+// Local includes ------------------------------------------------------------
+// Project includes ----------------------------------------------------------
+#include "SPELL_IPC/SPELLipcMessage.H"
+
+/** \addtogroup SPELL_CTX */
+/*@{*/
+
+
+// FORWARD REFERENCES ////////////////////////////////////////////////////////
+// TYPES /////////////////////////////////////////////////////////////////////
+// DEFINES ///////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+/**
+ ** \brief
+ **
+**////////////////////////////////////////////////////////////////////////////
+class SPELLserviceListener
+{
+public: //--------------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Constructor.
+ **////////////////////////////////////////////////////////////////////
+ SPELLserviceListener() {};
+
+ //////////////////////////////////////////////////////////////////////
+ /** Destructor.
+ **////////////////////////////////////////////////////////////////////
+ virtual ~SPELLserviceListener() {};
+
+ // METHODS ///////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Process an incoming message.
+ *
+ * \param msg IN: the message to be processed.
+ **////////////////////////////////////////////////////////////////////
+ virtual void processMessageFromService( SPELLipcMessage msg ) = 0;
+
+ //////////////////////////////////////////////////////////////////////
+ /** Process an incoming request.
+ *
+ * \param msg IN: request to be processed.
+ *
+ * \return The request response.
+ **////////////////////////////////////////////////////////////////////
+ virtual SPELLipcMessage processRequestFromService( SPELLipcMessage msg ) = 0;
+
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+
+protected: //-----------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // STATIC ////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+
+private: //-------------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // STATIC ////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+
+};
+
+/*@}*/
+#endif
diff --git a/include/SPELL_CTX/SPELLserviceManager.H b/include/SPELL_CTX/SPELLserviceManager.H
new file mode 100644
index 0000000..a472b90
--- /dev/null
+++ b/include/SPELL_CTX/SPELLserviceManager.H
@@ -0,0 +1,250 @@
+// ################################################################################
+// FILE : SPELLexecutorManager.H
+// DATE : Apr 11, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Manages the executor operations interacts with clients
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+#ifndef __SPELL_SERVICE_MANAGER_H__
+#define __SPELL_SERVICE_MANAGER_H__
+
+// FILES TO INCLUDE //////////////////////////////////////////////////////////
+// Local includes ------------------------------------------------------------
+#include "SPELL_CTX/SPELLservice.H"
+#include "SPELL_CTX/SPELLclient.H"
+#include "SPELL_CTX/SPELLserviceStartupParams.H"
+
+#include "SPELL_CTX/SPELLpersistencyTable.H"
+// Project includes ----------------------------------------------------------
+#include "SPELL_EXC/SPELLcommand.H"
+#include "SPELL_SYN/SPELLmutex.H"
+#include "SPELL_IPC/SPELLipcMessage.H"
+
+/** \addtogroup SPELL_CTX */
+/*@{*/
+
+
+// FORWARD REFERENCES ////////////////////////////////////////////////////////
+// TYPES /////////////////////////////////////////////////////////////////////
+// DEFINES ///////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+/**
+ ** \brief
+ **
+ ** \par Description:
+ **
+ ** \par Usage:
+ **
+ ** \par Synchronization:
+ **
+**////////////////////////////////////////////////////////////////////////////
+class SPELLserviceManager
+{
+public: //--------------------------------------------------------------------
+
+ // ENUMS /////////////////////////////////////////////////////////////////
+
+ typedef enum ErrorCode_
+ {
+ UNKNOWN_PROC_ID,
+ SERVICE_FAILED_STARTUP,
+ SERVICE_CRASHED,
+ UNKNOWN
+ }
+ ErrorCode;
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+
+ typedef struct OperationError_
+ {
+ std::string message;
+ ErrorCode errorCode;
+ }
+ OperationError;
+
+ // TYPES /////////////////////////////////////////////////////////////////
+
+ typedef std::list ServiceList;
+
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Constructor.
+ **////////////////////////////////////////////////////////////////////
+ SPELLserviceManager();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Destructor.
+ **////////////////////////////////////////////////////////////////////
+ ~SPELLserviceManager();
+
+ // STATIC ////////////////////////////////////////////////////////////////
+
+ static SPELLserviceManager& instance();
+
+ // METHODS ///////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Start a service
+ **////////////////////////////////////////////////////////////////////
+ void startService( SPELLserviceStartupParams& config );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Stop an executor
+ **////////////////////////////////////////////////////////////////////
+ void closeService(std::string& serviceId );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Kill an executor
+ **////////////////////////////////////////////////////////////////////
+ void killService( const std::string& serviceId );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Kill all executors
+ **////////////////////////////////////////////////////////////////////
+ void killAll();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Check for active executors
+ **////////////////////////////////////////////////////////////////////
+ unsigned int getNumActiveServices();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Obtain an available instance identifier
+ **////////////////////////////////////////////////////////////////////
+ std::string getInstanceId( const std::string& serviceId );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Initialize the manager
+ **////////////////////////////////////////////////////////////////////
+ void setup( const std::string& contextName );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Cleanup the manager
+ **////////////////////////////////////////////////////////////////////
+ void cleanup();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Obtain a given executor
+ **////////////////////////////////////////////////////////////////////
+ SPELLservice* getService( const std::string& serviceId );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Obtain list of existing executors
+ **////////////////////////////////////////////////////////////////////
+ ServiceList getServiceList();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Report an executor lost
+ **////////////////////////////////////////////////////////////////////
+ void serviceLost( SPELLservice& service );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Mark executor to be cleared
+ **////////////////////////////////////////////////////////////////////
+ void clearService( const std::string& instanceId );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Closes a service
+ **////////////////////////////////////////////////////////////////////
+ void closeService( const std::string& instanceId );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Complete the message with executor information
+ **////////////////////////////////////////////////////////////////////
+ void buildServiceInfo( const std::string& serviceId, SPELLipcMessage& msg );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Delete files corresponding to the given executor
+ **////////////////////////////////////////////////////////////////////
+ void deleteServiceFiles( const SPELLserviceStartupParams& config );
+
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+
+protected: //-----------------------------------------------------------------
+
+ friend class ServiceLoginMonitor;
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+
+ void callback_serviceReconnected( const std::string& instanceId );
+ void callback_serviceNotReconnected( const std::string& instanceId );
+
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+
+private: //-------------------------------------------------------------------
+ friend class SPELLexecutorManager;
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+
+ typedef std::map ServiceMap;
+ typedef std::list InstanceList;
+ typedef std::map InstanceMap;
+ typedef std::list IdentifierList;
+
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Prepare to executor reconnection in case of starting after crash
+ **////////////////////////////////////////////////////////////////////
+ void reconnectServices();
+
+ void addServiceModel( SPELLservice* exec );
+
+ void removeServiceModel( const std::string& instanceId );
+
+ bool hasInstanceNumber( const std::string& serviceId, int instanceNum );
+
+ void addInstanceNumber( const std::string& serviceId, int instanceNum );
+
+ void clearModels();
+
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+
+ /** Synchronization lock */
+ SPELLmutex m_lock;
+ /** Holds the singleton instance */
+ static SPELLserviceManager* s_instance;
+ /** Holds the map of existing executors */
+ ServiceMap m_services;
+ /** Holds the map of existing instance numbers */
+ InstanceMap m_instances;
+ /** Holds the context name */
+ std::string m_contextName;
+ /** Holds the list of executors to be cleared next time */
+ IdentifierList m_toClear;
+ /** Holds the persistency table for executors */
+ SPELLpersistencyTable* m_persisTable;
+ /** Orphan executors pending login */
+ ServiceMap m_pendingLogin;
+
+};
+
+/*@}*/
+#endif
diff --git a/include/SPELL_CTX/SPELLserviceStartupParams.H b/include/SPELL_CTX/SPELLserviceStartupParams.H
new file mode 100644
index 0000000..e999a08
--- /dev/null
+++ b/include/SPELL_CTX/SPELLserviceStartupParams.H
@@ -0,0 +1,143 @@
+// ################################################################################
+// FILE : SPELLexecutorStartupParams.H
+// DATE : Feb 13, 2014
+// PROJECT : SPELL
+// DESCRIPTION: Configuration for the executor process
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+#ifndef __SPELL_SERVICE_STARTUP_PARAMS_H__
+#define __SPELL_SERVICE_STARTUP_PARAMS_H__
+
+// FILES TO INCLUDE //////////////////////////////////////////////////////////
+// Local includes ------------------------------------------------------------
+#include "SPELL_CTX/SPELLclientMode.H"
+#include "SPELL_CTX/SPELLopenMode.H"
+#include "SPELL_CTX/SPELLexecutorStartupParams.H"
+// Project includes ----------------------------------------------------------
+#include "SPELL_UTIL/SPELLbase.H"
+#include "SPELL_UTIL/SPELLutils.H"
+
+/** \addtogroup SPELL_CTX */
+/*@{*/
+
+
+// FORWARD REFERENCES ////////////////////////////////////////////////////////
+// TYPES /////////////////////////////////////////////////////////////////////
+// DEFINES ///////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+/**
+ ** \brief
+ **
+**////////////////////////////////////////////////////////////////////////////
+class SPELLserviceStartupParams : public SPELLexecutorStartupParams
+{
+public: //--------------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Constructor.
+ **////////////////////////////////////////////////////////////////////
+ SPELLserviceStartupParams( const std::string& instanceId, const std::string& timeId, bool reconnecting = false ) :
+ SPELLexecutorStartupParams(instanceId,timeId,reconnecting)
+ {
+ int idx = instanceId.find("#");
+ m_procId = instanceId.substr(0, idx);
+ m_timeId = timeId;
+ m_instanceNum = STRI(instanceId.substr(idx+1,instanceId.size()-idx));
+ m_instanceId = instanceId;
+ m_arguments = "";
+ m_condition = "";
+ m_clientMode = CLIENT_MODE_UNKNOWN;
+ m_openMode = OPEN_MODE_UNKNOWN;
+ m_parentInstanceId = "";
+ m_groupId = "";
+ m_originId = "";
+ m_parentCallingLine = 0;
+ m_configFile = "";
+ m_contextName = "";
+ m_recoveryFile = "";
+ m_ipcPort = 0;
+ m_PID = 0;
+ m_reconnecting = reconnecting;
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ /** Destructor.
+ **////////////////////////////////////////////////////////////////////
+ ~SPELLserviceStartupParams() {};
+
+ // METHODS ///////////////////////////////////////////////////////////////
+
+ std::string getProcId() const { return m_procId; };
+ std::string getTimeId() const { return m_timeId; };
+ std::string getInstanceId() const { return m_instanceId; };
+ std::string getOriginId() const { return m_originId; };
+ std::string getGroupId() const { return m_groupId; };
+ unsigned int getInstanceNum() const { return m_instanceNum; };
+
+ pid_t getPID() const { return m_PID; };
+ int getIpcPort() const { return m_ipcPort; };
+ bool isReconnecting() const { return m_reconnecting; }
+
+ std::string getArguments() const { return m_arguments; };
+ std::string getCondition() const { return m_condition; };
+ SPELLclientMode getClientMode() const { return m_clientMode; };
+ SPELLopenMode getOpenMode() const { return m_openMode; };
+ std::string getParentInstanceId() const { return m_parentInstanceId; };
+ int getParentCallingLine() const { return m_parentCallingLine; };
+ std::string getConfigFile() const { return m_configFile; };
+ std::string getContextName() const { return m_contextName; };
+ std::string getRecoveryFile() const { return m_recoveryFile; };
+
+ void setPID( pid_t pid ) { m_PID = pid; };
+ void setIpcPort( int ipcPort ) { m_ipcPort = ipcPort; };
+ void setArguments( const std::string& arguments ) { m_arguments = arguments; };
+ void setCondition( const std::string& condition ) { m_condition = condition; };
+ void setClientMode( const SPELLclientMode& mode ) { m_clientMode = mode; };
+ void setOpenMode( const SPELLopenMode& mode ) { m_openMode = mode; };
+ void setParentInstanceId( const std::string& parentInstanceId ) { m_parentInstanceId = parentInstanceId; };
+ void setGroupId( const std::string& groupId ) { m_groupId = groupId; };
+ void setOriginId( const std::string& originId ) { m_originId = originId; };
+ void setParentCallingLine( int lineNo ) { m_parentCallingLine = lineNo; };
+ void setConfigFile( const std::string& configFile ) { m_configFile = configFile; };
+ void setContextName( const std::string& ctxName ) { m_contextName = ctxName; };
+ void setRecoveryFile( const std::string& recoveryFile ) { m_recoveryFile = recoveryFile; };
+
+private: //-------------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // STATIC ////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+
+};
+
+/*@}*/
+#endif
diff --git a/include/SPELL_CTX/SPELLsharedData.H b/include/SPELL_CTX/SPELLsharedData.H
index 31ba17d..8011f5f 100644
--- a/include/SPELL_CTX/SPELLsharedData.H
+++ b/include/SPELL_CTX/SPELLsharedData.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Shared data blackboard
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -161,7 +161,7 @@ public: //--------------------------------------------------------------------
protected: //-----------------------------------------------------------------
- friend class SPELLclientInterestList;
+ //friend class SPELLclientInterestList;
// EXCEPTIONS ////////////////////////////////////////////////////////////
// ENUMS /////////////////////////////////////////////////////////////////
diff --git a/include/SPELL_CTX/SPELLsharedDataOperation.H b/include/SPELL_CTX/SPELLsharedDataOperation.H
index dd181cc..afe09eb 100644
--- a/include/SPELL_CTX/SPELLsharedDataOperation.H
+++ b/include/SPELL_CTX/SPELLsharedDataOperation.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Definition of the shared data operations
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_DTA/SPELLdtaContainer.H b/include/SPELL_DTA/SPELLdtaContainer.H
index 09f8f80..7c05ac8 100644
--- a/include/SPELL_DTA/SPELLdtaContainer.H
+++ b/include/SPELL_DTA/SPELLdtaContainer.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Data variable container implementation
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_DTA/SPELLdtaContainerObject.H b/include/SPELL_DTA/SPELLdtaContainerObject.H
index ae7c792..6c65183 100644
--- a/include/SPELL_DTA/SPELLdtaContainerObject.H
+++ b/include/SPELL_DTA/SPELLdtaContainerObject.H
@@ -5,7 +5,7 @@
// DESCRIPTION: SPELL data dictionary
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_DTA/SPELLdtaVariable.H b/include/SPELL_DTA/SPELLdtaVariable.H
index 2b3047c..500ef67 100644
--- a/include/SPELL_DTA/SPELLdtaVariable.H
+++ b/include/SPELL_DTA/SPELLdtaVariable.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Data variable implementation
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_DTA/SPELLdtaVariableObject.H b/include/SPELL_DTA/SPELLdtaVariableObject.H
index 0040be3..dd02d3e 100644
--- a/include/SPELL_DTA/SPELLdtaVariableObject.H
+++ b/include/SPELL_DTA/SPELLdtaVariableObject.H
@@ -5,7 +5,7 @@
// DESCRIPTION: SPELL variable
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLastAnalyzer.H b/include/SPELL_EXC/SPELLastAnalyzer.H
index 54aa0a8..dd2bacb 100644
--- a/include/SPELL_EXC/SPELLastAnalyzer.H
+++ b/include/SPELL_EXC/SPELLastAnalyzer.H
@@ -6,7 +6,7 @@
// procedure execution.
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLbreakpoint.H b/include/SPELL_EXC/SPELLbreakpoint.H
index 13e1a2f..058d71f 100644
--- a/include/SPELL_EXC/SPELLbreakpoint.H
+++ b/include/SPELL_EXC/SPELLbreakpoint.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Management of breakpoints in the current procedure
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLbreakpointType.H b/include/SPELL_EXC/SPELLbreakpointType.H
index d3dd559..8820a66 100644
--- a/include/SPELL_EXC/SPELLbreakpointType.H
+++ b/include/SPELL_EXC/SPELLbreakpointType.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Types of breakpoints
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLbytecode.H b/include/SPELL_EXC/SPELLbytecode.H
index 67eab6a..2211a32 100644
--- a/include/SPELL_EXC/SPELLbytecode.H
+++ b/include/SPELL_EXC/SPELLbytecode.H
@@ -6,7 +6,7 @@
// that affect the executor features at runtime.
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -28,6 +28,11 @@
#ifndef __SPELL_BCODE_H__
#define __SPELL_BCODE_H__
+#ifndef JUMP_IF_TRUE
+#define JUMP_IF_TRUE JUMP_IF_TRUE_OR_POP
+#define JUMP_IF_FALSE JUMP_IF_FALSE_OR_POP
+#endif
+
// FILES TO INCLUDE ////////////////////////////////////////////////////////
// System includes ---------------------------------------------------------
// Local includes ----------------------------------------------------------
diff --git a/include/SPELL_EXC/SPELLcallstack.H b/include/SPELL_EXC/SPELLcallstack.H
index 9b62aa9..1af56e6 100644
--- a/include/SPELL_EXC/SPELLcallstack.H
+++ b/include/SPELL_EXC/SPELLcallstack.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Call stack model.
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -90,7 +90,7 @@ public: //--------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////
/** \see SPELLcallstackIF.
**////////////////////////////////////////////////////////////////////
- const std::string& getStack();
+ const std::string getStack();
//////////////////////////////////////////////////////////////////////
/** \see SPELLcallstackIF.
@@ -105,7 +105,7 @@ public: //--------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////
/** \see SPELLcallstackIF.
**////////////////////////////////////////////////////////////////////
- const std::string& getCodeName();
+ const std::string getCodeName();
//////////////////////////////////////////////////////////////////////
/** \see SPELLcallstackIF.
diff --git a/include/SPELL_EXC/SPELLcallstackIF.H b/include/SPELL_EXC/SPELLcallstackIF.H
index 79c022e..cebb586 100644
--- a/include/SPELL_EXC/SPELLcallstackIF.H
+++ b/include/SPELL_EXC/SPELLcallstackIF.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Call stack interface.
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -85,7 +85,7 @@ public: //--------------------------------------------------------------------
*
* \returns The current callstack string.
**////////////////////////////////////////////////////////////////////
- virtual const std::string& getStack() = 0;
+ virtual const std::string getStack() = 0;
//////////////////////////////////////////////////////////////////////
/** Obtain the current callstack string.
@@ -106,7 +106,7 @@ public: //--------------------------------------------------------------------
*
* \returns The current code name string.
**////////////////////////////////////////////////////////////////////
- virtual const std::string& getCodeName() = 0;
+ virtual const std::string getCodeName() = 0;
//////////////////////////////////////////////////////////////////////
/** Set the step over mode.
diff --git a/include/SPELL_EXC/SPELLchildManager.H b/include/SPELL_EXC/SPELLchildManager.H
index 7f14e24..f1ca33d 100644
--- a/include/SPELL_EXC/SPELLchildManager.H
+++ b/include/SPELL_EXC/SPELLchildManager.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Child procedure controller.
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLcodeTreeLine.H b/include/SPELL_EXC/SPELLcodeTreeLine.H
index caa4716..c060247 100644
--- a/include/SPELL_EXC/SPELLcodeTreeLine.H
+++ b/include/SPELL_EXC/SPELLcodeTreeLine.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Code tree line model implementation
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLcodeTreeLineIF.H b/include/SPELL_EXC/SPELLcodeTreeLineIF.H
index f8c6adf..9f4765d 100644
--- a/include/SPELL_EXC/SPELLcodeTreeLineIF.H
+++ b/include/SPELL_EXC/SPELLcodeTreeLineIF.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Code tree line interface definition
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLcodeTreeNode.H b/include/SPELL_EXC/SPELLcodeTreeNode.H
index 44b022c..69c3b97 100644
--- a/include/SPELL_EXC/SPELLcodeTreeNode.H
+++ b/include/SPELL_EXC/SPELLcodeTreeNode.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Code tree node implementation
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLcodeTreeNodeIF.H b/include/SPELL_EXC/SPELLcodeTreeNodeIF.H
index 112ef22..5f4422b 100644
--- a/include/SPELL_EXC/SPELLcodeTreeNodeIF.H
+++ b/include/SPELL_EXC/SPELLcodeTreeNodeIF.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Code tree node interface
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLcommand.H b/include/SPELL_EXC/SPELLcommand.H
index 13c9feb..e64423d 100644
--- a/include/SPELL_EXC/SPELLcommand.H
+++ b/include/SPELL_EXC/SPELLcommand.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Executor command definition
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -86,6 +86,8 @@ ExecutorCommand;
#define CMD_ACTION "CMD_ACTION"
/** Identifier for the FINISH command */
#define CMD_FINISH "CMD_FINISH"
+/** Identifier for the RESOURCE DISPLAY command */
+#define CMD_RESOURCES "CMD_RESOURCES"
/*@}*/
#endif
diff --git a/include/SPELL_EXC/SPELLcommandMailbox.H b/include/SPELL_EXC/SPELLcommandMailbox.H
index d45a9d5..c3c0c9c 100644
--- a/include/SPELL_EXC/SPELLcommandMailbox.H
+++ b/include/SPELL_EXC/SPELLcommandMailbox.H
@@ -6,7 +6,7 @@
// processing.
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLcontroller.H b/include/SPELL_EXC/SPELLcontroller.H
index 9d87f78..374057b 100644
--- a/include/SPELL_EXC/SPELLcontroller.H
+++ b/include/SPELL_EXC/SPELLcontroller.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Controls the command processing in a separate thread.
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -268,6 +268,12 @@ public: //--------------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
void removeControllerListener( SPELLcontrollerListener* listener );
+ void refreshStatus();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Inject a information event message to GCS
+ **////////////////////////////////////////////////////////////////////
+ void raiseInformationEventToGCS( const std::string& message );
// DATA MEMBERS //////////////////////////////////////////////////////////
protected: //-----------------------------------------------------------------
diff --git a/include/SPELL_EXC/SPELLcontrollerIF.H b/include/SPELL_EXC/SPELLcontrollerIF.H
index b863230..885c4a0 100644
--- a/include/SPELL_EXC/SPELLcontrollerIF.H
+++ b/include/SPELL_EXC/SPELLcontrollerIF.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Defines the controller interface.
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -253,6 +253,13 @@ public: //--------------------------------------------------------------------
/** Remove a controller listener
**////////////////////////////////////////////////////////////////////
virtual void removeControllerListener( SPELLcontrollerListener* listener ) {;};
+
+ virtual void refreshStatus() {;};
+
+ //////////////////////////////////////////////////////////////////////
+ /** Inject a information event message to GCS
+ **////////////////////////////////////////////////////////////////////
+ virtual void raiseInformationEventToGCS( const std::string& message ) = 0;
};
/*@}*/
diff --git a/include/SPELL_EXC/SPELLcontrollerListener.H b/include/SPELL_EXC/SPELLcontrollerListener.H
index 1fec2cb..d56caf5 100644
--- a/include/SPELL_EXC/SPELLcontrollerListener.H
+++ b/include/SPELL_EXC/SPELLcontrollerListener.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Controller listener interface
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLdispatchListener.H b/include/SPELL_EXC/SPELLdispatchListener.H
index 7c4a1cd..534a7bc 100644
--- a/include/SPELL_EXC/SPELLdispatchListener.H
+++ b/include/SPELL_EXC/SPELLdispatchListener.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Dispatch listener interface
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLexecutionMode.H b/include/SPELL_EXC/SPELLexecutionMode.H
index 7302303..7ec92f4 100644
--- a/include/SPELL_EXC/SPELLexecutionMode.H
+++ b/include/SPELL_EXC/SPELLexecutionMode.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Defines the diferent execution modes.
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLexecutionModel.H b/include/SPELL_EXC/SPELLexecutionModel.H
index af74db4..33f6708 100644
--- a/include/SPELL_EXC/SPELLexecutionModel.H
+++ b/include/SPELL_EXC/SPELLexecutionModel.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Composite of all models and analyzers associated to a given frame.
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLexecutionTrace.H b/include/SPELL_EXC/SPELLexecutionTrace.H
index c1cdb21..1036253 100644
--- a/include/SPELL_EXC/SPELLexecutionTrace.H
+++ b/include/SPELL_EXC/SPELLexecutionTrace.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Keeps trace of the visited and executed procedure lines.
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLexecutor.H b/include/SPELL_EXC/SPELLexecutor.H
index e7ccc45..225a30f 100644
--- a/include/SPELL_EXC/SPELLexecutor.H
+++ b/include/SPELL_EXC/SPELLexecutor.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Singleton factory for the executor
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -108,12 +108,17 @@ public: //--------------------------------------------------------------------
*
* \return The executor implementation instance.
**////////////////////////////////////////////////////////////////////
- static SPELLexecutorIF& instance()
+ static inline SPELLexecutorIF& instance()
{
assert(s_instance != NULL);
return *s_instance;
}
+ static inline bool isInitialized()
+ {
+ return s_instance != NULL;
+ }
+
//////////////////////////////////////////////////////////////////////
/** Set the executor instance
*
diff --git a/include/SPELL_EXC/SPELLexecutorConfiguration.H b/include/SPELL_EXC/SPELLexecutorConfiguration.H
index f7b4634..e0ca174 100644
--- a/include/SPELL_EXC/SPELLexecutorConfiguration.H
+++ b/include/SPELL_EXC/SPELLexecutorConfiguration.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Executor configuration parameters
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -218,7 +218,14 @@ public: //--------------------------------------------------------------------
bool isForceTcConfirm() const {
return m_forceTcConfirm;
};
-
+ //////////////////////////////////////////////////////////////////////
+ /** Obtain the force Prompt confirmation flag
+ *
+ * \returns The flag value
+ **////////////////////////////////////////////////////////////////////
+ bool isForcePromptConfirm() const {
+ return m_forcePromptConfirm;
+ };
//////////////////////////////////////////////////////////////////////
/** Obtain the executor condition.
*
@@ -256,6 +263,43 @@ public: //--------------------------------------------------------------------
};
+ //////////////////////////////////////////////////////////////////////
+ /** set resources display is enablement.
+ *
+ * \returns The status.
+ **////////////////////////////////////////////////////////////////////
+ void setResourcesDisplayEnabled( bool enabled ) {
+ m_resourcesDisplay = enabled;
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ /** Chekc if resource display is enabled or not.
+ *
+ * \returns The status.
+ **////////////////////////////////////////////////////////////////////
+ const bool isResourcesDisplayEnabled() const {
+ return m_resourcesDisplay;
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ /** Obtain the local resource support flag flag.
+ *
+ * \returns The flag value
+ **////////////////////////////////////////////////////////////////////
+ const bool isLocalResourcesSupported() const {
+ return m_localResourceSupport;
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ /** Set the local resource support flag.
+ *
+ * \param enabled IN: the flag value.
+ **////////////////////////////////////////////////////////////////////
+ void setLocalResourcesSupported( const bool enabled ) {
+ m_localResourceSupport = enabled;
+ };
+
+
//////////////////////////////////////////////////////////////////////
/** Set the run-into flag.
*
@@ -374,6 +418,9 @@ public: //--------------------------------------------------------------------
void setForceTcConfirm( bool force ) {
m_forceTcConfirm = force;
};
+ void setForcePromptConfirm( bool force ) {
+ m_forcePromptConfirm = force;
+ };
//////////////////////////////////////////////////////////////////////
/** Set the executor condition.
@@ -544,8 +591,11 @@ private: //-------------------------------------------------------------------
SPELLwsWorkingMode m_saveStateMode;
/** True if watch variables is enabled */
bool m_watchVariables;
+ /** True if resources display is enabled */
+ bool m_resourcesDisplay;
/** True if all TCs should be confirmed */
bool m_forceTcConfirm;
+ bool m_forcePromptConfirm;
/** Identifier of the controlling client if any */
std::string m_controlClient;
/** Host of the controlling GUI */
@@ -556,6 +606,8 @@ private: //-------------------------------------------------------------------
int m_maxVerbosity;
/** Context name */
std::string m_contextName;
+ /** Support for local resources flag */
+ bool m_localResourceSupport;
};
/*@}*/
diff --git a/include/SPELL_EXC/SPELLexecutorIF.H b/include/SPELL_EXC/SPELLexecutorIF.H
index c2bcc5c..9bb04ce 100644
--- a/include/SPELL_EXC/SPELLexecutorIF.H
+++ b/include/SPELL_EXC/SPELLexecutorIF.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Executor interface definition
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -38,6 +38,7 @@
#include "SPELL_EXC/SPELLcallstackIF.H"
#include "SPELL_EXC/SPELLbreakpointType.H"
#include "SPELL_EXC/SPELLvariableManager.H"
+#include "SPELL_EXC/SPELLresourceManager.H"
#include "SPELL_EXC/SPELLdispatchListener.H"
@@ -136,6 +137,7 @@ public: //--------------------------------------------------------------------
* \returns The controller reference
**////////////////////////////////////////////////////////////////////
virtual SPELLcontrollerIF& getController() const = 0;
+ virtual bool hasController() const { return true;};
//////////////////////////////////////////////////////////////////////
/** Obtain the scheduler reference
@@ -156,7 +158,7 @@ public: //--------------------------------------------------------------------
*
* \returns The configuration object.
**////////////////////////////////////////////////////////////////////
- virtual SPELLexecutorConfig& getConfiguration() const = 0;
+ virtual SPELLexecutorConfig& getConfiguration() = 0;
//////////////////////////////////////////////////////////////////////
/** Obtain variable manager.
@@ -165,6 +167,13 @@ public: //--------------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
virtual SPELLvariableManager& getVariableManager() const = 0;
+ //////////////////////////////////////////////////////////////////////
+ /** Obtain resource manager.
+ *
+ * \returns The resource manager object.
+ **////////////////////////////////////////////////////////////////////
+ virtual SPELLresourceManager& getResourceManager() const = 0;
+
//////////////////////////////////////////////////////////////////////
/** Obtain execution frame.
*
@@ -374,7 +383,7 @@ public: //--------------------------------------------------------------------
* \param force IN: the flag value
**////////////////////////////////////////////////////////////////////
virtual void setForceTcConfirm( const bool force ) = 0;
-
+ virtual void setForcePromptConfirm( const bool force ) = 0;
// *******************************************************************
// LANGUAGE INTERLOCK
// *******************************************************************
@@ -515,6 +524,7 @@ public: //--------------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
virtual void displayStage( const std::string& id, const std::string& title ) = 0;
+ virtual void refreshStatus() {;};
};
/*@}*/
diff --git a/include/SPELL_EXC/SPELLexecutorImpl.H b/include/SPELL_EXC/SPELLexecutorImpl.H
index 0e62777..2a34ee4 100644
--- a/include/SPELL_EXC/SPELLexecutorImpl.H
+++ b/include/SPELL_EXC/SPELLexecutorImpl.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the Executor.
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -113,6 +113,7 @@ public: //--------------------------------------------------------------------
/** \see SPELLexecutorIF.
**////////////////////////////////////////////////////////////////////
SPELLcontrollerIF& getController() const { return *m_controller; };
+ bool hasController() const { return m_controller != NULL; };
//////////////////////////////////////////////////////////////////////
/** \see SPELLexecutorIF.
@@ -127,13 +128,18 @@ public: //--------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////
/** \see SPELLexecutorIF.
**////////////////////////////////////////////////////////////////////
- SPELLexecutorConfig& getConfiguration() const;
+ SPELLexecutorConfig& getConfiguration();
//////////////////////////////////////////////////////////////////////
/** \see SPELLexecutorIF.
**////////////////////////////////////////////////////////////////////
SPELLvariableManager& getVariableManager() const { return *m_varManager; };
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ SPELLresourceManager& getResourceManager() const { return *m_resourceManager; };
+
//////////////////////////////////////////////////////////////////////
/** \see SPELLexecutorIF.
**////////////////////////////////////////////////////////////////////
@@ -286,7 +292,7 @@ public: //--------------------------------------------------------------------
/** \see SPELLexecutorIF.
**////////////////////////////////////////////////////////////////////
void setForceTcConfirm( const bool force );
-
+ void setForcePromptConfirm( const bool force );
// *******************************************************************
// LANGUAGE INTERLOCK
// *******************************************************************
@@ -377,6 +383,7 @@ public: //--------------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
void displayStage( const std::string& id, const std::string& title );
+ void refreshStatus();
// DATA MEMBERS //////////////////////////////////////////////////////////
protected: //-----------------------------------------------------------------
@@ -524,9 +531,12 @@ private: //-------------------------------------------------------------------
/** Change the force TC flag on the adapter layer
**////////////////////////////////////////////////////////////////////
void setForceTcConfirmInternal( bool force );
+ void setForcePromptConfirmInternal( bool force );
// DATA MEMBERS //////////////////////////////////////////////////////////
+ /** Empty configuration */
+ SPELLexecutorConfig m_emptyConfig;
/** True if the initial configuration parameters have been set */
bool m_initialized;
/** Holds the procedure instance identifier */
@@ -570,6 +580,8 @@ private: //-------------------------------------------------------------------
SPELLimportChecker m_importChecker;
/** Holds the variable manager */
SPELLvariableManager* m_varManager;
+ /** Holds the resource manager */
+ SPELLresourceManager* m_resourceManager;
/** Command synchronization lock */
SPELLmutex m_cmdLock;
diff --git a/include/SPELL_EXC/SPELLexecutorStatus.H b/include/SPELL_EXC/SPELLexecutorStatus.H
index 711ae6b..14f161e 100644
--- a/include/SPELL_EXC/SPELLexecutorStatus.H
+++ b/include/SPELL_EXC/SPELLexecutorStatus.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Executor status definition
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLexecutorUtils.H b/include/SPELL_EXC/SPELLexecutorUtils.H
index a78ecc2..bf63ccc 100644
--- a/include/SPELL_EXC/SPELLexecutorUtils.H
+++ b/include/SPELL_EXC/SPELLexecutorUtils.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Executor utilities
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLframeManager.H b/include/SPELL_EXC/SPELLframeManager.H
index f186e69..6567268 100644
--- a/include/SPELL_EXC/SPELLframeManager.H
+++ b/include/SPELL_EXC/SPELLframeManager.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Operations in relation with the current Python frame (runtime)
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -30,6 +30,7 @@
// FILES TO INCLUDE ////////////////////////////////////////////////////////
// Local includes ----------------------------------------------------------
#include "SPELL_EXC/SPELLexecutionModel.H"
+#include "SPELL_EXC/SPELLresourceMonitor.H"
#include "SPELL_EXC/SPELLexecutionTrace.H"
#include "SPELL_EXC/SPELLcallstackIF.H"
#include "SPELL_EXC/SPELLbreakpoint.H"
@@ -94,7 +95,7 @@ public: //--------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////
/** Destructor.
**////////////////////////////////////////////////////////////////////
- ~SPELLframeManager();
+ virtual ~SPELLframeManager();
// METHODS ///////////////////////////////////////////////////////////////
@@ -130,6 +131,13 @@ public: //--------------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
SPELLexecutionModel& getModel( const std::string& code_id );
+ //////////////////////////////////////////////////////////////////////
+ /** Get the resources monitor.
+ *
+ * \return Reference to the resources monitor.
+ **////////////////////////////////////////////////////////////////////
+ SPELLresourceMonitor& getResourceMonitor() { return m_resourceMonitor; };
+
//////////////////////////////////////////////////////////////////////
/** Replay the frame structure in the given stack
**////////////////////////////////////////////////////////////////////
@@ -332,7 +340,7 @@ protected: //-------------------------------------------------------------------
// METHODS ///////////////////////////////////////////////////////////////
private: //-------------------------------------------------------------------
-
+ friend class SPELLserviceFrameManager;
// EXCEPTIONS ////////////////////////////////////////////////////////////
// ENUMS /////////////////////////////////////////////////////////////////
// TYPES /////////////////////////////////////////////////////////////////
@@ -356,7 +364,7 @@ private: //-------------------------------------------------------------------
* \throws SPELLcoreException if the file cannot be found, or the
* compilation fails.
**////////////////////////////////////////////////////////////////////
- void compile();
+ virtual void compile();
//////////////////////////////////////////////////////////////////////
/** Compile the given script and obtain the bytecode.
@@ -368,7 +376,7 @@ private: //-------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////
/** Create initial frame out of the current code
**////////////////////////////////////////////////////////////////////
- void createInitialFrame();
+ virtual void createInitialFrame();
//////////////////////////////////////////////////////////////////////
/** Create frame model for a new frame
@@ -401,7 +409,7 @@ private: //-------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////
/** Update data for watch of variables when a new frame arrives
**////////////////////////////////////////////////////////////////////
- void updateVariables( PyFrameObject* frame );
+ virtual void updateVariables( PyFrameObject* frame );
//////////////////////////////////////////////////////////////////////
/** Update SPELL builtins using the given frames
@@ -435,6 +443,8 @@ private: //-------------------------------------------------------------------
PyObject* m_definitions;
/** Holds the currently active execution model */
SPELLexecutionModel* m_model;
+ /** Monitor of resources */
+ SPELLresourceMonitor m_resourceMonitor;
/** Holds the AST analyzer */
SPELLastAnalyzer m_ast;
/** Map of model objects per code object */
diff --git a/include/SPELL_EXC/SPELLgoto.H b/include/SPELL_EXC/SPELLgoto.H
index af804a7..b826750 100644
--- a/include/SPELL_EXC/SPELLgoto.H
+++ b/include/SPELL_EXC/SPELLgoto.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the Goto mechanism
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLimportChecker.H b/include/SPELL_EXC/SPELLimportChecker.H
index 143f084..782d01e 100644
--- a/include/SPELL_EXC/SPELLimportChecker.H
+++ b/include/SPELL_EXC/SPELLimportChecker.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Special check for import statements
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLinterpreter.H b/include/SPELL_EXC/SPELLinterpreter.H
index 15e13fe..0f796a8 100644
--- a/include/SPELL_EXC/SPELLinterpreter.H
+++ b/include/SPELL_EXC/SPELLinterpreter.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Main entry point of the executor.
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLlnotab.H b/include/SPELL_EXC/SPELLlnotab.H
index 3177db1..1709abb 100644
--- a/include/SPELL_EXC/SPELLlnotab.H
+++ b/include/SPELL_EXC/SPELLlnotab.H
@@ -5,7 +5,7 @@
// DESCRIPTION: LNotab analyzer.
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLresourceInfo.H b/include/SPELL_EXC/SPELLresourceInfo.H
new file mode 100644
index 0000000..56e0956
--- /dev/null
+++ b/include/SPELL_EXC/SPELLresourceInfo.H
@@ -0,0 +1,115 @@
+// ################################################################################
+// FILE : SPELLresourceInfo.H
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Procedure resource information
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+#ifndef __SPELL_RESOURCE_INFO_H__
+#define __SPELL_RESOURCE_INFO_H__
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// Local includes ----------------------------------------------------------
+// Project includes --------------------------------------------------------
+#include "SPELL_UTIL/SPELLbase.H"
+
+/** \addtogroup SPELL_EXC */
+/*@{*/
+
+
+// FORWARD REFERENCES //////////////////////////////////////////////////////
+// TYPES ///////////////////////////////////////////////////////////////////
+// DEFINES /////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+/**
+ ** \brief Resource information
+ **
+**////////////////////////////////////////////////////////////////////////////
+typedef struct SPELLresourceInfo_
+{
+ SPELLresourceInfo_()
+ {
+ resourceName = "";
+ resourceType = "";
+ resourceGlobalValue = "";
+ resourceLocalValue = "";
+ resourceValueRange.clear();
+ resourceGCSName = "";
+ }
+
+ SPELLresourceInfo_( const std::string& name,
+ const std::string& type,
+ const std::string& globalValue,
+ const std::string& localValue,
+ const std::vector >& valueRange,
+ const std::string& gcsName )
+ {
+ resourceName = name;
+ resourceType = type;
+ resourceGlobalValue = globalValue;
+ resourceLocalValue = localValue;
+ resourceValueRange.assign(valueRange.begin(), valueRange.end());
+ resourceGCSName = gcsName;
+ }
+
+ SPELLresourceInfo_& operator=( const SPELLresourceInfo_& other )
+ {
+ if (this != &other)
+ {
+ resourceName = other.resourceName;
+ resourceType = other.resourceType;
+ resourceGlobalValue = other.resourceGlobalValue;
+ resourceLocalValue = other.resourceLocalValue;
+ resourceValueRange.assign(other.resourceValueRange.begin(), other.resourceValueRange.end());
+ resourceGCSName = other.resourceGCSName;
+ }
+ return *this;
+ }
+
+ SPELLresourceInfo_( const SPELLresourceInfo_& other )
+ {
+ resourceName = other.resourceName;
+ resourceType = other.resourceType;
+ resourceGlobalValue = other.resourceGlobalValue;
+ resourceLocalValue = other.resourceLocalValue;
+ resourceValueRange.assign(other.resourceValueRange.begin(), other.resourceValueRange.end());
+ resourceGCSName = other.resourceGCSName;
+ }
+
+ /** Holds the resource name */
+ std::string resourceName;
+ /** Holds the resource type string */
+ std::string resourceType;
+ /** Holds the resource global value */
+ std::string resourceGlobalValue;
+ /** Holds the resource local value */
+ std::string resourceLocalValue;
+ /** List of values that the resource can have. Empty means any value */
+ std::vector > resourceValueRange;
+ /** Holds the resource GCS name */
+ std::string resourceGCSName;
+}
+SPELLresourceInfo;
+
+/*@}*/
+#endif
diff --git a/include/SPELL_EXC/SPELLresourceManager.H b/include/SPELL_EXC/SPELLresourceManager.H
new file mode 100644
index 0000000..5cf6d36
--- /dev/null
+++ b/include/SPELL_EXC/SPELLresourceManager.H
@@ -0,0 +1,147 @@
+// ################################################################################
+// FILE : SPELLresourceManager.H
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Manager of procedure runtime resources
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+#ifndef __SPELL_RESOURCE_MANAGER_H__
+#define __SPELL_RESOURCE_MANAGER_H__
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// System includes ---------------------------------------------------------
+// Local includes ----------------------------------------------------------
+#include "SPELL_EXC/SPELLframeManager.H"
+// Project includes --------------------------------------------------------
+#include "SPELL_SYN/SPELLqueue.H"
+
+/** \addtogroup SPELL_EXC */
+/*@{*/
+
+
+// FORWARD REFERENCES //////////////////////////////////////////////////////
+// TYPES ///////////////////////////////////////////////////////////////////
+// DEFINES /////////////////////////////////////////////////////////////////
+
+#define RESOURCE_MONITOR_CHANGE_RESOURCE "changeResource"
+#define RESOURCE_MONITOR_GET_RESOURCES "getResources"
+
+//////////////////////////////////////////////////////////////////////////////
+/**
+ ** \brief Resource manager
+ **
+**////////////////////////////////////////////////////////////////////////////
+class SPELLresourceManager
+{
+public: //--------------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Constructor.
+ **////////////////////////////////////////////////////////////////////
+ SPELLresourceManager( SPELLframeManager& frameManager );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Destructor.
+ **////////////////////////////////////////////////////////////////////
+ ~SPELLresourceManager();
+
+ // STATIC ////////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Enable or disable the manager.
+ **////////////////////////////////////////////////////////////////////
+ void setEnabled( bool enabled );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Check enabled
+ **////////////////////////////////////////////////////////////////////
+ bool isEnabled();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Analysis on demand
+ **////////////////////////////////////////////////////////////////////
+ void analyze();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Get available resources.
+ *
+ * \return The list of resources.
+ **////////////////////////////////////////////////////////////////////
+ void getResources();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Change a resource value.
+ *
+ * \param resource IN: the resource data.
+ *
+ **////////////////////////////////////////////////////////////////////
+ void changeResource( SPELLresourceInfo& resource );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Check if the internal executor status is valid to process
+ * resource manipulation.
+ *
+ * \returns True if the status is valid.
+ **////////////////////////////////////////////////////////////////////
+ bool isStatusValid();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Call resource monitor method.
+ *
+ * \param moitorTask IN: name of the method to call.
+ *
+ **////////////////////////////////////////////////////////////////////
+ void callResourceMonitorFromClient(std::string monitorTask);
+
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+
+protected: //-----------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+
+private: //-------------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+ /** Holds reference to the frame manager */
+ SPELLframeManager& m_frameManager;
+ /** Queue to store resources to change */
+ SPELLqueue m_changeResourceQueue;
+};
+
+/*@}*/
+#endif
diff --git a/include/SPELL_EXC/SPELLresourceMonitor.H b/include/SPELL_EXC/SPELLresourceMonitor.H
new file mode 100644
index 0000000..b924b4d
--- /dev/null
+++ b/include/SPELL_EXC/SPELLresourceMonitor.H
@@ -0,0 +1,199 @@
+// ################################################################################
+// FILE : SPELLresourceMonitor.H
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Monitor for runtime procedure resources
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+#ifndef __SPELL_RESOURCE_MONITOR_H__
+#define __SPELL_RESOURCE_MONITOR_H__
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// System includes ---------------------------------------------------------
+// Local includes ----------------------------------------------------------
+#include "SPELL_EXC/SPELLresourceInfo.H"
+// Project includes --------------------------------------------------------
+#include "SPELL_UTIL/SPELLbase.H"
+
+/** \addtogroup SPELL_EXC */
+/*@{*/
+
+
+// FORWARD REFERENCES //////////////////////////////////////////////////////
+// TYPES ///////////////////////////////////////////////////////////////////
+// DEFINES /////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+/**
+ ** \brief Listener for resource changes.
+ **
+**////////////////////////////////////////////////////////////////////////////
+class SPELLresourceChangeListener
+{
+public:
+
+ //////////////////////////////////////////////////////////////////////
+ /** Notify about a resource change.
+ *
+ * \param changed IN: list of changed resources.
+ *
+ **////////////////////////////////////////////////////////////////////
+ void resourceChanged( const std::vector& changed );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Notify about a resource list.
+ *
+ * \param changed IN: list of resources.
+ *
+ **////////////////////////////////////////////////////////////////////
+ void resourceList( const std::vector& resources );
+};
+
+//////////////////////////////////////////////////////////////////////////////
+/**
+ ** \brief Monitor of resources
+ **
+ ** \par Description and usage:
+ **
+ ** Used to implement the display-of-resurces mechanism
+ **
+**////////////////////////////////////////////////////////////////////////////
+class SPELLresourceMonitor: public SPELLresourceChangeListener
+{
+public: //--------------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+
+ /** Type for resource name-value map */
+ typedef std::map ResourceMap;
+
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Constructor.
+ **////////////////////////////////////////////////////////////////////
+ SPELLresourceMonitor( SPELLresourceChangeListener* listener );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Destructor.
+ **////////////////////////////////////////////////////////////////////
+ ~SPELLresourceMonitor();
+
+ // STATIC ////////////////////////////////////////////////////////////////
+
+ static bool s_enabled;
+
+ // METHODS ///////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Get available resources.
+ *
+ * \return The list of resources.
+ **////////////////////////////////////////////////////////////////////
+ void getResources();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Change resource
+ *
+ * \param resource IN: the resource to change.
+ *
+ **////////////////////////////////////////////////////////////////////
+ void changeResource( SPELLresourceInfo& resource );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Get resource value.
+ *
+ * \param resourceName IN: resource name
+ *
+ * \return The resource information.
+ **////////////////////////////////////////////////////////////////////
+ void getResource( SPELLresourceInfo& resource );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Analyze resource dictionary to detect changes.
+ **////////////////////////////////////////////////////////////////////
+ void analyze();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Initialize the resource dictionary
+ **////////////////////////////////////////////////////////////////////
+ void initialize();
+
+protected: //-----------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+
+private: //-------------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Retrieve existing resources, local or global
+ * \param resultingMap OUT: map of resource information to fill.
+ * \param isLocal IN: whether to retrieve local resources (true) or global (false).
+ * \param onlyLocal IN: whether to ONLY retrieve the values of local resources
+ * Neither the type, global value or ValueRange are retrieved
+ *
+ **////////////////////////////////////////////////////////////////////
+ void retrieveResources( ResourceMap &resultingMap, bool onlyLocal=false );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Retrieve resource value range and name map
+ **////////////////////////////////////////////////////////////////////
+ void retrieveResourceValueRangeAndNameMap( );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Check if a resource should not be monitored
+ **////////////////////////////////////////////////////////////////////
+ bool shouldDiscard( const std::string& name );
+
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+
+ /** Reference to the frame */
+ PyFrameObject* m_frame;
+ /** Scope name */
+ std::string m_scopeName;
+ /** Initialized flag */
+ bool m_initialized;
+ /** Reference to the single change listener */
+ SPELLresourceChangeListener* m_listener;
+ /** Map of resources */
+ ResourceMap m_resources;
+ /** Resources accepted values */
+ std::map > > m_resourceAcceptedValues;
+ /** Resources SPELL/GCS name mapping */
+ std::map m_resourceNameMapping;
+};
+
+/*@}*/
+#endif
diff --git a/include/SPELL_EXC/SPELLscheduleCondition.H b/include/SPELL_EXC/SPELLscheduleCondition.H
index 3ff3d93..86b7487 100644
--- a/include/SPELL_EXC/SPELLscheduleCondition.H
+++ b/include/SPELL_EXC/SPELLscheduleCondition.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Defines a scheduler condition
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -92,6 +92,7 @@ public: //--------------------------------------------------------------------
period.set(0,0,false);
message = "";
m_tmVerificationExpression = NULL;
+ promptUser = false;
}
//////////////////////////////////////////////////////////////////////
diff --git a/include/SPELL_EXC/SPELLscheduler.H b/include/SPELL_EXC/SPELLscheduler.H
index 841e858..ab1881a 100644
--- a/include/SPELL_EXC/SPELLscheduler.H
+++ b/include/SPELL_EXC/SPELLscheduler.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the executor scheduler.
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -163,6 +163,11 @@ public: //--------------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
void setPromptWarningDelay( unsigned int secs );
+ //////////////////////////////////////////////////////////////////////
+ /** Inject a warning event message to GCS
+ **////////////////////////////////////////////////////////////////////
+ void raiseWarningEventToGCS( const std::string& message );
+
// DATA MEMBERS //////////////////////////////////////////////////////////
protected: //-----------------------------------------------------------------
@@ -188,6 +193,11 @@ private: //-------------------------------------------------------------------
// LIFECYCLE /////////////////////////////////////////////////////////////
// METHODS ///////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////
+ /** Finish a wait condition (no check lock)
+ **////////////////////////////////////////////////////////////////////
+ void finishWaitInternal( bool setStatus, bool keepLock );
+
//////////////////////////////////////////////////////////////////////
/** Release the lock which may be blocking procedure execution
**////////////////////////////////////////////////////////////////////
diff --git a/include/SPELL_EXC/SPELLschedulerIF.H b/include/SPELL_EXC/SPELLschedulerIF.H
index 507df79..74df657 100644
--- a/include/SPELL_EXC/SPELLschedulerIF.H
+++ b/include/SPELL_EXC/SPELLschedulerIF.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Defines the interface of the executor scheduler
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -172,6 +172,11 @@ public: //--------------------------------------------------------------------
/** Set default delay for prompt warnings
**////////////////////////////////////////////////////////////////////
virtual void setPromptWarningDelay( unsigned int secs ) = 0;
+
+ //////////////////////////////////////////////////////////////////////
+ /** Inject a warning event message to GCS
+ **////////////////////////////////////////////////////////////////////
+ virtual void raiseWarningEventToGCS( const std::string& message ) = 0;
};
/*@}*/
diff --git a/include/SPELL_EXC/SPELLserviceImpl.H b/include/SPELL_EXC/SPELLserviceImpl.H
new file mode 100644
index 0000000..7061d69
--- /dev/null
+++ b/include/SPELL_EXC/SPELLserviceImpl.H
@@ -0,0 +1,599 @@
+// ################################################################################
+// FILE : SPELLexecutorImpl.H
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Implementation of the Executor.
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+#ifndef __SPELL_SERVICE_IMPL_H__
+#define __SPELL_SERVICE_IMPL_H__
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// Local includes ----------------------------------------------------------
+#include "SPELL_EXC/SPELLexecutorIF.H"
+#include "SPELL_EXC/SPELLimportChecker.H"
+#include "SPELL_EXC/SPELLbreakpointType.H"
+// Project includes --------------------------------------------------------
+#include "SPELL_CFG/SPELLbrowsableLibMode.H"
+// System includes ---------------------------------------------------------
+
+
+/** \addtogroup SPELL_EXC */
+/*@{*/
+
+
+// FORWARD REFERENCES //////////////////////////////////////////////////////
+// TYPES ///////////////////////////////////////////////////////////////////
+// DEFINES /////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+/**
+ ** \brief Main implementation of the procedure executor
+ **
+ ** \par Description and usage:
+ **
+ ** Main implementation of the SPELLexecutorIF interface for the SPELL
+ ** Executor process.
+ **
+**////////////////////////////////////////////////////////////////////////////
+class SPELLserviceImpl: public SPELLexecutorIF
+{
+public: //--------------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Constructor
+ **////////////////////////////////////////////////////////////////////
+ SPELLserviceImpl();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Destructor.
+ **////////////////////////////////////////////////////////////////////
+ virtual ~SPELLserviceImpl();
+
+ // STATIC ////////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+
+ // *******************************************************************
+ // INITIALIZATION
+ // *******************************************************************
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void initialize( SPELLcif* cif,
+ SPELLcontrollerIF* controller,
+ SPELLschedulerIF* scheduler,
+ SPELLcallstackIF* callstack,
+ SPELLframeManager* frameManager );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void prepare( const std::string& serviceId, const SPELLcontextConfig& ctxConfig );
+
+ // *******************************************************************
+ // COMPONENT ACCESSORS
+ // *******************************************************************
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ SPELLcif& getCIF() const { return *m_cif; };
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ SPELLcallstackIF& getCallstack() const { return *m_callstack; };
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ SPELLcontrollerIF& getController() const { return *m_controller; };
+ bool hasController() const { return m_controller != NULL; };
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ SPELLschedulerIF& getScheduler() const { return *m_scheduler; };
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ SPELLchildManager& getChildManager() const { return *m_childMgr; };
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ SPELLexecutorConfig& getConfiguration();
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ SPELLvariableManager& getVariableManager() const { return *m_varManager; };
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ SPELLresourceManager& getResourceManager() const { return *m_resourceManager; };
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ SPELLframeManager& getFrameManager() const { return *m_frameManager; };
+
+ // *******************************************************************
+ // EXECUTION ENTRY POINTS
+ // *******************************************************************
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void execute();
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void recover();
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void finalize();
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void save();
+
+ // *******************************************************************
+ // MAIN EXECUTION CONTROL
+ // *******************************************************************
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void addDispatchListener( SPELLdispatchListener* listener );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void removeDispatchListener( SPELLdispatchListener* listener );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ int dispatch( PyObject* obj, PyFrameObject* frame, int what, PyObject* args );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void command( const ExecutorCommand& cmd, const bool high_priority );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void abort( const std::string& message, bool systemAborted );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void finish( const std::string& message );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void pause();
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void interrupt();
+
+ // *******************************************************************
+ // STATUS INFORMATION
+ // *******************************************************************
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ const SPELLexecutorStatus getStatus() const;
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ const std::string getContextName() const;
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ const std::string getInstanceId() const;
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void setControllingClient( const std::string& clientId );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void setControllingHost( const std::string& hostName );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ const std::string getControllingHost() const;
+
+ // *******************************************************************
+ // EXECUTION CONFIGURATION PARAMETERS
+ // *******************************************************************
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void setProcedurePath( const std::string& servicePath ) { m_servicePath = servicePath; };
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void setLibraryPath( const std::string& libPath ) { m_libPath = libPath; };
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void setRunInto( const bool enabled );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void setByStep( const bool enabled );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void setBrowsableLib( const SPELLbrowsableLibMode& browsableLib );
+
+ void setBrowsableLibStr( const std::string& browsableLibStr );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void setExecDelay( const int delay );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void setPromptWarningDelay( const int delay );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void setForceTcConfirm( const bool force );
+ void setForcePromptConfirm( const bool force );
+ // *******************************************************************
+ // LANGUAGE INTERLOCK
+ // *******************************************************************
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void processLock();
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void processUnlock();
+
+ // *******************************************************************
+ // EXECUTION MANIPULATION
+ // *******************************************************************
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ const bool canSkip();
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ const bool goNextLine();
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ const bool goLabel( const std::string& label, bool programmed );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ const bool goLine( const int line );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ const bool setBreakpoint( const std::string& file,
+ const unsigned int line,
+ const SPELLbreakpointType type );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void clearBreakpoints();
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ const bool runScript( const std::string& script );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void executeUserAction();
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void setUserAction( const SPELLuserAction& action );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void enableUserAction( const bool enable );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void dismissUserAction();
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ const SPELLuserAction getUserAction() const { return m_userAction; };
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void stageReached( const std::string& id, const std::string& title );
+
+ //////////////////////////////////////////////////////////////////////
+ /** \see SPELLexecutorIF.
+ **////////////////////////////////////////////////////////////////////
+ void displayStage( const std::string& id, const std::string& title );
+
+ void refreshStatus();
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+
+protected: //-----------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ /** Identifies the status after an error recovery */
+ typedef enum AfterError_
+ {
+ CANNOT_RECOVER, // Will not recover because there is no ws support
+ CANCEL_RECOVER, // Will not recover because the user does not want
+ RECOVER_SUCCESS,// Recovery ok
+ RECOVER_FAILED // Recovery failed
+ }
+ AfterError;
+ // TYPES /////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Listener notifications
+ **////////////////////////////////////////////////////////////////////
+ void notifyLineEvent( PyFrameObject* frame, const std::string& file, const int line, const std::string& name );
+ void notifyCallEvent( PyFrameObject* frame, const std::string& file, const int line, const std::string& name );
+ void notifyReturnEvent( PyFrameObject* frame, const std::string& file, const int line, const std::string& name );
+ void notifyErrorEvent( PyFrameObject* frame, const std::string& file, const int line, const std::string& name );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Process a dispatched exception
+ *
+ * \return True if the dispatch processing shall not continue
+ **////////////////////////////////////////////////////////////////////
+ bool processException( PyObject* data, int lineno );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Internal implementation of the execute() method
+ **////////////////////////////////////////////////////////////////////
+ void executeInternal( bool reset );
+
+ //////////////////////////////////////////////////////////////////////
+ /** By-Step implementation. If the feature is enabled and the current
+ * procedure line is a Step, pause the execution.
+ *
+ * \param frameLine IN: the current line in the procedure.
+ **////////////////////////////////////////////////////////////////////
+ const bool checkByStep( const int& frameLine );
+
+ //////////////////////////////////////////////////////////////////////
+ /** INIT step feature checker
+ *
+ * \param frameLine IN: the current line in the procedure.
+ *
+ * \returns True if the dispatching shall be aborted and control
+ * returned to Python side immediately.
+ **////////////////////////////////////////////////////////////////////
+ const bool checkInitStep( const int& frameLine );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Breakpoint checker. If a breakpoint is set, pause the execution.
+ *
+ * \param file IN: current file name.
+ * \param lineNo IN: the current line in the procedure.
+ *
+ **////////////////////////////////////////////////////////////////////
+ void checkBreakpoint( const std::string& file, unsigned int lineNo );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Error recovery implementation
+ *
+ * \returns True if the error can be recovered
+ **////////////////////////////////////////////////////////////////////
+ const AfterError handleExecutionError();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Load execution environment data and instances
+ **////////////////////////////////////////////////////////////////////
+ void loadExecutionEnvironment();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Load SPELL driver
+ **////////////////////////////////////////////////////////////////////
+ void loadDriver();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Unload SPELL driver.
+ *
+ * \param shutdown IN: If true, unload completely all data. If false,
+ * just cleanup the driver, but do not remove it completely (this
+ * is handled on driver side, not in executor)
+ **////////////////////////////////////////////////////////////////////
+ void unloadDriver( bool shutdown );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Called when the execution finishes with errors. The behavior
+ * depends on the recovery mechanism status and user's choice.
+ *
+ * \return True if the execution shall be started over.
+ **////////////////////////////////////////////////////////////////////
+ bool executorFinishedWithErrors();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Called when the execution finishes sucessfully. The behavior
+ * depends on the user's choice.
+ *
+ * \return True if the execution shall be started over.
+ **////////////////////////////////////////////////////////////////////
+ bool executorFinishedRight();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Called when the execution is aborted. The behavior
+ * depends on the user's choice.
+ *
+ * \return True if the execution shall be started over.
+ **////////////////////////////////////////////////////////////////////
+ bool executorAborted();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Waits for the user's choice: close the procedure or reload it.
+ *
+ * \return True if the execution shall be started over.
+ **////////////////////////////////////////////////////////////////////
+ bool reloadOrClose();
+
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+
+private: //-------------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Install the calling arguments data container on the main scope.
+ **////////////////////////////////////////////////////////////////////
+ void installCallingArguments();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Install the internal variables data container on the main scope.
+ **////////////////////////////////////////////////////////////////////
+ void installInternalVariables();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Change the force TC flag on the adapter layer
+ **////////////////////////////////////////////////////////////////////
+ void setForceTcConfirmInternal( bool force );
+ void setForcePromptConfirmInternal( bool force );
+
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+
+ /** Empty configuration */
+ SPELLexecutorConfig m_emptyConfig;
+ /** True if the initial configuration parameters have been set */
+ bool m_initialized;
+ /** Holds the procedure instance identifier */
+ std::string m_instanceId;
+ /** Holds the parent procedure, if any */
+
+ std::string m_parentId;
+ /** Holds the child procedure, if any */
+ std::string m_childId;
+
+ /** Used for dispatching filter (procedures) */
+ std::string m_servicePath;
+ /** Used for dispatching filter (user library) */
+ std::string m_libPath;
+ /** Output directory location */
+ std::string m_outputDir;
+ /** Input directory location */
+ std::string m_inputDir;
+
+ /** True when the INIT step, if any, has been reached */
+ bool m_initStepDone;
+ /** Holds the lines in the main procedure that are executed during INIT mode */
+ std::list m_initLines;
+
+ /** Holds the user action data if any */
+ SPELLuserAction m_userAction;
+
+ /** Holds the command controller */
+ SPELLcontrollerIF* m_controller;
+ /** Holds the scheduler controller */
+ SPELLschedulerIF* m_scheduler;
+ /** Holds the callstack model */
+ SPELLcallstackIF* m_callstack;
+ /** Holds the reference to client interface */
+ SPELLcif* m_cif;
+ /** Holds the child procedure manager */
+ SPELLchildManager* m_childMgr;
+ /** Holds the execution control frame */
+ SPELLframeManager* m_frameManager;
+ /** Holds the module import checker */
+ SPELLimportChecker m_importChecker;
+ /** Holds the variable manager */
+ SPELLvariableManager* m_varManager;
+ /** Holds the resource manager */
+ SPELLresourceManager* m_resourceManager;
+
+ /** Command synchronization lock */
+ SPELLmutex m_cmdLock;
+ /** Dispatch synchronization lock */
+ SPELLmutex m_dspLock;
+
+ /** Next programmed goto target */
+ std::string m_gotoTarget;
+
+ /** Dispatch event listeners */
+ SPELLdispatchListeners m_listeners;
+};
+
+/*@}*/
+#endif
diff --git a/include/SPELL_EXC/SPELLserviceInterpreter.H b/include/SPELL_EXC/SPELLserviceInterpreter.H
new file mode 100644
index 0000000..91d0d61
--- /dev/null
+++ b/include/SPELL_EXC/SPELLserviceInterpreter.H
@@ -0,0 +1,249 @@
+// ################################################################################
+// FILE : SPELLinterpreter.H
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Main entry point of the executor.
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+#ifndef __SPELL_SERVICE_INTERPRETER_H__
+#define __SPELL_SERVICE_INTERPRETER_H__
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// Local includes ----------------------------------------------------------
+#include "SPELL_EXC/SPELLexecutorIF.H"
+#include "SPELL_EXC/SPELLserviceImpl.H"
+#include "SPELL_EXC/SPELLframeManager.H"
+// Project includes --------------------------------------------------------
+// System includes ---------------------------------------------------------
+
+
+/** \addtogroup SPELL_EXC */
+/*@{*/
+
+// FORWARD REFERENCES //////////////////////////////////////////////////////
+// ENUMS ///////////////////////////////////////////////////////////////////
+// TYPES ///////////////////////////////////////////////////////////////////
+
+/** Configuration parameters for the interpreter */
+typedef struct SPELLinterpreterConfig_
+{
+ /** If true, WS is enabled and the given persistent file is used */
+ bool warmstart;
+ /** If true, the given persistent file is used to recover status */
+ bool recover;
+ /** If true, the given procId corresponds to a script, not a proc id */
+ bool script;
+ /** Path to main configuration file */
+ std::string configFile;
+ /** Procedure identifier or script path */
+ std::string procId;
+ /** SPELL context to be used */
+ std::string ctxName;
+ /** Context listening port */
+ int ctxPort;
+ /** Time string to be used in generated files */
+ std::string timeId;
+ /** If given, holds the path to the file where WS data is stored */
+ std::string persis;
+}
+SPELLinterpreterConfig;
+
+// DEFINES /////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+/**
+ ** \brief Encapsulates the Python interpreter framework in a single object.
+ **
+ ** \par Description and usage:
+ **
+ ** The interpreter is the main class of the executor
+ ** process. It creates all the pieces needed to execute a given script
+ ** or procedure. It provides also the ability of recovering a proc
+ ** execution by using a given WS information file.
+ **
+ ** Singleton used in the main program function.
+ **
+**////////////////////////////////////////////////////////////////////////////
+class SPELLserviceInterpreter
+{
+public: //--------------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Destructor.
+ **////////////////////////////////////////////////////////////////////
+ ~SPELLserviceInterpreter();
+
+ // STATIC ////////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Access to the singleton instance
+ **////////////////////////////////////////////////////////////////////
+ static SPELLserviceInterpreter& instance();
+
+ // METHODS ///////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Main interpreter program loop. Will first prepare the control
+ * objects (controller, scheduler, callstack, etc), \see prepareObjects
+ * method. Then, execution environment will be set up (\see prepareExecution
+ * method). If both operations are success, the methods recover() or
+ * execute() are invoked depending on the command line arguments of
+ * the executor application. Once these finish, it waits for the signal
+ * to cleanup all things in order to exit the executor process.
+ **////////////////////////////////////////////////////////////////////
+ void mainLoop();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Initialize the interpreter with the given configuration
+ **
+ ** \param config IN: Configuration data
+ ** \param cif IN: SPELL client interface instance to use.
+ **////////////////////////////////////////////////////////////////////
+ void initialize( const SPELLinterpreterConfig& config, SPELLcif* cif );
+
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+
+protected: //-----------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Constructor.
+ **////////////////////////////////////////////////////////////////////
+ SPELLserviceInterpreter();
+
+ // METHODS ///////////////////////////////////////////////////////////////
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+
+private: //-------------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Prepare the CIF component
+ **////////////////////////////////////////////////////////////////////
+ void prepareCIF( const SPELLcontextConfig& ctxConfig );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Recover the CIF component information
+ **////////////////////////////////////////////////////////////////////
+ void recoverCIF( const SPELLcontextConfig& ctxConfig );
+
+ //////////////////////////////////////////////////////////////////////
+ /** Prepare the warm start / error recovery support mechanism. It will
+ * build the warmstart persistence file name, create the SPELLwarmStart
+ * object and initialize the execution frame with their references. MAy
+ * fail if SPELL_DATA environment variable is not set, or the persistent
+ * file cannot be created.
+ **////////////////////////////////////////////////////////////////////
+ void prepareWarmStart( const SPELLcontextConfig& ctxConfig );
+
+ //////////////////////////////////////////////////////////////////////
+ /** If initial preparation succeeds, additional mechanisms are intialized
+ * configured and/or installed:
+ *
+ * 1. Install special exceptions on Python side
+ * 2. Install the executor instance on the SPELL registry
+ * 3. Install the go-to mechanism on Python side
+ * 4. Install the CIF instance on the SPELL registry
+ * 5. Get procedure and User Library search paths
+ * 6. Compile the procedure code and prepare the execution frame.
+ *
+ * \returns False in case of failure.
+ **////////////////////////////////////////////////////////////////////
+ const bool prepareExecution();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Prepare objects neede for the execution of the procedure/script.
+ * The following steps are performed:
+ *
+ * 1. Initialize Python API
+ * 2. Install Log mechanism on Python side
+ * 3. Import SPELL framework on Python side.
+ * 4. Load configuration from XML files
+ * 5. Setup the client interface to connect to the client
+ * 6. Create control objects (controller, scheduler, frame, etc)
+ * 7. Prepare the warm start support
+ * 8. Initialize and configure the executor object
+ * 9. Start the command controller.
+ *
+ * \returns False in case of failure.
+ **////////////////////////////////////////////////////////////////////
+ const bool prepareObjects();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Execute the script/procedure. Basically invoke the execute() method
+ * of the executor object and catch any error taking place.
+ **////////////////////////////////////////////////////////////////////
+ void execute();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Recover script/procedure execution from persistent file. Invoke
+ * the recover() method of the executor object.
+ **////////////////////////////////////////////////////////////////////
+ void recover();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Handle errors raised during the initialization performed by the
+ * prepareExecution method.
+ **////////////////////////////////////////////////////////////////////
+ void handleStartupError();
+
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+ /** Interpreter configuration */
+ SPELLinterpreterConfig m_config;
+ /** Executor instance */
+ SPELLserviceImpl* m_serviceImpl;
+ /** Warm start mechanism */
+ SPELLwarmStart* m_warmStart;
+ /** Client interface */
+ SPELLcif* m_cif;
+ /** Execution controller */
+ SPELLcontrollerIF* m_controller;
+ /** Execution scheduler */
+ SPELLschedulerIF* m_scheduler;
+ /** Callstack manager */
+ SPELLcallstackIF* m_callstack;
+ /** Execution frame */
+ SPELLframeManager* m_frameManager;
+ /** Current procedure or file name */
+ std::string m_service;
+ /** Current procedures path */
+ std::string m_servicePath;
+ /** Current library path */
+ std::string m_libPath;
+};
+
+/*@}*/
+#endif
diff --git a/include/SPELL_EXC/SPELLstepOverMode.H b/include/SPELL_EXC/SPELLstepOverMode.H
index adeb7eb..de295b1 100644
--- a/include/SPELL_EXC/SPELLstepOverMode.H
+++ b/include/SPELL_EXC/SPELLstepOverMode.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Defines the step over modes
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLuserAction.H b/include/SPELL_EXC/SPELLuserAction.H
index 39f511e..f7d779f 100644
--- a/include/SPELL_EXC/SPELLuserAction.H
+++ b/include/SPELL_EXC/SPELLuserAction.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Defines a user action
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLvarInfo.H b/include/SPELL_EXC/SPELLvarInfo.H
index 357897a..d355712 100644
--- a/include/SPELL_EXC/SPELLvarInfo.H
+++ b/include/SPELL_EXC/SPELLvarInfo.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Procedure variable information
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLvariableManager.H b/include/SPELL_EXC/SPELLvariableManager.H
index fc0a63c..a8c490f 100644
--- a/include/SPELL_EXC/SPELLvariableManager.H
+++ b/include/SPELL_EXC/SPELLvariableManager.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Manager of procedure runtime variables
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_EXC/SPELLvariableMonitor.H b/include/SPELL_EXC/SPELLvariableMonitor.H
index 3d4c58a..4ce695a 100644
--- a/include/SPELL_EXC/SPELLvariableMonitor.H
+++ b/include/SPELL_EXC/SPELLvariableMonitor.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Monitor for runtime procedure variables
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_IPC/SPELLipc.H b/include/SPELL_IPC/SPELLipc.H
index 42f4554..0e046b6 100644
--- a/include/SPELL_IPC/SPELLipc.H
+++ b/include/SPELL_IPC/SPELLipc.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Inter process communication, data definitions
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_IPC/SPELLipcChannel.H b/include/SPELL_IPC/SPELLipcChannel.H
index ecfa0b5..065d413 100644
--- a/include/SPELL_IPC/SPELLipcChannel.H
+++ b/include/SPELL_IPC/SPELLipcChannel.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Inter-process communication - IPC channel
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -43,6 +43,7 @@
// FORWARD REFERENCES //////////////////////////////////////////////////////
class SPELLipcInterface;
+class SPELLipcInput;
// TYPES ///////////////////////////////////////////////////////////////////
// DEFINES /////////////////////////////////////////////////////////////////
diff --git a/include/SPELL_IPC/SPELLipcClientInterface.H b/include/SPELL_IPC/SPELLipcClientInterface.H
index 687e0f8..d24154b 100644
--- a/include/SPELL_IPC/SPELLipcClientInterface.H
+++ b/include/SPELL_IPC/SPELLipcClientInterface.H
@@ -5,7 +5,7 @@
// DESCRIPTION: IPC - Interface for clients
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -269,6 +269,8 @@ protected: //-----------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
void incomingResponse( const SPELLipcMessage& msg );
+ SPELLipcMessage getPingMessage();
+
// DATA MEMBERS //////////////////////////////////////////////////////////
diff --git a/include/SPELL_IPC/SPELLipcDataChunk.H b/include/SPELL_IPC/SPELLipcDataChunk.H
index c8cbc81..8119831 100644
--- a/include/SPELL_IPC/SPELLipcDataChunk.H
+++ b/include/SPELL_IPC/SPELLipcDataChunk.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Mechanism for transferring big data
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_IPC/SPELLipcError.H b/include/SPELL_IPC/SPELLipcError.H
index 2df1b2c..f5596fa 100644
--- a/include/SPELL_IPC/SPELLipcError.H
+++ b/include/SPELL_IPC/SPELLipcError.H
@@ -5,7 +5,7 @@
// DESCRIPTION: IPC error defintions
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_IPC/SPELLipcHelper.H b/include/SPELL_IPC/SPELLipcHelper.H
index 8cef46b..3fe969d 100644
--- a/include/SPELL_IPC/SPELLipcHelper.H
+++ b/include/SPELL_IPC/SPELLipcHelper.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Utilities for IPC
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_IPC/SPELLipcIncoming.H b/include/SPELL_IPC/SPELLipcIncoming.H
index 02c660e..9758650 100644
--- a/include/SPELL_IPC/SPELLipcIncoming.H
+++ b/include/SPELL_IPC/SPELLipcIncoming.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Handler for incoming IPC messages
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -30,13 +30,13 @@
// FILES TO INCLUDE ////////////////////////////////////////////////////////
// System includes ---------------------------------------------------------
// Local includes ----------------------------------------------------------
+#include "SPELL_IPC/SPELLipcChannel.H"
#include "SPELL_IPC/SPELLipcInterfaceListener.H"
// Project includes --------------------------------------------------------
#include "SPELL_SYN/SPELLthread.H"
#include "SPELL_SYN/SPELLevent.H"
#include "SPELL_SYN/SPELLthreadWork.H"
-
/** \addtogroup SPELL_IPC */
/*@{*/
@@ -44,6 +44,7 @@
// FORWARD REFERENCES //////////////////////////////////////////////////////
class SPELLipcInterface;
class SPELLipcOutput;
+
// TYPES ///////////////////////////////////////////////////////////////////
// DEFINES /////////////////////////////////////////////////////////////////
@@ -201,7 +202,7 @@ private: //-------------------------------------------------------------------
/** Holds the listener to be notified */
SPELLipcInterfaceListener& m_listener;
/** The message to be processed */
- const SPELLipcMessage m_message;
+ SPELLipcMessage m_message;
/** Event set when the processing finishes */
SPELLevent m_processingFinishEvent;
/** Event set when the processing starts */
@@ -294,7 +295,8 @@ public: //--------------------------------------------------------------------
SPELLipcIncomingRequest( const std::string& requestId,
const std::string& ifcName,
SPELLipcMessage msg,
- SPELLipcOutput& writer,
+ SPELLmutex& mutex,
+ SPELLipcChannel** channel,
SPELLipcInterfaceListener& listener );
//////////////////////////////////////////////////////////////////////
@@ -322,7 +324,8 @@ private: //-------------------------------------------------------------------
// DATA MEMBERS //////////////////////////////////////////////////////////
/** Holds the writer to use to send the response */
- SPELLipcOutput& m_writer;
+ SPELLipcChannel** m_channel;
+ SPELLmutex& m_mutex;
};
/*@}*/
diff --git a/include/SPELL_IPC/SPELLipcInput.H b/include/SPELL_IPC/SPELLipcInput.H
index 56b2619..e513036 100644
--- a/include/SPELL_IPC/SPELLipcInput.H
+++ b/include/SPELL_IPC/SPELLipcInput.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Data reader
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -42,6 +42,7 @@
// FORWARD REFERENCES //////////////////////////////////////////////////////
class SPELLipcChannel;
+class SPELLipcInterface;
// TYPES ///////////////////////////////////////////////////////////////////
// DEFINES /////////////////////////////////////////////////////////////////
@@ -96,6 +97,11 @@ public: //--------------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
bool isConnected();
+ void setHandleEOC(bool eocValue)
+ {
+ m_requestedEOC = eocValue;
+ }
+
// DATA MEMBERS //////////////////////////////////////////////////////////
protected: //-----------------------------------------------------------------
diff --git a/include/SPELL_IPC/SPELLipcInterface.H b/include/SPELL_IPC/SPELLipcInterface.H
index e62a32e..ba67190 100644
--- a/include/SPELL_IPC/SPELLipcInterface.H
+++ b/include/SPELL_IPC/SPELLipcInterface.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Common IPC interface
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -175,6 +175,12 @@ public: //--------------------------------------------------------------------
* \param msg IN: response to be processed.
**////////////////////////////////////////////////////////////////////
virtual void incomingResponse( const SPELLipcMessage& msg ) = 0;
+
+ virtual SPELLipcMessage getPingMessage()
+ {
+ static SPELLipcMessage empty = SPELLipcMessage();
+ return empty;
+ };
};
/*@}*/
diff --git a/include/SPELL_IPC/SPELLipcInterfaceListener.H b/include/SPELL_IPC/SPELLipcInterfaceListener.H
index 100926b..01e6838 100644
--- a/include/SPELL_IPC/SPELLipcInterfaceListener.H
+++ b/include/SPELL_IPC/SPELLipcInterfaceListener.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Interface IPC message listener
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -89,6 +89,12 @@ public:
/** Peer has closed the connection (end of conversation)
**////////////////////////////////////////////////////////////////////
virtual void processConnectionClosed( int clientKey ) = 0;
+
+ virtual SPELLipcMessage getPingMessage()
+ {
+ static SPELLipcMessage empty = SPELLipcMessage();
+ return empty;
+ };
};
/*@}*/
diff --git a/include/SPELL_IPC/SPELLipcMessage.H b/include/SPELL_IPC/SPELLipcMessage.H
index b93ae94..c882f51 100644
--- a/include/SPELL_IPC/SPELLipcMessage.H
+++ b/include/SPELL_IPC/SPELLipcMessage.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Definition of IPC message
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -239,6 +239,12 @@ public: //--------------------------------------------------------------------
return m_type;
}
+ //////////////////////////////////////////////////////////////////////
+ /**Cleans up this message and frees as much meory as possible.
+ *
+ **////////////////////////////////////////////////////////////////////
+ void clear();
+
//////////////////////////////////////////////////////////////////////
/** Set the value of a message field.
*
diff --git a/include/SPELL_IPC/SPELLipcMessageMailbox.H b/include/SPELL_IPC/SPELLipcMessageMailbox.H
index 989acdb..b8b365d 100644
--- a/include/SPELL_IPC/SPELLipcMessageMailbox.H
+++ b/include/SPELL_IPC/SPELLipcMessageMailbox.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Mailbox for incoming messages
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -166,11 +166,6 @@ private: //-------------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
SPELLipcMessageQueue* getQueue( std::string id );
- //////////////////////////////////////////////////////////////////////
- /** Cancell all requests waiting
- **////////////////////////////////////////////////////////////////////
- void cancelAll();
-
// DATA MEMBERS //////////////////////////////////////////////////////////
/** Holds the map of message queues */
SPELLipcMessageQueueMap m_queueMap;
diff --git a/include/SPELL_IPC/SPELLipcOutput.H b/include/SPELL_IPC/SPELLipcOutput.H
index 7d8d037..5ede685 100644
--- a/include/SPELL_IPC/SPELLipcOutput.H
+++ b/include/SPELL_IPC/SPELLipcOutput.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Data writer
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_IPC/SPELLipcServerInterface.H b/include/SPELL_IPC/SPELLipcServerInterface.H
index 261b597..8b693dc 100644
--- a/include/SPELL_IPC/SPELLipcServerInterface.H
+++ b/include/SPELL_IPC/SPELLipcServerInterface.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Interface for servers
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -216,7 +216,7 @@ protected: //-----------------------------------------------------------------
//////////////////////////////////////////////////////////////////////
/** Obtain the channel for a peer
**////////////////////////////////////////////////////////////////////
- SPELLipcChannel& getChannel( int peerKey );
+ SPELLipcChannel** getChannel( int peerKey );
// DATA MEMBERS //////////////////////////////////////////////////////////
@@ -251,6 +251,7 @@ private: //-------------------------------------------------------------------
* \param key IN: peer key.
**////////////////////////////////////////////////////////////////////
void removeClient( int key );
+ void removeClientInternal( int key );
//////////////////////////////////////////////////////////////////////
/** Remove all client of the list of connected clients and disconnect
@@ -325,6 +326,9 @@ private: //-------------------------------------------------------------------
std::string m_ifcName;
/** Holds the client keys used */
std::vector m_usedClientKeys;
+
+ std::vector m_clientKeysToRemove;
+
/** Holds the server key */
int m_serverKey;
/** Holds the server port */
@@ -333,6 +337,7 @@ private: //-------------------------------------------------------------------
SPELLsocket* m_serverSocket;
/** Synchronization mutex for operations */
SPELLmutex m_clientLock;
+ SPELLmutex m_clientCleanupLock;
/** True if the interface is connected */
bool m_connected;
/** Associated IPC listener */
diff --git a/include/SPELL_IPC/SPELLipcServerInterfaceSingle.H b/include/SPELL_IPC/SPELLipcServerInterfaceSingle.H
index c6c019e..3346ea7 100644
--- a/include/SPELL_IPC/SPELLipcServerInterfaceSingle.H
+++ b/include/SPELL_IPC/SPELLipcServerInterfaceSingle.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Interface for single-client servers
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -187,6 +187,7 @@ private: //-------------------------------------------------------------------
/** Remove the client
**////////////////////////////////////////////////////////////////////
void removeClient();
+ void removeClientInternal();
//////////////////////////////////////////////////////////////////////
/** \see SPELLipcInterface.
@@ -272,7 +273,8 @@ private: //-------------------------------------------------------------------
/** Synchronization mutex for operations */
SPELLmutex m_clientLock;
/** True if the interface is connected */
- bool m_connected;
+ bool m_connected;
+ bool m_removeClient;
/** Associated IPC listener */
SPELLipcInterfaceListener* m_listener;
/** Holds the set of incoming request processors to be cleaned up */
@@ -289,6 +291,8 @@ private: //-------------------------------------------------------------------
SPELLevent m_clientConnectionEvent;
/** Blocks processing of incoming requests */
SPELLmutex m_incomingLock;
+ /** Only allow one thread to cleanup the channel */
+ SPELLmutex m_cleanupLock;
/** IPC channel */
SPELLipcChannel* m_channel;
/** Timeout for request retries */
diff --git a/include/SPELL_IPC/SPELLipcTrash.H b/include/SPELL_IPC/SPELLipcTrash.H
index 5ff4201..4b103cc 100644
--- a/include/SPELL_IPC/SPELLipcTrash.H
+++ b/include/SPELL_IPC/SPELLipcTrash.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Cleaner for obsolete requests
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -111,8 +111,6 @@ public: //--------------------------------------------------------------------
// DATA MEMBERS //////////////////////////////////////////////////////////
-protected: //-----------------------------------------------------------------
-
// EXCEPTIONS ////////////////////////////////////////////////////////////
// ENUMS /////////////////////////////////////////////////////////////////
// TYPES /////////////////////////////////////////////////////////////////
diff --git a/include/SPELL_IPC/SPELLipc_Context.H b/include/SPELL_IPC/SPELLipc_Context.H
index cfe316e..57fe5dc 100644
--- a/include/SPELL_IPC/SPELLipc_Context.H
+++ b/include/SPELL_IPC/SPELLipc_Context.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Inter process communication, data definitions for context process
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -100,8 +100,11 @@ namespace MessageField
static const std::string FIELD_PROMPT_DELAY("PromptWarningDelay");
static const std::string FIELD_BY_STEP("ByStep");
static const std::string FIELD_FORCE_TC_CONFIRM("ForceTcConfirm");
+ static const std::string FIELD_FORCE_PROMPT_CONFIRM("ForcePromptConfirm");
static const std::string FIELD_SAVE_STATE_MODE("SaveStateMode");
static const std::string FIELD_WATCH_VARIABLES("WatchVariables");
+ static const std::string FIELD_RESOURCES_DISPLAY("ResourcesDisplay");
+ static const std::string FIELD_LOCAL_RESOURCE_SUPPORTED("LocalResourcesSupported");
static const std::string FIELD_MAX_VERBOSITY("MaxVerbosity");
static const std::string FIELD_BROWSABLE_LIB("BrowsableLib");
@@ -178,13 +181,18 @@ namespace MessageValue
namespace ContextMessages
{
/** Request list of available executors (running procedures) */
- static const std::string REQ_EXEC_LIST("REQ_EXEC_LIST");
+ static const std::string REQ_EXEC_LIST("REQ_EXEC_LIST");
+ static const std::string REQ_SERVICE_LIST("REQ_SERVICE_LIST");
+
/** Response to REQ_EXEC_LIST */
static const std::string RSP_EXEC_LIST("RSP_EXEC_LIST");
+ static const std::string RSP_SERVICE_LIST("RSP_SERVICE_LIST");
/** Request executor (procedure) information */
- static const std::string REQ_EXEC_INFO("REQ_EXEC_INFO");
- /** Response to REQ_EXEC_INFO */
+ static const std::string REQ_EXEC_INFO("REQ_EXEC_INFO");
+ /** Request service information */
+ static const std::string REQ_SERVICE_INFO("REQ_SERVICE_INFO");
+ /** Response to REQ_EXEC_INFO */
static const std::string RSP_EXEC_INFO("RSP_EXEC_INFO");
/** Request opening a new executor (procedure)
diff --git a/include/SPELL_IPC/SPELLipc_Executor.H b/include/SPELL_IPC/SPELLipc_Executor.H
index 582611b..0537f10 100644
--- a/include/SPELL_IPC/SPELLipc_Executor.H
+++ b/include/SPELL_IPC/SPELLipc_Executor.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Inter process communication, data definitions for executor process
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -80,6 +80,9 @@ namespace MessageId
/** Message for enabling or disabling variable analysis */
static const std::string MSG_ID_WVARIABLES_ENABLE("MSG_WVARIABLES_ENABLE");
static const std::string MSG_ID_WVARIABLES_DISABLE("MSG_WVARIABLES_DISABLE");
+ /** Message for enabling or disabling resource analysis */
+ static const std::string MSG_ID_DRESOURCES_ENABLE("MSG_DRESOURCES_ENABLE");
+ static const std::string MSG_ID_DRESOURCES_DISABLE("MSG_DRESOURCES_DISABLE");
};
/** Defines message fields */
@@ -201,6 +204,31 @@ namespace MessageField
/** Variable analysis enabled */
static const std::string FIELD_WVARIABLES_ENABLED("WVarEnabled");
+ //################################################################################
+ //# DISPLAY OF RESOURCES
+ //################################################################################
+
+ /** Resource names */
+ static const std::string FIELD_RESOURCE_NAME("ResourceName");
+ /** Resource global values */
+ static const std::string FIELD_RESOURCE_GLOBAL_VALUE("ResourceGlobalValue");
+ /** Resource local values */
+ static const std::string FIELD_RESOURCE_LOCAL_VALUE("ResourceLocalValue");
+ /** Resource types */
+ static const std::string FIELD_RESOURCE_TYPE("ResourceType");
+ /** Resource value range */
+ static const std::string FIELD_RESOURCE_VALUE_RANGE("ResourceValueRange");
+ /** Resource gcs value range */
+ static const std::string FIELD_RESOURCE_GCS_VALUE_RANGE("ResourceGCSValueRange");
+ /** Resource GCS names */
+ static const std::string FIELD_RESOURCE_GCS_NAME("ResourceGCSName");
+ /** Resource deleted flags */
+ static const std::string FIELD_RESOURCE_DELETE("ResourceDelete");
+ /** Resource added flags */
+ static const std::string FIELD_RESOURCE_ADDED("ResourceAdded");
+ /** Resource analysis enabled */
+ static const std::string FIELD_DRESOURCES_ENABLED("DResourcesEnabled");
+
//################################################################################
//# DICTIONARY EDITING
//################################################################################
@@ -399,6 +427,23 @@ namespace ExecutorMessages
/** Response */
static const std::string RSP_WVARIABLES_ENABLED("RSP_WVARIABLES_ENABLED");
+ //################################################################################
+ //# DISPLAY OF RESOURCES
+ //################################################################################
+
+ /** Request for retrieving resource names */
+ static const std::string REQ_GET_RESOURCES("REQ_GET_RESOURCES");
+ /** Response */
+ static const std::string RSP_GET_RESOURCES("RSP_GET_RESOURCES");
+ /** Request for changing resources */
+ static const std::string REQ_CHANGE_RESOURCE("REQ_CHANGE_RESOURCE");
+ /** Response */
+ static const std::string RSP_CHANGE_RESOURCE("RSP_CHANGE_RESOURCE");
+ /** Request to check if resource analysis is enabled */
+ static const std::string REQ_DRESOURCES_ENABLED("REQ_DRESOURCES_ENABLED");
+ /** Response */
+ static const std::string RSP_DRESOURCES_ENABLED("RSP_DRESOURCES_ENABLED");
+
//################################################################################
//# DICTIONARY EDITING
//################################################################################
@@ -423,6 +468,9 @@ namespace ExecutorMessages
/** Oneway message for variable scope change notifications */
static const std::string MSG_SCOPE_CHANGE("MSG_SCOPE_CHANGE");
+ /** Oneway message for resource change notifications */
+ static const std::string MSG_RESOURCE_CHANGE("MSG_RESOURCE_CHANGE");
+
//################################################################################
//# REQUESTS TO CONTEXT
//################################################################################
diff --git a/include/SPELL_IPC/SPELLipc_Listener.H b/include/SPELL_IPC/SPELLipc_Listener.H
index 5ef1469..8c2a68c 100644
--- a/include/SPELL_IPC/SPELLipc_Listener.H
+++ b/include/SPELL_IPC/SPELLipc_Listener.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Inter process communication, data definitions for listener process
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_IPC/SPELLsocket.H b/include/SPELL_IPC/SPELLsocket.H
index 0df5e6c..485e2b1 100644
--- a/include/SPELL_IPC/SPELLsocket.H
+++ b/include/SPELL_IPC/SPELLsocket.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Socket wrapper
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -60,7 +60,7 @@ public: //--------------------------------------------------------------------
*
* \param fd IN: socket file descriptor.
*/////////////////////////////////////////////////////////////////////
- SPELLsocket( int fd );
+ SPELLsocket(int fd, std::string user, std::vector groups);
/*////////////////////////////////////////////////////////////////////
* Destructor
@@ -116,6 +116,11 @@ public: //--------------------------------------------------------------------
*/////////////////////////////////////////////////////////////////////
bool waitData( int timeout );
+
+ std::string getUser() {
+ return user;
+ };
+
/*////////////////////////////////////////////////////////////////////
* Shutdown the socket input.
*/////////////////////////////////////////////////////////////////////
@@ -183,6 +188,9 @@ private: //-------------------------------------------------------------------
int m_socketFd;
/** Socket connected flag */
bool m_connected;
+
+ std::string user;
+ std::vector groups;
};
/*@}*/
diff --git a/include/SPELL_IPC/SPELLtimeoutValues.H b/include/SPELL_IPC/SPELLtimeoutValues.H
index 7157cd1..848b6f3 100644
--- a/include/SPELL_IPC/SPELLtimeoutValues.H
+++ b/include/SPELL_IPC/SPELLtimeoutValues.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Inter process communication, timeout values
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_LST/SPELLlistener.H b/include/SPELL_LST/SPELLlistener.H
index 1b9dc46..068d769 100644
--- a/include/SPELL_LST/SPELLlistener.H
+++ b/include/SPELL_LST/SPELLlistener.H
@@ -5,7 +5,7 @@
// DESCRIPTION: SPELL listener library header file
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_LST/SPELLlistenerComm.H b/include/SPELL_LST/SPELLlistenerComm.H
index 78ce8b8..a5507a9 100644
--- a/include/SPELL_LST/SPELLlistenerComm.H
+++ b/include/SPELL_LST/SPELLlistenerComm.H
@@ -5,7 +5,7 @@
// DESCRIPTION: SPELL listener library header file
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_LST/SPELLlistenerContext.H b/include/SPELL_LST/SPELLlistenerContext.H
index 3c0a5b6..836593e 100644
--- a/include/SPELL_LST/SPELLlistenerContext.H
+++ b/include/SPELL_LST/SPELLlistenerContext.H
@@ -5,7 +5,7 @@
// DESCRIPTION: SPELL listener library header file
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -97,10 +97,10 @@ public:
void notifyClients( const SPELLipcMessage& msg );
// SPELLprocessListener methods
- void processStarted( const std::string& identifier );
- void processFinished( const std::string& identifier, const int& retValue );
- void processKilled( const std::string& identifier );
- void processFailed( const std::string& identifier );
+ void processStarted( const std::string identifier );
+ void processFinished( const std::string identifier, const int& retValue );
+ void processKilled( const std::string identifier );
+ void processFailed( const std::string identifier );
bool respawnContext(const std::string& ctxName);
// Internals
diff --git a/include/SPELL_LST/SPELLlistenerGui.H b/include/SPELL_LST/SPELLlistenerGui.H
index 4848d39..ed5a28d 100644
--- a/include/SPELL_LST/SPELLlistenerGui.H
+++ b/include/SPELL_LST/SPELLlistenerGui.H
@@ -5,7 +5,7 @@
// DESCRIPTION: SPELL listener library header file
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_PRC/SPELLprocess.H b/include/SPELL_PRC/SPELLprocess.H
index 37d8315..08501b1 100644
--- a/include/SPELL_PRC/SPELLprocess.H
+++ b/include/SPELL_PRC/SPELLprocess.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Process model
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_PRC/SPELLprocessInfo.H b/include/SPELL_PRC/SPELLprocessInfo.H
index 3a9ee2f..5344f2f 100644
--- a/include/SPELL_PRC/SPELLprocessInfo.H
+++ b/include/SPELL_PRC/SPELLprocessInfo.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Process information
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_PRC/SPELLprocessManager.H b/include/SPELL_PRC/SPELLprocessManager.H
index 4efd787..1c8b05d 100644
--- a/include/SPELL_PRC/SPELLprocessManager.H
+++ b/include/SPELL_PRC/SPELLprocessManager.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Process manager
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -77,7 +77,7 @@ public://--------------------------------------------------------------------
*
* \param identifier IN: unique identifier of the process.
**////////////////////////////////////////////////////////////////////
- virtual void processStarted( const std::string& identifier ) = 0;
+ virtual void processStarted( const std::string identifier ) = 0;
//////////////////////////////////////////////////////////////////////
/** Notify the given process has finished.
@@ -85,21 +85,21 @@ public://--------------------------------------------------------------------
* \param identifier IN: unique identifier of the process.
* \param retValue IN: process exit code.
**////////////////////////////////////////////////////////////////////
- virtual void processFinished( const std::string& identifier, const int& retValue ) = 0;
+ virtual void processFinished( std::string identifier, const int& retValue ) = 0;
//////////////////////////////////////////////////////////////////////
/** Notify the given process has been killed.
*
* \param identifier IN: unique identifier of the process.
**////////////////////////////////////////////////////////////////////
- virtual void processKilled( const std::string& identifier ) = 0;
+ virtual void processKilled( std::string identifier ) = 0;
//////////////////////////////////////////////////////////////////////
/** Notify the given process has failed to start.
*
* \param identifier IN: unique identifier of the process.
**////////////////////////////////////////////////////////////////////
- virtual void processFailed( const std::string& identifier ) = 0;
+ virtual void processFailed( std::string identifier ) = 0;
};
//////////////////////////////////////////////////////////////////////////////
@@ -168,6 +168,8 @@ public: //--------------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
void killProcess( const std::string& identifier );
+ bool checkProcessExist( const std::string& identifier );
+
//////////////////////////////////////////////////////////////////////
/** Wait the given process to finish.
*
@@ -241,7 +243,7 @@ protected: //-----------------------------------------------------------------
*
* \param identifier IN: process unique identifier.
**////////////////////////////////////////////////////////////////////
- void fireProcessStarted( const std::string& identifier );
+ void fireProcessStarted( const std::string identifier );
//////////////////////////////////////////////////////////////////////
/** Notify listeners that a given process has finished.
@@ -249,21 +251,21 @@ protected: //-----------------------------------------------------------------
* \param identifier IN: process unique identifier.
* \param retValue IN: process exit code.
**////////////////////////////////////////////////////////////////////
- void fireProcessFinished( const std::string& identifier, int retValue );
+ void fireProcessFinished( std::string identifier, int retValue );
//////////////////////////////////////////////////////////////////////
/** Notify listeners that a given process has been killed.
*
* \param identifier IN: process unique identifier.
**////////////////////////////////////////////////////////////////////
- void fireProcessKilled( const std::string& identifier );
+ void fireProcessKilled( std::string identifier );
//////////////////////////////////////////////////////////////////////
/** Notify listeners that a given process has failed to start.
*
* \param identifier IN: process unique identifier.
**////////////////////////////////////////////////////////////////////
- void fireProcessFailed( const std::string& identifier );
+ void fireProcessFailed( std::string identifier );
// DATA MEMBERS //////////////////////////////////////////////////////////
diff --git a/include/SPELL_PRC/SPELLprocessStatus.H b/include/SPELL_PRC/SPELLprocessStatus.H
index 8b61681..16923fd 100644
--- a/include/SPELL_PRC/SPELLprocessStatus.H
+++ b/include/SPELL_PRC/SPELLprocessStatus.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Process status codes
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_PRD/SPELLlibrary.H b/include/SPELL_PRD/SPELLlibrary.H
index 0fe2a2f..ecbd6f4 100644
--- a/include/SPELL_PRD/SPELLlibrary.H
+++ b/include/SPELL_PRD/SPELLlibrary.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Library model
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -120,7 +120,7 @@ protected: //-----------------------------------------------------------------
*
* \param path IN: the path to the procedure file.
**////////////////////////////////////////////////////////////////////
- void parseFile( const std::string& path );
+ void parseFile( const std::string& path ) {};
// DATA MEMBERS //////////////////////////////////////////////////////////
diff --git a/include/SPELL_PRD/SPELLprocedure.H b/include/SPELL_PRD/SPELLprocedure.H
index 3e78a9d..809dbd5 100644
--- a/include/SPELL_PRD/SPELLprocedure.H
+++ b/include/SPELL_PRD/SPELLprocedure.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Procedure model
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -106,15 +106,6 @@ public: //--------------------------------------------------------------------
return m_name;
};
- //////////////////////////////////////////////////////////////////////
- /** Obtain the procedure file MD5 checksum.
- *
- * \returns The checksum.
- **////////////////////////////////////////////////////////////////////
- const std::string getMD5() const {
- return m_md5;
- };
-
//////////////////////////////////////////////////////////////////////
/** Obtain the procedure file name and path.
*
@@ -210,11 +201,6 @@ protected: //-----------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
const bool isPropertyContinued( const std::string& line );
- //////////////////////////////////////////////////////////////////////
- /** Calculate de MD5 checksum of the procedure file.
- **////////////////////////////////////////////////////////////////////
- std::string obtainChecksum( const std::string& filename );
-
// DATA MEMBERS //////////////////////////////////////////////////////////
private: //-------------------------------------------------------------------
@@ -229,8 +215,6 @@ private: //-------------------------------------------------------------------
std::string m_procId;
/** Procedure name */
std::string m_name;
- /** MD5 checksum */
- std::string m_md5;
/** Procedure file */
std::string m_file;
/** Procedure source code */
diff --git a/include/SPELL_PRD/SPELLprocedureManager.H b/include/SPELL_PRD/SPELLprocedureManager.H
index b66c66b..e9f431d 100644
--- a/include/SPELL_PRD/SPELLprocedureManager.H
+++ b/include/SPELL_PRD/SPELLprocedureManager.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Procedure manager
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -30,6 +30,7 @@
// FILES TO INCLUDE ////////////////////////////////////////////////////////
// System includes ---------------------------------------------------------
// Local includes ----------------------------------------------------------
+#include "SPELL_PRD/SPELLpyService.H"
#include "SPELL_PRD/SPELLprocedure.H"
#include "SPELL_PRD/SPELLlibrary.H"
// Project includes --------------------------------------------------------
@@ -38,11 +39,9 @@
/** \addtogroup SPELL_PRD */
/*@{*/
-
// FORWARD REFERENCES //////////////////////////////////////////////////////
// TYPES ///////////////////////////////////////////////////////////////////
// DEFINES /////////////////////////////////////////////////////////////////
-
//////////////////////////////////////////////////////////////////////////////
/**
** \brief Procedure manager.
@@ -54,175 +53,208 @@
** Used by the executor when loading subprocedures, and to check if a
** given file is on the procedure path.
**
-**////////////////////////////////////////////////////////////////////////////
+ **////////////////////////////////////////////////////////////////////////////
+
+const std::string noInstanceId( const std::string& procId );
+
+
class SPELLprocedureManager
{
-public: //--------------------------------------------------------------------
+public:
+ //--------------------------------------------------------------------
// EXCEPTIONS ////////////////////////////////////////////////////////////
// ENUMS /////////////////////////////////////////////////////////////////
// TYPES /////////////////////////////////////////////////////////////////
- /** Shorcut for procedure lists */
- typedef std::list ProcList;
+ /** Shorcut for procedure lists */
+ typedef std::list ProcList;
// LIFECYCLE /////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////
- /** Destructor
- **////////////////////////////////////////////////////////////////////
- ~SPELLprocedureManager();
+ //////////////////////////////////////////////////////////////////////
+ /** Destructor
+ **////////////////////////////////////////////////////////////////////
+ ~SPELLprocedureManager();
// STATIC ////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////
- /** Obtain the singleton instance.
- *
- * \return The singleton instance
- **////////////////////////////////////////////////////////////////////
- static SPELLprocedureManager& instance();
+ //////////////////////////////////////////////////////////////////////
+ /** Obtain the singleton instance.
+ *
+ * \return The singleton instance
+ **////////////////////////////////////////////////////////////////////
+ static SPELLprocedureManager& instance();
// METHODS ///////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////
- /** Setup the procedure manager.
- *
- * \param ctxName IN: current context name.
- **////////////////////////////////////////////////////////////////////
- void setup( const std::string& ctxName );
-
- //////////////////////////////////////////////////////////////////////
- /** Obtain the configured library path.
- *
- * \returns The library path.
- **////////////////////////////////////////////////////////////////////
- const std::string getLibPath() const;
-
- //////////////////////////////////////////////////////////////////////
- /** Obtain the configured procedure path.
- *
- * \returns The library path.
- **////////////////////////////////////////////////////////////////////
- const std::string getProcPath() const;
-
- //////////////////////////////////////////////////////////////////////
- /** Obtain the filename corresponding to the given procedure.
- *
- * \param procId IN: the procedure identifier.
- *
- * \returns The file name.
- **////////////////////////////////////////////////////////////////////
- const std::string getProcFile( const std::string& procId );
-
- //////////////////////////////////////////////////////////////////////
- /** Obtain the name corresponding to the given procedure.
- *
- * \param procId IN: the procedure identifier.
- *
- * \returns The procedure name.
- **////////////////////////////////////////////////////////////////////
- const std::string getProcName( const std::string& procId );
-
- //////////////////////////////////////////////////////////////////////
- /** Obtain the identifier corresponding to the given procedure file.
- *
- * \param filename IN: the procedure file.
- *
- * \returns The identifier.
- **////////////////////////////////////////////////////////////////////
- const std::string getProcId( const std::string& filename );
-
- //////////////////////////////////////////////////////////////////////
- /** Get the list of available procedures.
- *
- * \returns The list of procedure identifiers.
- **////////////////////////////////////////////////////////////////////
- const ProcList getProcList();
-
- //////////////////////////////////////////////////////////////////////
- /** Obtain the source code corresponding to the given procedure.
- *
- * \param procId IN: the procedure identifier.
- *
- * \returns The source code.
- **////////////////////////////////////////////////////////////////////
- SPELLprocedureSourceCode getSourceCode( const std::string& procId );
-
- //////////////////////////////////////////////////////////////////////
- /** Obtain the list of procedure properties
- **////////////////////////////////////////////////////////////////////
- SPELLprocedure::PropertyKeys getPropertyKeys( const std::string& procId );
-
- //////////////////////////////////////////////////////////////////////
- /** Obtain the value of a procedure property
- **////////////////////////////////////////////////////////////////////
- const std::string getProperty( const std::string& procId, const std::string& key );
-
- //////////////////////////////////////////////////////////////////////
- /** Refresh and reload the list of available procedures.
- **////////////////////////////////////////////////////////////////////
- void refresh();
-
- //////////////////////////////////////////////////////////////////////
- /** Get a procedure model
- **////////////////////////////////////////////////////////////////////
- SPELLprocedure& getProcedure( const std::string& procId );
+ //////////////////////////////////////////////////////////////////////
+ /** Setup the procedure manager.
+ *
+ * \param ctxName IN: current context name.
+ **////////////////////////////////////////////////////////////////////
+ void setup(const std::string& ctxName);
+
+ //////////////////////////////////////////////////////////////////////
+ /** Obtain the configured library path.
+ *
+ * \returns The library path.
+ **////////////////////////////////////////////////////////////////////
+ const std::string getLibPath() const;
+
+ //////////////////////////////////////////////////////////////////////
+ /** Obtain the configured procedure path.
+ *
+ * \returns The library path.
+ **////////////////////////////////////////////////////////////////////
+ const std::string getProcPath() const;
+
+ //////////////////////////////////////////////////////////////////////
+ /** Obtain the filename corresponding to the given procedure.
+ *
+ * \param procId IN: the procedure identifier.
+ *
+ * \returns The file name.
+ **////////////////////////////////////////////////////////////////////
+ const std::string getProcFile(const std::string& procId);
+
+ //////////////////////////////////////////////////////////////////////
+ /** Obtain the name corresponding to the given procedure.
+ *
+ * \param procId IN: the procedure identifier.
+ *
+ * \returns The procedure name.
+ **////////////////////////////////////////////////////////////////////
+ const std::string getProcName(const std::string& procId);
+
+ //////////////////////////////////////////////////////////////////////
+ /** Obtain the identifier corresponding to the given procedure file.
+ *
+ * \param filename IN: the procedure file.
+ *
+ * \returns The identifier.
+ **////////////////////////////////////////////////////////////////////
+ const std::string getProcId(const std::string& filename);
+
+ //////////////////////////////////////////////////////////////////////
+ /** Get the list of available procedures.
+ *
+ * \returns The list of procedure identifiers.
+ **////////////////////////////////////////////////////////////////////
+ const ProcList getProcList();
+ //////////////////////////////////////////////////////////////////////
+ /** Get the list of available services.
+ *
+ * \returns The list of service identifiers.
+ **////////////////////////////////////////////////////////////////////
+ const ProcList getServiceList();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Obtain the source code corresponding to the given procedure.
+ *
+ * \param procId IN: the procedure identifier.
+ *
+ * \returns The source code.
+ **////////////////////////////////////////////////////////////////////
+ SPELLprocedureSourceCode getSourceCode(const std::string& procId);
+
+ //////////////////////////////////////////////////////////////////////
+ /** Obtain the list of procedure properties
+ **////////////////////////////////////////////////////////////////////
+ SPELLprocedure::PropertyKeys getPropertyKeys(const std::string& procId);
+
+ //////////////////////////////////////////////////////////////////////
+ /** Obtain the value of a procedure property
+ **////////////////////////////////////////////////////////////////////
+ const std::string getProperty(const std::string& procId, const std::string& key);
+
+ //////////////////////////////////////////////////////////////////////
+ /** Refresh and reload the list of available procedures.
+ **////////////////////////////////////////////////////////////////////
+ void refresh();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Get a procedure model
+ **////////////////////////////////////////////////////////////////////
+ SPELLprocedure& getProcedure(const std::string& procId);
+
+ //////////////////////////////////////////////////////////////////////
+ /** Get a service model
+ **////////////////////////////////////////////////////////////////////
+ SPELLpyService& getService(const std::string& serviceId);
+
+ //////////////////////////////////////////////////////////////////////
+ /** Callback for registering a SPELL Service
+ **////////////////////////////////////////////////////////////////////
+ void registerServiceHandler(PyObject* serviceImpl);
// DATA MEMBERS //////////////////////////////////////////////////////////
-protected: //-----------------------------------------------------------------
+protected:
+ //-----------------------------------------------------------------
// EXCEPTIONS ////////////////////////////////////////////////////////////
// ENUMS /////////////////////////////////////////////////////////////////
// TYPES /////////////////////////////////////////////////////////////////
- /** Shortcut for procedure id-name map */
- typedef std::map ProcMap;
- /** Shortcut for procedure id-model map */
- typedef std::map ProcModels;
- /** Shortcut for library id-model map */
- typedef std::map LibModels;
+ /** Shortcut for procedure id-name map */
+ typedef std::map ProcMap;
+ /** Shortcut for procedure id-model map */
+ typedef std::map ProcModels;
+ typedef std::map ServiceModelMap;
+ /** Shortcut for library id-model map */
+ typedef std::map LibModels;
// LIFECYCLE /////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////
- /** Constructor.
- **////////////////////////////////////////////////////////////////////
- SPELLprocedureManager();
+ //////////////////////////////////////////////////////////////////////
+ /** Constructor.
+ **////////////////////////////////////////////////////////////////////
+ SPELLprocedureManager();
// METHODS ///////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////
- /** Resolve procedure paths
- **////////////////////////////////////////////////////////////////////
- void resolvePaths();
-
- //////////////////////////////////////////////////////////////////////
- /** Find all procedures in the given search path. Include only those
- * procedures whose associated spacecraft matches the given one.
- *
- * \param basePath IN: search path
- * \param sc IN: spacecraft id.
- **////////////////////////////////////////////////////////////////////
- void findProcedures( const std::string& basePath, const std::string& sc );
-
- //////////////////////////////////////////////////////////////////////
- /** Find all libraries available in UserLib location path.
- *
- * \param basePath IN: the path of UserLib location.
- **////////////////////////////////////////////////////////////////////
- void findLibraries( const std::string& basePath );
-
- //////////////////////////////////////////////////////////////////////
- /** Remove the instance number from the given procedure identifier.
- *
- * \param procId IN: the identifier to process.
- *
- * \returns The procedure identifier without instance information.
- **////////////////////////////////////////////////////////////////////
- const std::string noInstanceId( const std::string& procId );
+ //////////////////////////////////////////////////////////////////////
+ /** Resolve procedure paths
+ **////////////////////////////////////////////////////////////////////
+ void resolvePaths();
+
+ //////////////////////////////////////////////////////////////////////
+ /** Find all procedures in the given search path. Include only those
+ * procedures whose associated spacecraft matches the given one.
+ *
+ * \param basePath IN: search path
+ * \param sc IN: spacecraft id.
+ **////////////////////////////////////////////////////////////////////
+ void findProcedures(const std::string& basePath, const std::string& sc);
+
+ //////////////////////////////////////////////////////////////////////
+ /** Find all Spell Services in the given search path. Include only those
+ * procedures whose associated spacecraft matches the given one.
+ *
+ * \param basePath IN: search path
+ * \param sc IN: spacecraft id.
+ **////////////////////////////////////////////////////////////////////
+ void findServices(const std::string& basePath, const std::string& sc);
+
+ //////////////////////////////////////////////////////////////////////
+ /** Find all libraries available in UserLib location path.
+ *
+ * \param basePath IN: the path of UserLib location.
+ **////////////////////////////////////////////////////////////////////
+ void findLibraries(const std::string& basePath);
+
+ //////////////////////////////////////////////////////////////////////
+ /** Remove the instance number from the given procedure identifier.
+ *
+ * \param procId IN: the identifier to process.
+ *
+ * \returns The procedure identifier without instance information.
+ **////////////////////////////////////////////////////////////////////
+ //const std::string noInstanceId(const std::string& procId);
// DATA MEMBERS //////////////////////////////////////////////////////////
-private: //-------------------------------------------------------------------
+private:
+ //-------------------------------------------------------------------
// EXCEPTIONS ////////////////////////////////////////////////////////////
// ENUMS /////////////////////////////////////////////////////////////////
@@ -230,26 +262,30 @@ private: //-------------------------------------------------------------------
// LIFECYCLE /////////////////////////////////////////////////////////////
// METHODS ///////////////////////////////////////////////////////////////
// DATA MEMBERS ///////////////////////////////////////////////////////////
- /** The current context name */
- std::string m_ctxName;
- /** The configured procedure search path */
- std::string m_procPath;
- /** The configured library path */
- std::string m_libPath;
- /** Map of identifiers to names */
- ProcMap m_idToName;
- /** Map of names to identifiers */
- ProcMap m_nameToId;
- /** Map of filenames to identifiers */
- ProcMap m_filenameToId;
- /** Map of identifiers to filenames */
- ProcMap m_idToFilename;
- /** Map of identifiers and procedure models */
- ProcModels m_procModels;
- /** Map of identifiers and library models */
- LibModels m_libModels;
- /** Synchronization lock */
- SPELLmutex m_lock;
+ /** The current context name */
+ std::string m_ctxName;
+ /** The configured procedure search path */
+ std::string m_procPath;
+ /** The configured library path */
+ std::string m_libPath;
+ /** The configured service path */
+ std::string m_servicePath;
+ /** Map of identifiers to names */
+ ProcMap m_idToName;
+ /** Map of names to identifiers */
+ ProcMap m_nameToId;
+ /** Map of filenames to identifiers */
+ ProcMap m_filenameToId;
+ /** Map of identifiers to filenames */
+ ProcMap m_idToFilename;
+ /** Map of identifiers and procedure models */
+ ProcModels m_procModels;
+ /** Map of identifiers and Spell service models */
+ ServiceModelMap m_serviceModels;
+ /** Map of identifiers and library models */
+ LibModels m_libModels;
+ /** Synchronization lock */
+ SPELLmutex m_lock;
};
/*@}*/
diff --git a/include/SPELL_PRD/SPELLprocedureSourceCode.H b/include/SPELL_PRD/SPELLprocedureSourceCode.H
index 8375c09..0d5a250 100644
--- a/include/SPELL_PRD/SPELLprocedureSourceCode.H
+++ b/include/SPELL_PRD/SPELLprocedureSourceCode.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Procedure source code model
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -64,7 +64,6 @@ public: //--------------------------------------------------------------------
SPELLprocedureSourceCode( const std::string filename )
{
m_filename = filename;
- m_source = "";
m_sourceLines.clear();
}
@@ -80,23 +79,12 @@ public: //--------------------------------------------------------------------
return m_filename;
} ;
- //////////////////////////////////////////////////////////////////////
- /** Obtain the procedure source code.
- *
- * \returns The procedure source code.
- **////////////////////////////////////////////////////////////////////
- const std::string getSourceCode() const {
- return m_source;
- };
-
//////////////////////////////////////////////////////////////////////
/** Obtain the procedure source code lines.
*
* \returns The procedure source code lines.
**////////////////////////////////////////////////////////////////////
- const std::vector getSourceCodeLines() const {
- return m_sourceLines;
- };
+ const std::vector getSourceCodeLines();
// DATA MEMBERS //////////////////////////////////////////////////////////
@@ -119,7 +107,6 @@ protected: //-----------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
void addSourceCodeLine( const std::string& sourceLine )
{
- m_source += sourceLine + "\n";
m_sourceLines.push_back(sourceLine);
};
@@ -128,7 +115,6 @@ protected: //-----------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
void clear()
{
- m_source = "";
m_sourceLines.clear();
};
@@ -142,8 +128,6 @@ private: //-------------------------------------------------------------------
// DATA MEMBERS //////////////////////////////////////////////////////////
/** Procedure file name */
std::string m_filename;
- /** Procedure source code */
- std::string m_source;
/** Procedure source code splitted in lines */
std::vector m_sourceLines;
};
diff --git a/include/SPELL_PRD/SPELLpyService.H b/include/SPELL_PRD/SPELLpyService.H
new file mode 100644
index 0000000..9e2da78
--- /dev/null
+++ b/include/SPELL_PRD/SPELLpyService.H
@@ -0,0 +1,160 @@
+// ################################################################################
+// FILE : SPELLservice.H
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Service model
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+#ifndef __SPELL_PY_SERVICE_H__
+#define __SPELL_PY_SERVICE_H__
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// System includes ---------------------------------------------------------
+#include "SPELL_UTIL/SPELLbase.H"
+#include "SPELL_PRD/SPELLprocedureSourceCode.H"
+// Local includes ----------------------------------------------------------
+
+// Project includes --------------------------------------------------------
+
+/** \defgroup SPELL_PRD Service management (SPELL_PRD)
+ *
+ * This module provides mechanisms for reading procedure files and libraries,
+ * getting their source code and properties, etc.
+ *
+ * */
+/*@{*/
+
+// FORWARD REFERENCES //////////////////////////////////////////////////////
+// TYPES ///////////////////////////////////////////////////////////////////
+// DEFINES /////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+/**
+ ** \brief Model of a spell service.
+ **
+ ** \par Description and usage:
+ **
+ ** Used by the procedure manager to keep track of all available
+ ** services and their related information.
+ **
+ ** The SPELLprocedureManager creates one model per service found in
+ ** the service search path.
+ **
+ **////////////////////////////////////////////////////////////////////////////
+class SPELLpyService
+{
+public:
+ //--------------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////////
+ /** Constructor
+ *
+ * \param procPath IN: procedure path
+ * \param file IN: file name.
+ **////////////////////////////////////////////////////////////////////
+ SPELLpyService(PyObject* serviceImpl);
+
+ //////////////////////////////////////////////////////////////////////
+ /** Destructor
+ **////////////////////////////////////////////////////////////////////
+ ~SPELLpyService();
+
+ // STATIC ////////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+ std::string getName() const
+ {
+ return m_name;
+ }
+
+ std::string getBasePath() const
+ {
+ return m_basePath;
+ }
+ std::string getMainServiceFile() const
+ {
+ return m_mainServiceFile;
+ }
+
+ void setBasePath(std::string basePath)
+ {
+ m_basePath = basePath;
+ }
+
+ bool useCommandOverride() const;
+
+ std::string getCommandOverride(int startTimeout, int loginTimeout, std::string config, std::string contextName, int ipcPort, std::string instanceId,
+ std::string warmstartFile) const;
+
+ void startWatchDog(void (*callback)(std::string&));
+
+ void start();
+
+ PyObject* getStartFunction() const;
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+
+ PyObject* getService() const{
+ Py_INCREF(m_service);
+ return m_service;
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ /** Obtain the procedure source code.
+ *
+ * \returns The procedure source code.
+ **////////////////////////////////////////////////////////////////////
+ SPELLprocedureSourceCode getSourceCode() const {
+ return m_source;
+ };
+protected:
+ //-----------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+
+private:
+ //-------------------------------------------------------------------
+
+ // EXCEPTIONS ////////////////////////////////////////////////////////////
+ // ENUMS /////////////////////////////////////////////////////////////////
+ // TYPES /////////////////////////////////////////////////////////////////
+ // LIFECYCLE /////////////////////////////////////////////////////////////
+ // METHODS ///////////////////////////////////////////////////////////////
+ // DATA MEMBERS //////////////////////////////////////////////////////////
+ PyObject* m_service;
+ SPELLprocedureSourceCode m_source;
+ std::string m_name;
+ std::string m_basePath;
+ std::string m_mainServiceFile;
+};
+
+/*@}*/
+#endif
diff --git a/include/SPELL_PRD/SPELLservicePython.H b/include/SPELL_PRD/SPELLservicePython.H
new file mode 100644
index 0000000..f3379e7
--- /dev/null
+++ b/include/SPELL_PRD/SPELLservicePython.H
@@ -0,0 +1,59 @@
+// ################################################################################
+// FILE : SPELLSpellService.H
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Implementation of the SpellService mechanism
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+#ifndef __SPELL_SpellPyService_H__
+#define __SPELL_SpellPyService_H__
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// System includes ---------------------------------------------------------
+// Local includes ----------------------------------------------------------
+// Project includes --------------------------------------------------------
+#include "SPELL_UTIL/SPELLbase.H"
+
+/** \addtogroup SPELL_CTX */
+/*@{*/
+
+
+// FORWARD REFERENCES //////////////////////////////////////////////////////
+// TYPES ///////////////////////////////////////////////////////////////////
+
+/** Python binding for the SpellService object */
+typedef struct PySpellServiceObject_
+{
+ PyObject_HEAD;
+}
+PySpellServiceObject;
+
+
+/** Install the SpellService binding on the Python layer */
+void SpellService_Install();
+
+// DEFINES /////////////////////////////////////////////////////////////////
+
+
+
+/*@}*/
+#endif
diff --git a/include/SPELL_PRD/SPELLserviceWatchdogPython.H b/include/SPELL_PRD/SPELLserviceWatchdogPython.H
new file mode 100644
index 0000000..0bcecfb
--- /dev/null
+++ b/include/SPELL_PRD/SPELLserviceWatchdogPython.H
@@ -0,0 +1,57 @@
+// ################################################################################
+// FILE : SPELLSpellService.H
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Implementation of the SpellService mechanism
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+#ifndef __SPELL_SpellPyServiceWatchdog_H__
+#define __SPELL_SpellPyServiceWatchdog_H__
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// System includes ---------------------------------------------------------
+// Local includes ----------------------------------------------------------
+// Project includes --------------------------------------------------------
+#include "SPELL_UTIL/SPELLbase.H"
+
+/** \addtogroup SPELL_CTX */
+/*@{*/
+
+
+// FORWARD REFERENCES //////////////////////////////////////////////////////
+// TYPES ///////////////////////////////////////////////////////////////////
+
+/** Python binding for the SpellService object */
+typedef struct PySpellServiceWatchdogObject_
+{
+ PyObject_HEAD;
+ PyObject *callback;
+}
+PySpellServiceWatchdogObject;
+
+
+// DEFINES /////////////////////////////////////////////////////////////////
+PyObject* SpellServiceWatchdog_Create(void (*callback)(std::string&));
+
+
+/*@}*/
+#endif
diff --git a/include/SPELL_SDB/SPELLdatabase.H b/include/SPELL_SDB/SPELLdatabase.H
index d142567..8ccfd60 100644
--- a/include/SPELL_SDB/SPELLdatabase.H
+++ b/include/SPELL_SDB/SPELLdatabase.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Base class of SPELL databases
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SDB/SPELLdatabaseFactory.H b/include/SPELL_SDB/SPELLdatabaseFactory.H
index cf0109e..08aa558 100644
--- a/include/SPELL_SDB/SPELLdatabaseFactory.H
+++ b/include/SPELL_SDB/SPELLdatabaseFactory.H
@@ -5,7 +5,7 @@
// DESCRIPTION: SPELL database factory
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SDB/SPELLdatabaseFile.H b/include/SPELL_SDB/SPELLdatabaseFile.H
index 77e0dfd..8ab6e82 100644
--- a/include/SPELL_SDB/SPELLdatabaseFile.H
+++ b/include/SPELL_SDB/SPELLdatabaseFile.H
@@ -5,7 +5,7 @@
// DESCRIPTION: SPELL database based on local files
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SDB/SPELLdatabaseFileSPB.H b/include/SPELL_SDB/SPELLdatabaseFileSPB.H
index 94147e8..4b2e6b3 100644
--- a/include/SPELL_SDB/SPELLdatabaseFileSPB.H
+++ b/include/SPELL_SDB/SPELLdatabaseFileSPB.H
@@ -5,7 +5,7 @@
// DESCRIPTION: SPELL database based on SPB local files
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SDB/SPELLpyDatabaseObject.H b/include/SPELL_SDB/SPELLpyDatabaseObject.H
index 03daf22..f3f2765 100644
--- a/include/SPELL_SDB/SPELLpyDatabaseObject.H
+++ b/include/SPELL_SDB/SPELLpyDatabaseObject.H
@@ -5,7 +5,7 @@
// DESCRIPTION: SPELL database Python extension
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -218,8 +218,7 @@ PyObject* SPELLpyDatabase_IterLen( PyDatabaseIteratorObject* iterator );
#define DATABASE_DEFINITION(__type__,__name__,__doc__) \
static PyTypeObject __type__ = \
{ \
- PyObject_HEAD_INIT(NULL) /* basic object head */ \
- 0, /* var objects */ \
+ PyVarObject_HEAD_INIT(NULL,0) /* basic object head */ \
__name__, /* type name */ \
sizeof(PyDatabaseObject), /* type size */ \
0, /* item size */ \
@@ -278,7 +277,7 @@ PyObject* SPELLpyDatabase_IterLen( PyDatabaseIteratorObject* iterator );
err += std::string(__type__.tp_name); \
PyErr_SetString( PyExc_RuntimeError, err.c_str()); \
std::cerr << "ERROR: " << err << std::endl; \
- return; \
+ return MOD_ERROR_VAL; \
}
/** Convenience macro to load a new type into the given module */
diff --git a/include/SPELL_SYN/SPELLcondition.H b/include/SPELL_SYN/SPELLcondition.H
index d743eaa..6f3b592 100644
--- a/include/SPELL_SYN/SPELLcondition.H
+++ b/include/SPELL_SYN/SPELLcondition.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Condition mechanism wrapper
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SYN/SPELLconditionFactory.H b/include/SPELL_SYN/SPELLconditionFactory.H
index 126e797..424fd6a 100644
--- a/include/SPELL_SYN/SPELLconditionFactory.H
+++ b/include/SPELL_SYN/SPELLconditionFactory.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Factory of conditions
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SYN/SPELLconditionIF.H b/include/SPELL_SYN/SPELLconditionIF.H
index 9ed1ba5..9152569 100644
--- a/include/SPELL_SYN/SPELLconditionIF.H
+++ b/include/SPELL_SYN/SPELLconditionIF.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Condition interface definition
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SYN/SPELLconditionPOSIX.H b/include/SPELL_SYN/SPELLconditionPOSIX.H
index 0a58d31..963bb44 100644
--- a/include/SPELL_SYN/SPELLconditionPOSIX.H
+++ b/include/SPELL_SYN/SPELLconditionPOSIX.H
@@ -5,7 +5,7 @@
// DESCRIPTION: POSIX implementation of condition mechanism
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SYN/SPELLevent.H b/include/SPELL_SYN/SPELLevent.H
index cae3c52..bba34a5 100644
--- a/include/SPELL_SYN/SPELLevent.H
+++ b/include/SPELL_SYN/SPELLevent.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Event mechanism
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SYN/SPELLmonitor.H b/include/SPELL_SYN/SPELLmonitor.H
index 428e9eb..6aacfec 100644
--- a/include/SPELL_SYN/SPELLmonitor.H
+++ b/include/SPELL_SYN/SPELLmonitor.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Monitor mechanism
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SYN/SPELLmutex.H b/include/SPELL_SYN/SPELLmutex.H
index 50ef616..23ce473 100644
--- a/include/SPELL_SYN/SPELLmutex.H
+++ b/include/SPELL_SYN/SPELLmutex.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Mutex mechanism
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SYN/SPELLmutexFactory.H b/include/SPELL_SYN/SPELLmutexFactory.H
index 136a6aa..762a0c7 100644
--- a/include/SPELL_SYN/SPELLmutexFactory.H
+++ b/include/SPELL_SYN/SPELLmutexFactory.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Factory for mutexes
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SYN/SPELLmutexIF.H b/include/SPELL_SYN/SPELLmutexIF.H
index 88d5122..0a4014a 100644
--- a/include/SPELL_SYN/SPELLmutexIF.H
+++ b/include/SPELL_SYN/SPELLmutexIF.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Mutex interface definition
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SYN/SPELLmutexPOSIX.H b/include/SPELL_SYN/SPELLmutexPOSIX.H
index 1661028..7690dcc 100644
--- a/include/SPELL_SYN/SPELLmutexPOSIX.H
+++ b/include/SPELL_SYN/SPELLmutexPOSIX.H
@@ -5,7 +5,7 @@
// DESCRIPTION: POSIX implementation for mutex
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SYN/SPELLqueue.H b/include/SPELL_SYN/SPELLqueue.H
index f7facce..6cf7485 100644
--- a/include/SPELL_SYN/SPELLqueue.H
+++ b/include/SPELL_SYN/SPELLqueue.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Queue mechanism
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SYN/SPELLsyncError.H b/include/SPELL_SYN/SPELLsyncError.H
index cc9bbdc..f9cb76b 100644
--- a/include/SPELL_SYN/SPELLsyncError.H
+++ b/include/SPELL_SYN/SPELLsyncError.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Synchronization error
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SYN/SPELLthread.H b/include/SPELL_SYN/SPELLthread.H
index d6dd68e..63aa5d3 100644
--- a/include/SPELL_SYN/SPELLthread.H
+++ b/include/SPELL_SYN/SPELLthread.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Thread mechanism
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SYN/SPELLthreadPool.H b/include/SPELL_SYN/SPELLthreadPool.H
index 933f377..bb21ddc 100644
--- a/include/SPELL_SYN/SPELLthreadPool.H
+++ b/include/SPELL_SYN/SPELLthreadPool.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Thread pool mechanism
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SYN/SPELLthreadWork.H b/include/SPELL_SYN/SPELLthreadWork.H
index f50e641..1d57c2b 100644
--- a/include/SPELL_SYN/SPELLthreadWork.H
+++ b/include/SPELL_SYN/SPELLthreadWork.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Thread worker for thread pools
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SYN/SPELLthreadWorker.H b/include/SPELL_SYN/SPELLthreadWorker.H
index af6c14c..d60e2c5 100644
--- a/include/SPELL_SYN/SPELLthreadWorker.H
+++ b/include/SPELL_SYN/SPELLthreadWorker.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Thread worker for thread pools
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_SYN/SPELLtimer.H b/include/SPELL_SYN/SPELLtimer.H
index e7c0e05..975b7ac 100644
--- a/include/SPELL_SYN/SPELLtimer.H
+++ b/include/SPELL_SYN/SPELLtimer.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Timer mechanism
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_UTIL/SPELLbase.H b/include/SPELL_UTIL/SPELLbase.H
index 8e8a32a..3b2c062 100644
--- a/include/SPELL_UTIL/SPELLbase.H
+++ b/include/SPELL_UTIL/SPELLbase.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Base includes for SPELL framework
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -58,6 +58,7 @@
#include
#include
#include
+#include
#include "log4cplus/appender.h"
#include "log4cplus/fileappender.h"
#include "log4cplus/layout.h"
@@ -89,5 +90,50 @@
// DEFINES /////////////////////////////////////////////////////////////////
#define BYTE unsigned char
+//Python 3 Compatibility
+#if PY_MAJOR_VERSION >= 3
+#define PyString_AsString PyUnicode_AsUTF8
+#define PyString_CheckExact PyUnicode_CheckExact
+#define PyString_FromString PyUnicode_FromString
+#define PyString_Check PyUnicode_Check
+#define PyString_Size PyUnicode_GetLength
+#define PyString_AsStringAndSize PyBytes_AsStringAndSize
+#define CHAR wchar_t
+#define PyInt_Check PyLong_Check
+#define PyInt_AsLong PyLong_AsLong
+#define PyInt_FromSize_t PyLong_FromSize_t
+#define PyInt_FromLong PyLong_FromLong
+#define PyClass_Check(value) PyObject_IsInstance(value, (PyObject *)&PyType_Type)
+#define PyInstance_Check(value) PyObject_IsInstance(value, (PyObject *)&PyBaseObject_Type)
+#define PyInt_CheckExact PyLong_CheckExact
+#define PyInt_AS_LONG PyLong_AS_LONG
+
+#define PyFloat_FromString(floatObj,pend) PyFloat_FromString(floatObj)
+
+#define PyEval_EvalCode(code,globals,locals) PyEval_EvalCode((PyObject*)code,globals,locals)
+
+#define MOD_ERROR_VAL NULL
+#define MOD_SUCCESS_VAL(val) val
+#define MOD_NAME(name) #name"_v3"
+#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name##_v3(void)
+#define MOD_DEF(ob, name, doc, methods) \
+ static struct PyModuleDef moduledef = { \
+ PyModuleDef_HEAD_INIT, name, doc, -1, methods, }; \
+ ob = PyModule_Create(&moduledef); \
+ if (ob == NULL) \
+ return NULL;
+#define BUILTINS "builtins"
+#else
+#define BUILTINS "__builtin__"
+#define CHAR char
+#define MOD_ERROR_VAL
+#define MOD_SUCCESS_VAL(val)
+#define MOD_NAME(name) #name"_v2"
+#define MOD_INIT(name) PyMODINIT_FUNC init##name##_v2(void)
+#define MOD_DEF(ob, name, doc, methods) \
+ ob = Py_InitModule3(name, methods, doc);
+#define _Py_CODEUNIT unsigned char
+#endif
+
/*@}*/
#endif
diff --git a/include/SPELL_UTIL/SPELLcompression.H b/include/SPELL_UTIL/SPELLcompression.H
index 17bd5d6..5d03267 100644
--- a/include/SPELL_UTIL/SPELLcompression.H
+++ b/include/SPELL_UTIL/SPELLcompression.H
@@ -5,7 +5,7 @@
// DESCRIPTION: General utilities
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_UTIL/SPELLerror.H b/include/SPELL_UTIL/SPELLerror.H
index e4b9eb9..58e7014 100644
--- a/include/SPELL_UTIL/SPELLerror.H
+++ b/include/SPELL_UTIL/SPELLerror.H
@@ -5,7 +5,7 @@
// DESCRIPTION: SPELL core exceptions
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/include/SPELL_UTIL/SPELLlog.H b/include/SPELL_UTIL/SPELLlog.H
index eb9a582..9a94602 100644
--- a/include/SPELL_UTIL/SPELLlog.H
+++ b/include/SPELL_UTIL/SPELLlog.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Executor logging mechanism
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -30,6 +30,7 @@
// FILES TO INCLUDE ////////////////////////////////////////////////////////
// Local includes ----------------------------------------------------------
// Project includes --------------------------------------------------------
+#include "SPELL_UTIL/SPELLutils.H"
#include "SPELL_SYN/SPELLmutex.H"
// System includes ---------------------------------------------------------
@@ -202,19 +203,19 @@ static const std::string LOG_LEVEL_LBL[] =
** \brief Log an information message.
**
*////////////////////////////////////////////////////////////////////////////
-#define LOG_INFO(x) log4cplus::Logger::getRoot().log(log4cplus::INFO_LOG_LEVEL, x, __FILE__, __LINE__ )
+#define LOG_INFO(x) log4cplus::Logger::getRoot().log(log4cplus::INFO_LOG_LEVEL, x, __FILE__, __LINE__, NULL )
//////////////////////////////////////////////////////////////////////////////
/**
** \brief Log a warning message.
**
*////////////////////////////////////////////////////////////////////////////
-#define LOG_WARN(x) log4cplus::Logger::getRoot().log(log4cplus::WARN_LOG_LEVEL, x, __FILE__, __LINE__ )
+#define LOG_WARN(x) log4cplus::Logger::getRoot().log(log4cplus::WARN_LOG_LEVEL, x, __FILE__, __LINE__, NULL )
//////////////////////////////////////////////////////////////////////////////
/**
** \brief Log an error message.
**
*////////////////////////////////////////////////////////////////////////////
-#define LOG_ERROR(x) log4cplus::Logger::getRoot().log(log4cplus::ERROR_LOG_LEVEL, x, __FILE__, __LINE__ )
+#define LOG_ERROR(x) log4cplus::Logger::getRoot().log(log4cplus::ERROR_LOG_LEVEL, x, __FILE__, __LINE__, NULL )
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -242,8 +243,9 @@ static const std::string LOG_LEVEL_LBL[] =
** the \c WITH_DEBUG macro is defined.
**
*////////////////////////////////////////////////////////////////////////////
+
#ifdef WITH_DEBUG
-#define DEBUG(x) log4cplus::Logger::getRoot().log(log4cplus::DEBUG_LOG_LEVEL, x, __FILE__, __LINE__ )
+#define DEBUG(x) log4cplus::Logger::getRoot().log(log4cplus::DEBUG_LOG_LEVEL, x, __FILE__, __LINE__ );
#else
#define DEBUG(x)
#endif
diff --git a/include/SPELL_UTIL/SPELLpyArgs.H b/include/SPELL_UTIL/SPELLpyArgs.H
index e07eb4b..a092f15 100644
--- a/include/SPELL_UTIL/SPELLpyArgs.H
+++ b/include/SPELL_UTIL/SPELLpyArgs.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Utility for Python arguments processing
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -30,6 +30,7 @@
// FILES TO INCLUDE ////////////////////////////////////////////////////////
// Local includes ----------------------------------------------------------
// Project includes --------------------------------------------------------
+#include "SPELL_UTIL/SPELLutils.H"
#include "SPELL_UTIL/SPELLtime.H"
// System includes ---------------------------------------------------------
@@ -234,6 +235,20 @@ public: //--------------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
std::string getModifier_HiYel() const;
+ //////////////////////////////////////////////////////////////////////
+ /** Obtain the value of the Select modifier.
+ *
+ * \return The modifier value.
+ **////////////////////////////////////////////////////////////////////
+ std::string getModifier_Select() const;
+
+ //////////////////////////////////////////////////////////////////////
+ /** Obtain the value of the Type modifier for Limits.
+ *
+ * \return The modifier value.
+ **////////////////////////////////////////////////////////////////////
+ std::string getModifier_LimitType() const;
+
//////////////////////////////////////////////////////////////////////
/** Obtain the value of the Message modifier.
*
@@ -288,6 +303,7 @@ public: //--------------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
std::string getModifier_Default() const;
+
// DATA MEMBERS //////////////////////////////////////////////////////////
protected: //-----------------------------------------------------------------
diff --git a/include/SPELL_UTIL/SPELLpythonHelper.H b/include/SPELL_UTIL/SPELLpythonHelper.H
index 7bdecca..8c56fba 100644
--- a/include/SPELL_UTIL/SPELLpythonHelper.H
+++ b/include/SPELL_UTIL/SPELLpythonHelper.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Python utilities and manipulation functions
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -118,6 +118,18 @@ public: //--------------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
void importAllFrom( const std::string& package );
+ //////////////////////////////////////////////////////////////////////
+ /** Import all items from the given package into the builtins package.
+ *
+ * \throws SPELLcoreException if the given module cannot be imported.
+ * \throws SPELLcoreException if the __main__ module cannot be accessed.
+ * \throws SPELLcoreException if the __main__ module dictionary cannot be accessed.
+ *
+ * \param package IN: the package to import objects from.
+ **////////////////////////////////////////////////////////////////////
+ void updateBuiltinsWith( const std::string& package );
+
+
//////////////////////////////////////////////////////////////////////
/** Import an user library module
*
@@ -127,7 +139,7 @@ public: //--------------------------------------------------------------------
*
* \param package IN: the package to import objects from.
**////////////////////////////////////////////////////////////////////
- void importUserLibraries( const std::string& libraryPath );
+ bool importUserLibraries( const std::string& libraryPath, std::string& errors );
//////////////////////////////////////////////////////////////////////
/** Install an object in main dictionary
@@ -210,7 +222,9 @@ public: //--------------------------------------------------------------------
**////////////////////////////////////////////////////////////////////
PyFrameObject* createFrame( const std::string& filename, PyCodeObject* code );
- //////////////////////////////////////////////////////////////////////
+ PyFrameObject* createFrameFromFunction( const std::string& filename, PyObject* func );
+
+ //////////////////////////////////////////////////////////////////////
/** Call the given method of the given object, with variable arguments
*
* \param obj IN: object providing the desired method.
diff --git a/include/SPELL_UTIL/SPELLpythonMonitors.H b/include/SPELL_UTIL/SPELLpythonMonitors.H
index 5eba813..3d9add8 100644
--- a/include/SPELL_UTIL/SPELLpythonMonitors.H
+++ b/include/SPELL_UTIL/SPELLpythonMonitors.H
@@ -5,7 +5,7 @@
// DESCRIPTION: Python safe operation monitors
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -59,14 +59,71 @@ class SPELLsafePythonOperations
public:
SPELLsafePythonOperations( const std::string& where )
{
- //std::cerr << "PYTHON OPERATIONS IN " << where << std::endl;
+ //std::cerr << "PYTHON OPERATIONS TRY-IN " << where << std::endl;
m_state = SPELLpythonHelper::instance().acquireGIL();
+ //std::cerr << ">>PYTHON OPERATIONS IN " << where << std::endl;
m_where = where;
};
- ~SPELLsafePythonOperations()
+ virtual ~SPELLsafePythonOperations() noexcept(false)
{
+ PyObject* err = PyErr_Occurred();
+ if (err != NULL)
+ {
+ std::cerr << std::endl << "===============================" << std::endl;
+ //PyErr_Print();
+ PyObject* ptype;
+ PyObject* pvalue;
+ PyObject* ptraceback;
+ PyErr_Fetch( &ptype, &pvalue, &ptraceback );
+ std::cerr << "TYPE : " << PYREPR(ptype) << std::endl;
+ std::cerr << "VALUE: " << PYREPR(pvalue) << std::endl;
+ if (ptraceback)
+ {
+ std::cerr << "Traceback: " << std::endl;
+ PyTracebackObject* traceback = (PyTracebackObject*) ptraceback;
+ while(traceback != NULL)
+ {
+ std::cerr << "at " << PYREPR(traceback->tb_frame->f_code->co_filename) << ":" << traceback->tb_lineno << std::endl;
+ traceback = traceback->tb_next;
+ }
+ }
+ std::cerr << "===============================" << std::endl << std::endl;
+ // Parse the exception to give better information about the error on python side
+ PyObject* spellException = SPELLpythonHelper::instance().getObject("spell.lib.exception", "SpellException");
+ std::string excType = PYREPR(ptype);
+ if (PyObject_IsInstance( pvalue, spellException ))
+ {
+ PyObject* msg = PyObject_GetAttrString( pvalue, "message" );
+ PyObject* rea = PyObject_GetAttrString( pvalue, "reason" );
+ std::string message = "";
+ std::string reason = "";
+ if (msg != NULL)
+ {
+ message = PYSSTR(msg);
+ }
+ if (rea != NULL )
+ {
+ reason = PYSSTR(rea);
+ }
+ /** \todo decide the fatal flag value */
+ std::cerr << "RAISING INTERNAL DRIVER EXCEPTION" << std::endl;
+ PyErr_Clear();
+ THROW_EXCEPTION("Driver error: " + message, reason, SPELL_DRIVER_ERROR );
+ }
+ else if ( PYSTR(pvalue) == "EXECUTION ABORTED" || PYSTR(pvalue) == "EXECUTION TERMINATED" )
+ {
+ // Do not raise exceptions if the detected exception is an aborted or finished internal exception
+ return;
+ }
+ else
+ {
+ std::cerr << "RAISING PYTHON ERROR EXCEPTION" << std::endl;
+ PyErr_Clear();
+ THROW_EXCEPTION("Python error", PYSSTR(PyObject_Str(pvalue)), SPELL_ERROR_PYTHON_API );
+ }
+ }
SPELLpythonHelper::instance().releaseGIL(m_state);
- //std::cerr << "PYTHON OPERATIONS OUT " << m_where << std::endl;
+ //std::cerr << "<.
+#
+################################################################################
-if WITH_LIBS
SUBDIRS = SPELL_UTIL \
SPELL_SYN \
SPELL_CFG \
@@ -13,22 +31,8 @@ SUBDIRS = SPELL_UTIL \
SPELL_SDB \
SPELL_DTA \
SPELL_EXC \
- SPELL_WS
-
-if WITH_EXECUTOR
-SUBDIRS += SPELL_CIFS
-endif
-
-if WITH_EXECUTOR_CMD
-SUBDIRS += SPELL_CIFC
-endif
-
-if WITH_CONTEXT
-SUBDIRS += SPELL_CTX
-endif
-
-if WITH_LISTENER
-SUBDIRS += SPELL_LST
-endif
-
-endif
+ SPELL_WS \
+ SPELL_CIFS \
+ SPELL_CIFC \
+ SPELL_CTX \
+ SPELL_LST
diff --git a/lib/SPELL_CFG/Makefile.am b/lib/SPELL_CFG/Makefile.am
index 1b326a2..d8a92f2 100644
--- a/lib/SPELL_CFG/Makefile.am
+++ b/lib/SPELL_CFG/Makefile.am
@@ -1,37 +1,47 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
include ${top_srcdir}/common.mk
-lib_LTLIBRARIES= libSPELL_CFG.la
-libSPELL_CFG_la_LDFLAGS = -version-info 3:0:0
-libSPELL_CFG_la_SOURCES = \
- src/SPELLxmlConfigReaderFactory.C \
- src/SPELLxmlConfigReaderXC.C \
- src/SPELLconfiguration.C \
- src/SPELLcontextConfig.C \
- src/SPELLdriverConfig.C \
- src/SPELLbrowsableLibMode.C
-
+
+lib_LTLIBRARIES = libSPELL_CFG_v2.la libSPELL_CFG_v3.la
+
+libSPELL_CFG_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+
+libSPELL_CFG_v2_la_CDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_CFG_v2_la_SOURCES = src/SPELLxmlConfigReaderFactory.C \
+ src/SPELLxmlConfigReaderXC.C \
+ src/SPELLconfiguration.C \
+ src/SPELLcontextConfig.C \
+ src/SPELLdriverConfig.C \
+ src/SPELLbrowsableLibMode.C
+
+
+libSPELL_CFG_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS}
+
+libSPELL_CFG_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_CFG_v3_la_SOURCES = src/SPELLxmlConfigReaderFactory.C \
+ src/SPELLxmlConfigReaderXC.C \
+ src/SPELLconfiguration.C \
+ src/SPELLcontextConfig.C \
+ src/SPELLdriverConfig.C \
+ src/SPELLbrowsableLibMode.C
\ No newline at end of file
diff --git a/lib/SPELL_CFG/src/SPELLbrowsableLibMode.C b/lib/SPELL_CFG/src/SPELLbrowsableLibMode.C
index e819ae1..4d48f74 100644
--- a/lib/SPELL_CFG/src/SPELLbrowsableLibMode.C
+++ b/lib/SPELL_CFG/src/SPELLbrowsableLibMode.C
@@ -5,7 +5,7 @@
// DESCRIPTION:
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -39,9 +39,6 @@ std::string s_BROWSABLELIB_MODE_STR[] =
"Disabled"
};
-unsigned int s_NUM_MODES = sizeof(s_BROWSABLELIB_MODE_STR) / sizeof(std::string);
-
-
// Methods
@@ -51,6 +48,7 @@ unsigned int s_NUM_MODES = sizeof(s_BROWSABLELIB_MODE_STR) / sizeof(std::string)
SPELLbrowsableLibMode stringToBrowsableLibMode( const std::string& mode )
{
unsigned int index = 0;
+ unsigned int s_NUM_MODES = sizeof(s_BROWSABLELIB_MODE_STR) / sizeof(std::string);
for( index = 0; index < s_NUM_MODES; index++)
{
diff --git a/lib/SPELL_CFG/src/SPELLconfiguration.C b/lib/SPELL_CFG/src/SPELLconfiguration.C
index 7ba8d4c..50f1fb1 100644
--- a/lib/SPELL_CFG/src/SPELLconfiguration.C
+++ b/lib/SPELL_CFG/src/SPELLconfiguration.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the configuration reader
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_CFG/src/SPELLcontextConfig.C b/lib/SPELL_CFG/src/SPELLcontextConfig.C
index 2553e19..725e9c8 100644
--- a/lib/SPELL_CFG/src/SPELLcontextConfig.C
+++ b/lib/SPELL_CFG/src/SPELLcontextConfig.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the context configuration model
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -37,6 +37,7 @@
// GLOBALS /////////////////////////////////////////////////////////////////
const std::string SPELLcontextConfig::ExecutorProgram = "ExecutorProgram";
+const std::string SPELLcontextConfig::ServiceProgram = "ServiceProgram";
const std::string SPELLcontextConfig::ExecutorStartTimeout = "ExecutorStartTimeout";
const std::string SPELLcontextConfig::ExecutorLoginTimeout = "ExecutorLoginTimeout";
const std::string SPELLcontextConfig::UseDriverTime = "UseDriverTime";
@@ -57,6 +58,7 @@ SPELLcontextConfig::SPELLcontextConfig( const std::string& contextFile )
m_gcs = "unknown";
m_family = "unknown";
m_procPath = "unknown";
+ m_servicePath = "unknown";
m_libPath = "unknown";
m_outputDir = "";
m_inputDir = "";
@@ -178,6 +180,18 @@ void SPELLcontextConfig::loadBasics()
m_libPath = "";
}
+ list = m_reader->findElementsByName( XMLTags::TAG_CTX_SPATH );
+ if (list.size()==1)
+ {
+ node = *(list.begin());
+ m_servicePath = node->getValue();
+ dealloc_list(list);
+ }
+ else
+ {
+ m_servicePath = "Services";
+ }
+
list = m_reader->findElementsByName( XMLTags::TAG_CTX_OPATH );
if (list.size()==1)
{
diff --git a/lib/SPELL_CFG/src/SPELLdriverConfig.C b/lib/SPELL_CFG/src/SPELLdriverConfig.C
index 69668a3..186a661 100644
--- a/lib/SPELL_CFG/src/SPELLdriverConfig.C
+++ b/lib/SPELL_CFG/src/SPELLdriverConfig.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the driver configuration model
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_CFG/src/SPELLexecutorDefaults.C b/lib/SPELL_CFG/src/SPELLexecutorDefaults.C
index 56db148..abc9e93 100644
--- a/lib/SPELL_CFG/src/SPELLexecutorDefaults.C
+++ b/lib/SPELL_CFG/src/SPELLexecutorDefaults.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the context execution defaults.
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -42,14 +42,17 @@ SPELLexecutorDefaults::SPELLexecutorDefaults( const SPELLexecutorDefaults& from
LOG_INFO("[CTX] Copied Executor Defaults for " + m_ctxName);
m_execDelay = from.getExecDelay();
- m_promptWarningDelay = from.getpromptWarningDelay();
+ m_promptWarningDelay = from.getPromptWarningDelay();
m_runInto = from.isRunInto();
m_byStep = from.isByStep();
m_browsableLib = from.getBrowsableLib();
m_maxVerbosity = from.getMaxVerbosity();
- m_forceTcConfirm = from.getForceTcConfirm();
+ m_forceTcConfirm = from.isForceTcConfirm();
+ m_forcePromptConfirm = from.isForcePromptConfirm();
m_saveStateMode = from.getSaveStateMode();
m_watchVariables = from.isWatchVariables();
+ m_resourcesDisplay = from.isResourcesDisplay();
+ m_localResourceSupport = from.isLocalResourcesSupported();
m_ctxName = from.getCtxName();
} //copy constructor
diff --git a/lib/SPELL_CFG/src/SPELLxmlConfigReaderFactory.C b/lib/SPELL_CFG/src/SPELLxmlConfigReaderFactory.C
index af1c71e..cd6c56c 100644
--- a/lib/SPELL_CFG/src/SPELLxmlConfigReaderFactory.C
+++ b/lib/SPELL_CFG/src/SPELLxmlConfigReaderFactory.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the configuration reader factory
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_CFG/src/SPELLxmlConfigReaderXC.C b/lib/SPELL_CFG/src/SPELLxmlConfigReaderXC.C
index ae370df..7638235 100644
--- a/lib/SPELL_CFG/src/SPELLxmlConfigReaderXC.C
+++ b/lib/SPELL_CFG/src/SPELLxmlConfigReaderXC.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the configuration reader with Xerces-C
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_CIF/Makefile.am b/lib/SPELL_CIF/Makefile.am
index ab595e1..1e1fa1f 100644
--- a/lib/SPELL_CIF/Makefile.am
+++ b/lib/SPELL_CIF/Makefile.am
@@ -1,35 +1,46 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
include ${top_srcdir}/common.mk
-lib_LTLIBRARIES= libSPELL_CIF.la
-libSPELL_CIF_la_LDFLAGS = -version-info 3:0:0
-libSPELL_CIF_la_SOURCES = \
- src/SPELLcif.C \
- src/SPELLcifPython.C \
- src/SPELLcifHelper.C \
- src/SPELLasRun.C \
- src/SPELLnotifications.C
+
+lib_LTLIBRARIES = libSPELL_CIF_v2.la libSPELL_CIF_v3.la
+
+libSPELL_CIF_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+
+libSPELL_CIF_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_CIF_v2_la_SOURCES = src/SPELLcif.C \
+ src/SPELLcifPython.C \
+ src/SPELLcifHelper.C \
+ src/SPELLasRun.C \
+ src/SPELLnotifications.C
+
+libSPELL_CIF_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS}
+
+libSPELL_CIF_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_CIF_v3_la_SOURCES = src/SPELLcif.C \
+ src/SPELLcifPython.C \
+ src/SPELLcifHelper.C \
+ src/SPELLasRun.C \
+ src/SPELLnotifications.C
+
+
\ No newline at end of file
diff --git a/lib/SPELL_CIF/src/SPELLasRun.C b/lib/SPELL_CIF/src/SPELLasRun.C
index aa739ac..d7e5ba2 100644
--- a/lib/SPELL_CIF/src/SPELLasRun.C
+++ b/lib/SPELL_CIF/src/SPELLasRun.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the As-RUN interface
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_CIF/src/SPELLcif.C b/lib/SPELL_CIF/src/SPELLcif.C
index 525a289..2468767 100644
--- a/lib/SPELL_CIF/src/SPELLcif.C
+++ b/lib/SPELL_CIF/src/SPELLcif.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the CIF
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -56,8 +56,9 @@ SPELLcif::SPELLcif()
m_ctxName = "";
m_ctxPort = 0;
m_notificationsEnabled = true;
-
+ m_forcePromptConfirm = false;
m_finishEvent.clear();
+ m_errorState = false;
}
//=============================================================================
@@ -135,6 +136,15 @@ void SPELLcif::setVerbosity( int verbosity )
{
m_verbosity = verbosity;
}
+
+//=============================================================================
+// METHOD : SPELLcif::setVerbosity
+//=============================================================================
+void SPELLcif::setForcePromptConfirm( bool force )
+{
+ m_forcePromptConfirm = force;
+}
+
//=============================================================================
// METHOD : SPELLcif::setVerbosityFilter
//=============================================================================
@@ -188,6 +198,8 @@ const int SPELLcif::getVerbosityFilter() const
//=============================================================================
const std::string SPELLcif::getProcId() const
{
+ if (m_procId.find("#") == std::string::npos)
+ return m_procId + "#0";
return m_procId;
}
@@ -450,24 +462,53 @@ void SPELLcif::error( const std::string& msg, unsigned int scope )
//=============================================================================
// METHOD: SPELLcif::prompt
//=============================================================================
-std::string SPELLcif::prompt( const SPELLpromptDefinition& def )
+std::string SPELLcif::prompt( const SPELLpromptDefinition& def ,bool doPromptConfirm /* = true*/)
{
- // Local variables
+ bool canExit = true;
std::string answerToShow= "";
std::string rawAnswer = "";
-
- // Debug trace
- DEBUG("[CIF] Prompt message");
-
- // Write the prompt in the asrun
- m_asRun->writePrompt( getStack(), def );
-
- //Run Implementation Specifics
- specificPrompt( def, rawAnswer, answerToShow );
-
- // Write the answer in asrun
- m_asRun->writeAnswer( getStack(), rawAnswer, def.scope );
-
+ // Local variables
+ do {
+ // Debug trace
+ canExit = true;
+ DEBUG("[CIF] Prompt message");
+
+ // Write the prompt in the asrun
+ m_asRun->writePrompt( getStack(), def );
+
+ //Run Implementation Specifics
+ specificPrompt( def, rawAnswer, answerToShow );
+
+ // Write the answer in asrun
+ if ( (def.typecode & LanguageConstants::PROMPT_PASSWORD)>0)
+ m_asRun->writeAnswer( getStack(), "***", def.scope );
+ else
+ m_asRun->writeAnswer( getStack(), answerToShow, def.scope );
+
+ if (m_forcePromptConfirm && doPromptConfirm)
+ {
+ DEBUG("[CIF] Prompt Confirm message");
+ SPELLpromptDefinition confirmPromptDefiniton;
+ confirmPromptDefiniton.message = "The answer '" + answerToShow + "' was provided for the previous Prompt.\nIs this value correct?";
+ confirmPromptDefiniton.options.push_back("YES");
+ confirmPromptDefiniton.options.push_back("NO");
+ confirmPromptDefiniton.expected.push_back("YES");
+ confirmPromptDefiniton.expected.push_back("NO");
+ confirmPromptDefiniton.scope = def.scope;
+ confirmPromptDefiniton.typecode = 128;
+
+ std::string confirmResult = this->prompt(confirmPromptDefiniton,false);
+
+ if (confirmResult != "YES")
+ {
+ canExit = false;
+ }
+ else
+ {
+ canExit = true;
+ }
+ }
+ } while (!canExit);
return answerToShow;
} //std::string SPELLcif::prompt( const SPELLpromptDefinition& definition )
@@ -485,6 +526,7 @@ void SPELLcif::canClose()
//=============================================================================
void SPELLcif::waitClose()
{
+ SPELLsafeThreadOperations ops("waitClose");
m_finishEvent.wait();
}
@@ -560,6 +602,23 @@ void SPELLcif::notifyVariableScopeChange( const std::string& scopeName,
}
+//=============================================================================
+// METHOD: SPELLcif::notifyResourceChange()
+//=============================================================================
+void SPELLcif::notifyResourceChange( const std::vector& changed )
+{
+ specificNotifyResourceChange( changed );
+}
+
+//=============================================================================
+// METHOD: SPELLcif::notifyResourceList()
+//=============================================================================
+void SPELLcif::notifyResourceList( const std::vector& resources )
+{
+ specificNotifyResourceList( resources );
+}
+
+
//=============================================================================
// METHOD: SPELLcif::openSubprocedure
//=============================================================================
diff --git a/lib/SPELL_CIF/src/SPELLcifHelper.C b/lib/SPELL_CIF/src/SPELLcifHelper.C
index 8437191..923d33b 100644
--- a/lib/SPELL_CIF/src/SPELLcifHelper.C
+++ b/lib/SPELL_CIF/src/SPELLcifHelper.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the CIF helper
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -360,6 +360,9 @@ std::string SPELLcifHelper::getResult( const std::string& result, const SPELLpro
if ((def.options.size()>0))
{
int optionIndex = STRI(result);
+ if (optionIndex < 0 || (unsigned)optionIndex >= def.options.size()){
+ return "";
+ }
// Conversion LIST|ALPHA
if ( (def.typecode & LanguageConstants::PROMPT_ALPHA)>0)
{
@@ -411,6 +414,7 @@ std::string SPELLcifHelper::getResult( const std::string& result, const SPELLpro
}
break;
}
+
return promptResult;
}
@@ -477,15 +481,15 @@ std::string SPELLcifHelper::commandLinePrompt( const SPELLpromptDefinition& def,
if (def.options.size()>0)
{
SPELLpromptDefinition::Options::const_iterator eit;
- int count = 0;
+ unsigned int count = 0;
for( eit = def.expected.begin(); eit != def.expected.end(); eit++)
{
if (*eit == answer )
{
- if (useRaw)
- {
- answer = ISTR(count);
- }
+// if (useRaw)
+// {
+// answer = ISTR(count);
+// }
keepTrying = false;
break;
}
@@ -498,7 +502,8 @@ std::string SPELLcifHelper::commandLinePrompt( const SPELLpromptDefinition& def,
for( eit = def.expected.begin(); eit != def.expected.end(); eit++)
{
std::cout << " " << (*eit);
- if (countob_type->tp_free( (PyObject*) self );
+ Py_TYPE(self)->tp_free( (PyObject*) self );
}
//============================================================================
@@ -307,6 +314,33 @@ static PyObject* ClientIF_ResetVerbosity( PyObject* self, PyObject* args )
Py_RETURN_NONE;
}
+static PyObject* ClientIF_ForcePromptConfirm( PyObject* self, PyObject* args )
+{
+ SPELLpyArgs pargs(args);
+ bool forcePromptConfirm = false;
+
+ if (pargs.size()>0)
+ {
+ PyObject* pyForcePrompt = pargs[0];
+ if (PyBool_Check(pyForcePrompt))
+ {
+
+ forcePromptConfirm = pyForcePrompt == Py_True;
+ }
+ else if(pyForcePrompt == Py_None)
+ {
+ // Nothing to do
+ }
+ else
+ {
+ THROW_SYNTAX_EXCEPTION("Syntax error on CIF::forcePromptConfirm()", "Malformed argument: " + PYREPR(args));
+ }
+ }
+ SPELLexecutor::instance().getCIF().setForcePromptConfirm(forcePromptConfirm);
+
+ Py_RETURN_NONE;
+}
+
//============================================================================
// FUNCTION : ClientIF_Write
//============================================================================
@@ -467,6 +501,10 @@ static PyObject* ClientIF_Prompt( PyObject* self, PyObject* args, PyObject* kwds
if (argumentsC.hasModifier(LanguageModifiers::Timeout))
{
def.timeout = argumentsC.getModifier_Timeout();
+ }
+ else
+ {
+ def.timeout = SPELLtime(0, true);
}
// The prompt scope
def.scope = argumentsC.getModifier_Scope();
diff --git a/lib/SPELL_CIF/src/SPELLnotifications.C b/lib/SPELL_CIF/src/SPELLnotifications.C
index 927b3cb..afbcb89 100644
--- a/lib/SPELL_CIF/src/SPELLnotifications.C
+++ b/lib/SPELL_CIF/src/SPELLnotifications.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Notification data class
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_CIFC/Makefile.am b/lib/SPELL_CIFC/Makefile.am
index 9a5cf32..ae2684e 100644
--- a/lib/SPELL_CIFC/Makefile.am
+++ b/lib/SPELL_CIFC/Makefile.am
@@ -1,34 +1,42 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
include ${top_srcdir}/common.mk
-lib_LTLIBRARIES= libSPELL_CIFC.la
-libSPELL_CIFC_la_LDFLAGS = -version-info 1:0:0
-libSPELL_CIFC_la_SOURCES = \
- src/SPELLautomaticCif.C \
- src/SPELLncursesShell.C \
- src/SPELLstandaloneCif.C
-
+
+lib_LTLIBRARIES = libSPELL_CIFC_v2.la libSPELL_CIFC_v3.la
+
+libSPELL_CIFC_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+
+libSPELL_CIFC_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} -lmenu
+
+libSPELL_CIFC_v2_la_SOURCES = src/SPELLautomaticCif.C \
+ src/SPELLncursesShell.C \
+ src/SPELLstandaloneCif.C
+
+
+libSPELL_CIFC_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS}
+
+libSPELL_CIFC_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} -lmenu
+
+libSPELL_CIFC_v3_la_SOURCES = src/SPELLautomaticCif.C \
+ src/SPELLncursesShell.C \
+ src/SPELLstandaloneCif.C
+
\ No newline at end of file
diff --git a/lib/SPELL_CIFC/src/SPELLautomaticCif.C b/lib/SPELL_CIFC/src/SPELLautomaticCif.C
index 632370b..d250ae9 100644
--- a/lib/SPELL_CIFC/src/SPELLautomaticCif.C
+++ b/lib/SPELL_CIFC/src/SPELLautomaticCif.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the automatic (non-interactive) CIF
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -96,12 +96,17 @@ void SPELLautomaticCif::specificSetup( const SPELLcifStartupInfo& info )
getExecutorConfig().setPromptWarningDelay( STRI((ctx.getExecutorParameter(ExecutorConstants::PromptDelay))) );
getExecutorConfig().setBrowsableLib( stringToBrowsableLibMode(ctx.getExecutorParameter(ExecutorConstants::BrowsableLib) ) );
getExecutorConfig().setForceTcConfirm( (ctx.getExecutorParameter(ExecutorConstants::ForceTcConfirm) == PythonConstants::True) );
+ getExecutorConfig().setForcePromptConfirm( (ctx.getExecutorParameter(ExecutorConstants::ForcePromptConfirm) == PythonConstants::True) );
std::string saveMode = ctx.getExecutorParameter(ExecutorConstants::SaveStateMode);
getExecutorConfig().setSaveStateMode( saveMode );
std::string wvMode = ctx.getExecutorParameter(ExecutorConstants::WatchVariables);
bool wvEnabled = wvMode == ExecutorConstants::ENABLED;
getExecutorConfig().setWatchEnabled( wvEnabled );
+ std::string rdMode = ctx.getExecutorParameter(ExecutorConstants::ResourcesDisplay);
+ bool rdEnabled = rdMode == ExecutorConstants::ENABLED;
+ getExecutorConfig().setResourcesDisplayEnabled( rdEnabled );
+ getExecutorConfig().setLocalResourcesSupported( (ctx.getExecutorParameter(ExecutorConstants::LocalResourcesSupported) == PythonConstants::True) );
}
//=============================================================================
@@ -322,6 +327,22 @@ void SPELLautomaticCif::specificNotifyVariableScopeChange( const std::string& sc
std::cout << "[ NOTIFY VARIABLE SCOPE CHANGE ] " << "Variable Scope Change" << std::endl;
}
+//=============================================================================
+// METHOD: SPELLautomaticCif::specificNotifyResourceChange()
+//=============================================================================
+void SPELLautomaticCif::specificNotifyResourceChange( const std::vector& changed )
+{
+ std::cout << "[ NOTIFY RESOURCE CHANGE ] " << "Resource Change" << std::endl;
+}
+
+//=============================================================================
+// METHOD: SPELLautomaticCif::specificNotifyResourceList()
+//=============================================================================
+void SPELLautomaticCif::specificNotifyResourceList( const std::vector& resources )
+{
+ std::cout << "[ NOTIFY RESOURCE LIST ] " << "Resource List" << std::endl;
+}
+
//=============================================================================
// METHOD: SPELLautomaticCif::specificNotify
//=============================================================================
diff --git a/lib/SPELL_CIFC/src/SPELLncursesShell.C b/lib/SPELL_CIFC/src/SPELLncursesShell.C
index 18649bb..a34ea90 100644
--- a/lib/SPELL_CIFC/src/SPELLncursesShell.C
+++ b/lib/SPELL_CIFC/src/SPELLncursesShell.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the NCurses shell for standalone executor
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -47,7 +47,7 @@
#define COLOR_WARNING 3
#define COLOR_OK 4
-char *choices[] = {
+static const std::string choices[] = {
"RUN",
"PAUSE",
"SKIP",
@@ -60,7 +60,7 @@ char *choices[] = {
"RELOAD"
};
-char *descriptions[] = {
+static const std::string descriptions[] = {
"Run the procedure",
"Pause the execution",
"Skip current line",
@@ -333,7 +333,7 @@ void SPELLncursesShell::setupMenu()
m_menuItems = (ITEM **)calloc(n_choices, sizeof(ITEM *));
for(i = 0; i < n_choices; ++i)
{
- m_menuItems[i] = new_item(choices[i], descriptions[i]);
+ m_menuItems[i] = new_item(choices[i].c_str(), descriptions[i].c_str());
}
// Crate menu
diff --git a/lib/SPELL_CIFC/src/SPELLstandaloneCif.C b/lib/SPELL_CIFC/src/SPELLstandaloneCif.C
index b122fb2..1eef08c 100644
--- a/lib/SPELL_CIFC/src/SPELLstandaloneCif.C
+++ b/lib/SPELL_CIFC/src/SPELLstandaloneCif.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the CIF for standalone executor
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_CIFS/Makefile.am b/lib/SPELL_CIFS/Makefile.am
index 18834d7..12a323d 100644
--- a/lib/SPELL_CIFS/Makefile.am
+++ b/lib/SPELL_CIFS/Makefile.am
@@ -1,36 +1,47 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
include ${top_srcdir}/common.mk
-lib_LTLIBRARIES= libSPELL_CIFS.la
-libSPELL_CIFS_la_LDFLAGS = -version-info 2:1:0
-libSPELL_CIFS_la_SOURCES = \
- src/SPELLrequestProcessor.C \
- src/SPELLdisplayBuffer.C \
- src/SPELLvariableBuffer.C \
- src/SPELLcifPromptHelper.C \
- src/SPELLserverCif.C
-
+
+lib_LTLIBRARIES = libSPELL_CIFS_v2.la libSPELL_CIFS_v3.la
+
+libSPELL_CIFS_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+
+libSPELL_CIFS_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_CIFS_v2_la_SOURCES = src/SPELLrequestProcessor.C \
+ src/SPELLdisplayBuffer.C \
+ src/SPELLvariableBuffer.C \
+ src/SPELLresourceBuffer.C \
+ src/SPELLcifPromptHelper.C \
+ src/SPELLserverCif.C
+
+libSPELL_CIFS_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS}
+
+libSPELL_CIFS_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_CIFS_v3_la_SOURCES = src/SPELLrequestProcessor.C \
+ src/SPELLdisplayBuffer.C \
+ src/SPELLvariableBuffer.C \
+ src/SPELLresourceBuffer.C \
+ src/SPELLcifPromptHelper.C \
+ src/SPELLserverCif.C
+
\ No newline at end of file
diff --git a/lib/SPELL_CIFS/src/SPELLcifPromptHelper.C b/lib/SPELL_CIFS/src/SPELLcifPromptHelper.C
index 3ecf0e2..0561ffe 100644
--- a/lib/SPELL_CIFS/src/SPELLcifPromptHelper.C
+++ b/lib/SPELL_CIFS/src/SPELLcifPromptHelper.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Helper for prompt processing
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -38,7 +38,7 @@ std::string SPELLcifPromptHelper::completeOptions( const SPELLpromptDefinition&
{
std::string msgToShow = origMsgToShow;
- msgToShow += "\nAvailable options:\n";
+ msgToShow += "Available options:\n";
int keyCount = 0;
std::string optionStr = "";
diff --git a/lib/SPELL_CIFS/src/SPELLdisplayBuffer.C b/lib/SPELL_CIFS/src/SPELLdisplayBuffer.C
index 5a4a46c..aa97e9f 100644
--- a/lib/SPELL_CIFS/src/SPELLdisplayBuffer.C
+++ b/lib/SPELL_CIFS/src/SPELLdisplayBuffer.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the display messages buffer
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_CIFS/src/SPELLrequestProcessor.C b/lib/SPELL_CIFS/src/SPELLrequestProcessor.C
index d51c8c7..31644ce 100644
--- a/lib/SPELL_CIFS/src/SPELLrequestProcessor.C
+++ b/lib/SPELL_CIFS/src/SPELLrequestProcessor.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the message request processor
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -160,12 +160,14 @@ void SPELLrequestProcessor::processGetConfig( const SPELLipcMessage& msg, SPELLi
std::string byStep = config.isByStep() ? True : False;
std::string browsableLibStr = config.getBrowsableLibStr();
std::string forceTcConfirm = config.isForceTcConfirm() ? True : False;
+ std::string forcePromptConfirm = config.isForcePromptConfirm() ? True : False;
response.set(ExecutorConstants::ExecDelay, execDelay);
response.set(ExecutorConstants::PromptDelay, promptDelay);
response.set(ExecutorConstants::ByStep, byStep);
response.set(ExecutorConstants::BrowsableLib, browsableLibStr );
response.set(ExecutorConstants::ForceTcConfirm, forceTcConfirm);
+ response.set(ExecutorConstants::ForcePromptConfirm, forcePromptConfirm);
LOG_INFO("Current executor configuration:");
LOG_INFO(" run into : " + (config.isRunInto() ? True : False) );
@@ -174,6 +176,7 @@ void SPELLrequestProcessor::processGetConfig( const SPELLipcMessage& msg, SPELLi
LOG_INFO(" by step : " + byStep);
LOG_INFO(" browsable lib : " + browsableLibStr );
LOG_INFO(" force confirm : " + forceTcConfirm);
+ LOG_INFO(" force prompt confirm : " + forcePromptConfirm);
DEBUG("[CIF] Request to get executor config done");
}
@@ -237,6 +240,7 @@ void SPELLrequestProcessor::processSetConfig( const SPELLipcMessage& msg, SPELLi
std::string byStep = msg.get(ExecutorConstants::ByStep);
std::string browsableLibStr = msg.get(ExecutorConstants::BrowsableLib);
std::string forceTcConfirm = msg.get(ExecutorConstants::ForceTcConfirm);
+ std::string forcePromptConfirm = msg.get(ExecutorConstants::ForcePromptConfirm);
LOG_INFO("New executor configuration ----------------------------------");
@@ -246,6 +250,7 @@ void SPELLrequestProcessor::processSetConfig( const SPELLipcMessage& msg, SPELLi
LOG_INFO(" By step : " + byStep);
LOG_INFO(" Br. lib : " + browsableLibStr);
LOG_INFO(" TC confirm: " + forceTcConfirm);
+ LOG_INFO("Prompt confirm: " + forcePromptConfirm);
LOG_INFO("-------------------------------------------------------------");
SPELLexecutor::instance().setRunInto( (runInto == True) );
@@ -254,6 +259,7 @@ void SPELLrequestProcessor::processSetConfig( const SPELLipcMessage& msg, SPELLi
SPELLexecutor::instance().setByStep( (byStep == True) );
SPELLexecutor::instance().setBrowsableLibStr( browsableLibStr );
SPELLexecutor::instance().setForceTcConfirm( forceTcConfirm == True );
+ SPELLexecutor::instance().setForcePromptConfirm( forcePromptConfirm == True );
DEBUG("[CIF] Request to change executor config done");
}
@@ -280,7 +286,6 @@ void SPELLrequestProcessor::processSetBreakpoint( const SPELLipcMessage& msg, SP
//=============================================================================
void SPELLrequestProcessor::processClearBreakpoints( const SPELLipcMessage& msg, SPELLipcMessage& response )
{
- SPELLmonitor mon(m_requestLock);
DEBUG("[CIF] Request to clear breakpoints for the given code");
// Update the response message
response.setId(ExecutorMessages::RSP_CLEAR_BREAKPOINT);
@@ -293,7 +298,6 @@ void SPELLrequestProcessor::processClearBreakpoints( const SPELLipcMessage& msg,
//=============================================================================
void SPELLrequestProcessor::processCheckVariablesEnabled( const SPELLipcMessage& msg, SPELLipcMessage& response )
{
- SPELLmonitor mon(m_requestLock);
// Update the response message
response.setId(ExecutorMessages::RSP_WVARIABLES_ENABLED);
bool enabled = SPELLexecutor::instance().getVariableManager().isEnabled();
@@ -449,6 +453,82 @@ void SPELLrequestProcessor::processChangeVariable( const SPELLipcMessage& msg, S
SPELLexecutor::instance().getVariableManager().changeVariable( info );
}
+//=============================================================================
+// METHOD: SPELLrequestProcessor::processCheckResourcesEnabled
+//=============================================================================
+void SPELLrequestProcessor::processCheckResourcesEnabled( const SPELLipcMessage& msg, SPELLipcMessage& response )
+{
+ // Update the response message
+ response.setId(ExecutorMessages::RSP_DRESOURCES_ENABLED);
+ bool enabled = SPELLexecutor::instance().getResourceManager().isEnabled();
+ bool localSupport = SPELLexecutor::instance().getConfiguration().isLocalResourcesSupported();
+ response.set( MessageField::FIELD_DRESOURCES_ENABLED, enabled ? "True" : "False");
+ response.set( MessageField::FIELD_LOCAL_RESOURCE_SUPPORTED, localSupport ? "True" : "False");
+}
+
+//=============================================================================
+// METHOD: SPELLrequestProcessor::processGetResources
+//=============================================================================
+void SPELLrequestProcessor::processGetResources( const SPELLipcMessage& msg, SPELLipcMessage& response )
+{
+ SPELLmonitor mon(m_requestLock);
+ // Update the response message
+ response.setId(ExecutorMessages::RSP_GET_RESOURCES);
+
+ if (!SPELLexecutor::instance().getResourceManager().isStatusValid())
+ {
+ LOG_WARN("Resource manager is not in valid status");
+ response.setType(MSG_TYPE_ERROR);
+ response.set( MessageField::FIELD_ERROR, "Cannot retrieve resources");
+ response.set( MessageField::FIELD_REASON, "Resource analysis cannot be done in the current status");
+ response.set( MessageField::FIELD_FATAL, PythonConstants::False );
+ return;
+ }
+
+ if (!SPELLexecutor::instance().getResourceManager().isEnabled())
+ {
+ LOG_WARN("Resource manager is disabled, but received getResources request");
+ return;
+ }
+
+ SPELLexecutor::instance().getResourceManager().getResources();
+}
+
+//=============================================================================
+// METHOD: SPELLrequestProcessor::processChangeResource
+//=============================================================================
+void SPELLrequestProcessor::processChangeResource( const SPELLipcMessage& msg, SPELLipcMessage& response )
+{
+ SPELLmonitor mon(m_requestLock);
+ // Update the response message
+ response.setId(ExecutorMessages::RSP_CHANGE_RESOURCE);
+
+ if (!SPELLexecutor::instance().getResourceManager().isStatusValid())
+ {
+ LOG_WARN("Resource manager is not in valid status");
+ response.setType(MSG_TYPE_ERROR);
+ response.set( MessageField::FIELD_ERROR, "Cannot change resources");
+ response.set( MessageField::FIELD_REASON, "Resource analysis cannot be done in the current status");
+ response.set( MessageField::FIELD_FATAL, PythonConstants::False );
+ return;
+ }
+
+ if (!SPELLexecutor::instance().getResourceManager().isEnabled())
+ {
+ LOG_WARN("Resource manager is disabled, but received change resource request");
+ return;
+ }
+
+ std::string name = msg.get( MessageField::FIELD_RESOURCE_NAME );
+ std::string globalValueExpression = msg.get( MessageField::FIELD_RESOURCE_GLOBAL_VALUE );
+ std::string localValueExpression = msg.get( MessageField::FIELD_RESOURCE_LOCAL_VALUE );
+
+ // Type and registration flag are not important here
+ SPELLresourceInfo info(name,"",globalValueExpression,localValueExpression, std::vector >(), "");
+
+ SPELLexecutor::instance().getResourceManager().changeResource( info );
+}
+
//=============================================================================
// METHOD: SPELLrequestProcessor::processGetDictionary
//=============================================================================
diff --git a/lib/SPELL_CIFS/src/SPELLresourceBuffer.C b/lib/SPELL_CIFS/src/SPELLresourceBuffer.C
new file mode 100644
index 0000000..0e5f95a
--- /dev/null
+++ b/lib/SPELL_CIFS/src/SPELLresourceBuffer.C
@@ -0,0 +1,197 @@
+// ################################################################################
+// FILE : SPELLresourceBuffer.C
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Implementation of the RDOTCO messages buffer
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// Local includes ----------------------------------------------------------
+#include "SPELL_CIFS/SPELLresourceBuffer.H"
+#include "SPELL_CIFS/SPELLserverCif.H"
+// Project includes --------------------------------------------------------
+#include "SPELL_IPC/SPELLipc.H"
+#include "SPELL_SYN/SPELLmonitor.H"
+#include "SPELL_UTIL/SPELLlog.H"
+#include "SPELL_WRP/SPELLconstants.H"
+// System includes ---------------------------------------------------------
+
+
+#define FLUSH_PERIOD_USEC 250000 //half a sec
+
+//=============================================================================
+// CONSTRUCTOR: SPELLresourceBuffer::SPELLresourceBuffer
+//=============================================================================
+SPELLresourceBuffer::SPELLresourceBuffer( const std::string& procId, SPELLserverCif& cif )
+: SPELLthread("display-buffer"),
+ m_cif(cif),
+ m_resourceMessage( ExecutorMessages::MSG_RESOURCE_CHANGE )
+{
+ DEBUG("[CIF] Created display buffer");
+ m_working = true;
+ m_resourceMessage.setType(MSG_TYPE_ONEWAY);
+ m_resourceMessage.set( MessageField::FIELD_PROC_ID, procId );
+ m_total = 0;
+ m_bufferHasListResources = false;
+}
+
+//=============================================================================
+// DESTRUCTOR: SPELLresourceBuffer::~SPELLresourceBuffer
+//=============================================================================
+SPELLresourceBuffer::~SPELLresourceBuffer()
+{
+ DEBUG("[CIF] Destroyed RDOTCO buffer");
+}
+
+//=============================================================================
+// METHOD: SPELLresourceBuffer::run()
+//=============================================================================
+void SPELLresourceBuffer::run()
+{
+ while(m_working)
+ {
+ usleep(FLUSH_PERIOD_USEC);
+ {
+ SPELLmonitor m(m_lock);
+ if (hasDataToSend())
+ {
+ flush();
+ }
+ }
+ }
+}
+
+//=============================================================================
+// METHOD: SPELLresourceBuffer::run()
+//=============================================================================
+void SPELLresourceBuffer::stop()
+{
+ m_working = false;
+}
+
+//=============================================================================
+// METHOD: SPELLresourceBuffer::resourceChange()
+//=============================================================================
+void SPELLresourceBuffer::resourceChange( const std::vector& changed )
+{
+ SPELLmonitor m(m_lock);
+ std::vector::const_iterator it;
+ std::map::iterator mit;
+
+ for( it = changed.begin(); it != changed.end(); it++)
+ {
+ // If the resource was added and not yet notified, just not process
+ // this notification and leave the add operation but with the new value.
+ std::string name = (*it).resourceName;
+ m_resources[ name ] = (*it);
+ }
+ m_total++;
+}
+
+//=============================================================================
+// METHOD: SPELLresourceBuffer::resourceList()
+//=============================================================================
+void SPELLresourceBuffer::resourceList( const std::vector& resources )
+{
+ resourceChange(resources);
+ m_bufferHasListResources = true;
+}
+
+//=============================================================================
+// METHOD: SPELLresourceBuffer::flush()
+//=============================================================================
+void SPELLresourceBuffer::flush()
+{
+ SPELLmonitor m(m_lock);
+
+ std::string names = "";
+ std::string types = "";
+ std::string globalValues = "";
+ std::string localValues = "";
+ std::string valueRange = "";
+ std::string gcsValueRange = "";
+ std::string gcsNames = "";
+
+ std::map::const_iterator it;
+ for(it = m_resources.begin(); it != m_resources.end(); it++)
+ {
+ if (names != "")
+ {
+ names += VARIABLE_SEPARATOR;
+ types += VARIABLE_SEPARATOR;
+ globalValues += VARIABLE_SEPARATOR;
+ localValues += VARIABLE_SEPARATOR;
+ gcsNames += VARIABLE_SEPARATOR;
+ if (m_bufferHasListResources)
+ {
+ valueRange += VARIABLE_SEPARATOR;
+ gcsValueRange += VARIABLE_SEPARATOR;
+ }
+ }
+ names += it->second.resourceName;
+ types += it->second.resourceType;
+ globalValues += it->second.resourceGlobalValue;
+ localValues += it->second.resourceLocalValue;
+ gcsNames += it->second.resourceGCSName;
+ if (m_bufferHasListResources)
+ {
+ for (unsigned int vri = 0; vri < it->second.resourceValueRange.size(); vri++)
+ {
+ if (vri > 0)
+ {
+ valueRange += VARIABLE_PROPERTY_SEPARATOR;
+ gcsValueRange += VARIABLE_PROPERTY_SEPARATOR;
+ }
+ valueRange += it->second.resourceValueRange[vri].first;
+ gcsValueRange += it->second.resourceValueRange[vri].second;
+ }
+ }
+ }
+
+ m_resources.clear();
+
+ m_resourceMessage.set(MessageField::FIELD_RESOURCE_NAME, names);
+ m_resourceMessage.set(MessageField::FIELD_RESOURCE_TYPE, types);
+ m_resourceMessage.set(MessageField::FIELD_RESOURCE_GLOBAL_VALUE, globalValues);
+ m_resourceMessage.set(MessageField::FIELD_RESOURCE_LOCAL_VALUE, localValues);
+ // An empty string is passed in case of resource change (no need to resend the ranges)
+ m_resourceMessage.set(MessageField::FIELD_RESOURCE_VALUE_RANGE, valueRange);
+ m_resourceMessage.set(MessageField::FIELD_RESOURCE_GCS_VALUE_RANGE, gcsValueRange);
+ m_resourceMessage.set(MessageField::FIELD_RESOURCE_GCS_NAME, gcsNames);
+
+#ifdef WITH_DEBUG
+ std::cerr << "SEND RDOTCO (" << m_total << ")" << std::endl;
+#endif
+
+ m_cif.sendGUIMessage(m_resourceMessage);
+ m_total = 0;
+ m_bufferHasListResources = false;
+}
+
+//=============================================================================
+// METHOD: SPELLresourceBuffer::hasDataToSend()
+//=============================================================================
+bool SPELLresourceBuffer::hasDataToSend()
+{
+ SPELLmonitor m(m_lock);
+ return (m_resources.size()>0);
+}
diff --git a/lib/SPELL_CIFS/src/SPELLserverCif.C b/lib/SPELL_CIFS/src/SPELLserverCif.C
index 85a133d..0be5af8 100644
--- a/lib/SPELL_CIFS/src/SPELLserverCif.C
+++ b/lib/SPELL_CIFS/src/SPELLserverCif.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the CIF for server environment
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -51,7 +51,7 @@
// DEFINES /////////////////////////////////////////////////////////////////
-#define ACKNOWLEDGE_TIMEOUT_SEC 30
+#define ACKNOWLEDGE_TIMEOUT_MSEC 30000
// GLOBALS /////////////////////////////////////////////////////////////////
SPELLserverCif* s_handle = NULL;
@@ -72,11 +72,18 @@ SPELLserverCif::SPELLserverCif()
m_ifc = NULL;
m_buffer = NULL;
m_wovBuffer = NULL;
+ m_rdotcoBuffer = NULL;
m_ready = false;
-
+ m_timeoutOpenProcMsec = 0;
+ m_ipcTimeoutGuiRequestMsec = 0;
+ m_ipcTimeoutCtxRequestMsec = 0;
+ m_ipcInterruptionNotified = false;
m_errorState = false;
m_sequence = 0;
m_sequenceStack = 0;
+ m_numNotAcknowledged = 0;
+ m_timeoutExecLoginMsec = 0;
+ m_timeoutAcknowledgeSec = 0;
getExecutorConfig().setVisible(true);
getExecutorConfig().setAutomatic(false);
@@ -101,12 +108,6 @@ SPELLserverCif::SPELLserverCif()
m_closing = false;
m_lastStack = "";
-
- m_ipcTimeoutGuiRequestMsec = SPELLconfiguration::instance().commonOrDefault( "GuiRequestTimeout", IPC_GUIREQUEST_DEFAULT_TIMEOUT_MSEC );
- m_ipcTimeoutCtxRequestMsec = SPELLconfiguration::instance().commonOrDefault( "CtxRequestTimeout", IPC_CTXREQUEST_DEFAULT_TIMEOUT_MSEC );
- m_timeoutOpenProcMsec = SPELLconfiguration::instance().commonOrDefault( "OpenProcTimeout", IPC_OPENPROC_DEFAULT_TIMEOUT_MSEC );
- m_timeoutExecLoginMsec = SPELLconfiguration::instance().commonOrDefault( "ExecutorLoginTimeout", IPC_EXLOGIN_DEFAULT_TIMEOUT_MSEC );
- m_timeoutAcknowledgeSec = SPELLconfiguration::instance().commonOrDefault( "AcknowledgeTimeout", ACKNOWLEDGE_TIMEOUT_SEC );
}
//=============================================================================
@@ -129,6 +130,11 @@ SPELLserverCif::~SPELLserverCif()
delete m_wovBuffer;
m_wovBuffer = NULL;
}
+ if (m_rdotcoBuffer != NULL)
+ {
+ delete m_rdotcoBuffer;
+ m_rdotcoBuffer = NULL;
+ }
}
//=============================================================================
@@ -136,6 +142,18 @@ SPELLserverCif::~SPELLserverCif()
//=============================================================================
void SPELLserverCif::specificSetup( const SPELLcifStartupInfo& info )
{
+ m_ipcTimeoutGuiRequestMsec = SPELLconfiguration::instance().commonOrDefault( "GuiRequestTimeout", IPC_GUIREQUEST_DEFAULT_TIMEOUT_MSEC );
+ m_ipcTimeoutCtxRequestMsec = SPELLconfiguration::instance().commonOrDefault( "CtxRequestTimeout", IPC_CTXREQUEST_DEFAULT_TIMEOUT_MSEC );
+ m_timeoutOpenProcMsec = SPELLconfiguration::instance().commonOrDefault( "OpenProcTimeout", IPC_OPENPROC_DEFAULT_TIMEOUT_MSEC );
+ m_timeoutExecLoginMsec = SPELLconfiguration::instance().commonOrDefault( "ExecutorLoginTimeout", IPC_EXLOGIN_DEFAULT_TIMEOUT_MSEC );
+ m_timeoutAcknowledgeSec = SPELLconfiguration::instance().commonOrDefault( "AcknowledgeTimeout", ACKNOWLEDGE_TIMEOUT_MSEC ) / 1000;
+
+ LOG_INFO("GUI request timeout: " + ISTR(m_ipcTimeoutGuiRequestMsec) + " ms");
+ LOG_INFO("CTX request timeout: " + ISTR(m_ipcTimeoutCtxRequestMsec) + " ms");
+ LOG_INFO(" OPEN timeout: " + ISTR(m_timeoutOpenProcMsec) + " ms");
+ LOG_INFO(" LOGIN timeout: " + ISTR(m_timeoutExecLoginMsec) + " ms");
+ LOG_INFO(" ACK timeout: " + ISTR(m_timeoutAcknowledgeSec) + " sec");
+
//Initialize Executor Config parameters
getExecutorConfig().setVisible(true);
getExecutorConfig().setAutomatic(false);
@@ -157,6 +175,9 @@ void SPELLserverCif::specificSetup( const SPELLcifStartupInfo& info )
m_wovBuffer = new SPELLvariableBuffer( getProcId(), *this );
m_wovBuffer->start();
+ m_rdotcoBuffer = new SPELLresourceBuffer( getProcId(), *this );
+ m_rdotcoBuffer->start();
+
// Initialize message sequencer
m_sequence = 0;
m_sequenceStack = 0;
@@ -188,8 +209,10 @@ void SPELLserverCif::specificCleanup( bool force )
cancelPrompt();
m_buffer->stop();
m_wovBuffer->stop();
+ m_rdotcoBuffer->stop();
m_buffer->join();
m_wovBuffer->join();
+ m_rdotcoBuffer->join();
DEBUG("[CIF] Disconnecting server CIF");
if (!force)
{
@@ -246,14 +269,12 @@ SPELLipcMessage SPELLserverCif::login()
loginmsg.set( MessageField::FIELD_CSP, getProcId());
// status loaded is not correct if the procedure did not compile, but the error will be
- // notified afterwards anyhow.
- loginmsg.set( MessageField::FIELD_EXEC_STATUS, SPELLexecutorUtils::statusToString(STATUS_LOADED));
+ // notified afterwards anyhow.c
loginmsg.set( MessageField::FIELD_ASRUN_NAME, getAsRunName() );
loginmsg.set( MessageField::FIELD_LOG_NAME, SPELLlog::instance().getLogFile() );
LOG_INFO("Login information:");
LOG_INFO("Proc : " + getProcId() );
- LOG_INFO("Status: LOADED");
LOG_INFO("AsRun : " + getAsRunName() );
LOG_INFO("Log : " + SPELLlog::instance().getLogFile() );
@@ -376,7 +397,10 @@ void SPELLserverCif::processLogin( const SPELLipcMessage& loginResp )
{
getExecutorConfig().setForceTcConfirm( loginResp.get(MessageField::FIELD_FORCE_TC_CONFIRM) == ExecutorConstants::TRUE_VALUE );
}
-
+ if (loginResp.hasField(MessageField::FIELD_FORCE_PROMPT_CONFIRM))
+ {
+ getExecutorConfig().setForcePromptConfirm( loginResp.get(MessageField::FIELD_FORCE_PROMPT_CONFIRM) == ExecutorConstants::TRUE_VALUE );
+ }
if (loginResp.hasField(MessageField::FIELD_SAVE_STATE_MODE))
{
getExecutorConfig().setSaveStateMode( loginResp.get(MessageField::FIELD_SAVE_STATE_MODE) );
@@ -387,6 +411,16 @@ void SPELLserverCif::processLogin( const SPELLipcMessage& loginResp )
getExecutorConfig().setWatchEnabled( loginResp.get(MessageField::FIELD_WATCH_VARIABLES) == ExecutorConstants::TRUE_VALUE );
}
+ if (loginResp.hasField(MessageField::FIELD_RESOURCES_DISPLAY))
+ {
+ getExecutorConfig().setResourcesDisplayEnabled( loginResp.get(MessageField::FIELD_RESOURCES_DISPLAY) == ExecutorConstants::TRUE_VALUE );
+ }
+
+ if (loginResp.hasField(MessageField::FIELD_LOCAL_RESOURCE_SUPPORTED))
+ {
+ getExecutorConfig().setLocalResourcesSupported( loginResp.get(MessageField::FIELD_LOCAL_RESOURCE_SUPPORTED) == ExecutorConstants::TRUE_VALUE );
+ }
+
if (loginResp.hasField(MessageField::FIELD_MAX_VERBOSITY))
{
getExecutorConfig().setMaxVerbosity( STRI(loginResp.get(MessageField::FIELD_MAX_VERBOSITY)) );
@@ -412,8 +446,11 @@ void SPELLserverCif::processLogin( const SPELLipcMessage& loginResp )
LOG_INFO("Prompt Delay : " + ISTR(getExecutorConfig().getPromptWarningDelay()));
LOG_INFO("By Step : " + BSTR(getExecutorConfig().isByStep()));
LOG_INFO("Force Tc Conf : " + BSTR(getExecutorConfig().isForceTcConfirm()));
+ LOG_INFO("Force Prompt Conf : " + BSTR(getExecutorConfig().isForcePromptConfirm()));
LOG_INFO("Save State Mod: " + getExecutorConfig().getSaveStateMode());
LOG_INFO("WatchVariables: " + BSTR(getExecutorConfig().isWatchEnabled()));
+ LOG_INFO("ResourcesDisplay: " + BSTR(getExecutorConfig().isResourcesDisplayEnabled()));
+ LOG_INFO("Local Resource supported: " + BSTR(getExecutorConfig().isLocalResourcesSupported()));
LOG_INFO("Max Verbosity : " + ISTR(getExecutorConfig().getMaxVerbosity()));
}
@@ -479,6 +516,8 @@ void SPELLserverCif::sendGUIMessage( const SPELLipcMessage& msg )
LOG_ERROR("Unable to communicate with Context: " + std::string(ex.what()));
SPELLexecutor::instance().pause();
}
+ } else {
+ usleep(500000);
}
}
@@ -576,35 +615,30 @@ void SPELLserverCif::prepareMessage( SPELLipcMessage& msg, const std::string da
void SPELLserverCif::specificNotifyLine()
{
// Local variables
- std::string stage = "";
-
+ SPELLsafeThreadOperations ops("Notify");
+ std::string stage = "";
+ SPELLipcMessage msg = m_lnMessage;
// prepares the message to be sent to GUI
- prepareMessage( m_lnMessage, MessageValue::DATA_TYPE_LINE, MSG_TYPE_NOTIFY_ASYNC);
+ prepareMessage( msg, MessageValue::DATA_TYPE_LINE, MSG_TYPE_NOTIFY_ASYNC);
// Update message with stage info
stage = getStage();
-
- if (stage.find(":") != std::string::npos)
+ size_t delim = stage.find(":");
+ if (delim != std::string::npos)
{
- std::vector stage_title = SPELLutils::tokenize(stage,":");
- if (stage_title.size()==2)
- {
- m_lnMessage.set(MessageField::FIELD_STAGE_ID,stage_title[0]);
- m_lnMessage.set(MessageField::FIELD_STAGE_TL,stage_title[1]);
- }
+ msg.set(MessageField::FIELD_STAGE_ID,stage.substr(0, delim));
+ if (delim + 1 < stage.length())
+ msg.set(MessageField::FIELD_STAGE_TL,stage.substr(delim + 1));
else
- {
- m_lnMessage.set(MessageField::FIELD_STAGE_ID,"(none)");
- m_lnMessage.set(MessageField::FIELD_STAGE_TL,"(none)");
- }
+ msg.set(MessageField::FIELD_STAGE_TL,"(none)");
}
else
{
- m_lnMessage.set(MessageField::FIELD_STAGE_ID,stage);
- m_lnMessage.set(MessageField::FIELD_STAGE_TL,stage);
+ msg.set(MessageField::FIELD_STAGE_ID,stage);
+ msg.set(MessageField::FIELD_STAGE_TL,stage);
}
- sendGUIMessage(m_lnMessage);
+ sendGUIMessage(msg);
} //SPELLserverCif::specificNotifyLine()
@@ -615,10 +649,16 @@ void SPELLserverCif::specificNotifyLine()
void SPELLserverCif::specificNotifyCall()
{
// prepares the message to be sent to GUI
- prepareMessage( m_lnMessage, MessageValue::DATA_TYPE_CALL, MSG_TYPE_NOTIFY);
+ SPELLsafeThreadOperations ops("NotifyCall");
+ SPELLipcMessage msg = m_lnMessage;
+ prepareMessage( msg, MessageValue::DATA_TYPE_CALL, MSG_TYPE_NOTIFY);
+
+ do
+ {
+ sendGUIMessage(msg);
+ }
+ while (!waitAcknowledge(msg));
- sendGUIMessage(m_lnMessage);
- waitAcknowledge(m_lnMessage);
} //void SPELLserverCif::specificNotifyCall()
@@ -627,11 +667,15 @@ void SPELLserverCif::specificNotifyCall()
//=============================================================================
void SPELLserverCif::specificNotifyReturn()
{
- // prepares the message to be sent to GUI
- prepareMessage( m_lnMessage, MessageValue::DATA_TYPE_RETURN, MSG_TYPE_NOTIFY);
+ // prepares the message to be sent to GUI
+ SPELLsafeThreadOperations ops("NotifyReturn");
+ SPELLipcMessage msg = m_lnMessage;
+ prepareMessage(msg, MessageValue::DATA_TYPE_RETURN, MSG_TYPE_NOTIFY);
- sendGUIMessage(m_lnMessage);
- waitAcknowledge(m_lnMessage);
+ do
+ {
+ sendGUIMessage(msg);
+ } while (!waitAcknowledge(msg));
}
//=============================================================================
@@ -640,24 +684,28 @@ void SPELLserverCif::specificNotifyReturn()
void SPELLserverCif::specificNotifyStatus( const SPELLstatusInfo& st )
{
// Prepare message
- m_stMessage.set(MessageField::FIELD_EXEC_STATUS, SPELLexecutorUtils::statusToString(st.status));
- completeMessage( m_stMessage );
+ SPELLsafeThreadOperations ops("NotifyStatus");
+ SPELLipcMessage msg = m_stMessage;
+ msg.set(MessageField::FIELD_EXEC_STATUS, SPELLexecutorUtils::statusToString(st.status));
+ completeMessage( msg );
// Set message Condition information
if (st.condition.size()>0)
{
- m_stMessage.set( MessageField::FIELD_CONDITION, st.condition );
+ msg.set( MessageField::FIELD_CONDITION, st.condition );
}
// Set message Action information
if (st.actionLabel != "")
{
- m_stMessage.set( MessageField::FIELD_ACTION_LABEL, st.actionLabel );
- m_stMessage.set( MessageField::FIELD_ACTION_ENABLED, st.actionEnabled ? MessageValue::DATA_TRUE : MessageValue::DATA_FALSE );
+ msg.set( MessageField::FIELD_ACTION_LABEL, st.actionLabel );
+ msg.set( MessageField::FIELD_ACTION_ENABLED, st.actionEnabled ? MessageValue::DATA_TRUE : MessageValue::DATA_FALSE );
}
- sendGUIMessage(m_stMessage);
- waitAcknowledge(m_stMessage);
+ do{
+ sendGUIMessage(msg);
+ } while(!waitAcknowledge(msg));
+
}
//=============================================================================
@@ -665,6 +713,7 @@ void SPELLserverCif::specificNotifyStatus( const SPELLstatusInfo& st )
//=============================================================================
void SPELLserverCif::specificNotifyUserActionSet( const std::string& label, const unsigned int severity )
{
+ SPELLsafeThreadOperations ops("NotifyActionSet");
SPELLipcMessage actionMessage(MessageId::MSG_ID_SET_UACTION);
actionMessage.setType(MSG_TYPE_ONEWAY);
actionMessage.set( MessageField::FIELD_PROC_ID, getProcId() );
@@ -692,6 +741,7 @@ void SPELLserverCif::specificNotifyUserActionSet( const std::string& label, cons
//=============================================================================
void SPELLserverCif::specificNotifyUserActionUnset()
{
+ SPELLsafeThreadOperations ops("NotifyActionUnset");
SPELLipcMessage actionMessage(MessageId::MSG_ID_DISMISS_UACTION);
actionMessage.setType(MSG_TYPE_ONEWAY);
actionMessage.set( MessageField::FIELD_PROC_ID, getProcId() );
@@ -703,6 +753,7 @@ void SPELLserverCif::specificNotifyUserActionUnset()
//=============================================================================
void SPELLserverCif::specificNotifyUserActionEnable( bool enable )
{
+ SPELLsafeThreadOperations ops("Notify");
if (enable)
{
SPELLipcMessage actionMessage(MessageId::MSG_ID_ENABLE_UACTION);
@@ -725,7 +776,9 @@ void SPELLserverCif::specificNotifyUserActionEnable( bool enable )
void SPELLserverCif::specificNotify( ItemNotification notification )
{
//Prepare message
- completeMessage( m_ntMessage );
+ SPELLsafeThreadOperations ops("Notify");
+ SPELLipcMessage msg = m_ntMessage;
+ completeMessage( msg );
//DEBUG("[CIF] Processing status");
@@ -733,27 +786,30 @@ void SPELLserverCif::specificNotify( ItemNotification notification )
std::stringstream buffer;
buffer << notification.getSuccessfulCount();
- m_ntMessage.set(MessageField::FIELD_NOTIF_ITEM_TYPE, NOTIF_TYPE_STR[notification.type]);
- m_ntMessage.set(MessageField::FIELD_NOTIF_ITEM_NAME, notification.name);
- m_ntMessage.set(MessageField::FIELD_NOTIF_ITEM_VALUE, notification.value);
- m_ntMessage.set(MessageField::FIELD_NOTIF_ITEM_STATUS, notification.status);
- m_ntMessage.set(MessageField::FIELD_NOTIF_ITEM_REASON, notification.getTokenizedComment());
- m_ntMessage.set(MessageField::FIELD_NOTIF_ITEM_TIME, notification.getTokenizedTime());
- m_ntMessage.set(MessageField::FIELD_NOTIF_ITEM_SCOUNT, buffer.str());
+ msg.set(MessageField::FIELD_NOTIF_ITEM_TYPE, NOTIF_TYPE_STR[notification.type]);
+ msg.set(MessageField::FIELD_NOTIF_ITEM_NAME, notification.name);
+ msg.set(MessageField::FIELD_NOTIF_ITEM_VALUE, notification.value);
+ msg.set(MessageField::FIELD_NOTIF_ITEM_STATUS, notification.status);
+ msg.set(MessageField::FIELD_NOTIF_ITEM_REASON, notification.getTokenizedComment());
+ msg.set(MessageField::FIELD_NOTIF_ITEM_TIME, notification.getTokenizedTime());
+ msg.set(MessageField::FIELD_NOTIF_ITEM_SCOUNT, buffer.str());
//DEBUG("[CIF] Message prepared, sending");
- sendGUIMessage(m_ntMessage);
- waitAcknowledge(m_ntMessage);
+ do
+ {
+ sendGUIMessage(msg);
+ } while(!waitAcknowledge(msg));
+
//DEBUG("[CIF] Notification sent");
}
//=============================================================================
// METHOD: SPELLserverCif::waitAcknowledge()
//=============================================================================
-void SPELLserverCif::waitAcknowledge( const SPELLipcMessage& msg )
+bool SPELLserverCif::waitAcknowledge( const SPELLipcMessage& msg )
{
- if (m_ready && !m_ipcInterruptionNotified)
+ if (m_ready)
{
bool found = false;
std::string seq = msg.get(MessageField::FIELD_MSG_SEQUENCE);
@@ -766,11 +822,12 @@ void SPELLserverCif::waitAcknowledge( const SPELLipcMessage& msg )
SPELLmonitor m(m_ackLock);
it = std::find(m_ackSequences.begin(), m_ackSequences.end(), seq);
-
found = it != m_ackSequences.end();
if (found)
{
m_ackSequences.erase(it);
+
+ return true;
}
else
{
@@ -782,41 +839,16 @@ void SPELLserverCif::waitAcknowledge( const SPELLipcMessage& msg )
LOG_WARN("Acknowledge not received!");
LOG_WARN(msg.dataStr());
LOG_WARN("#########################");
- m_numNotAcknowledged++;
-
- if (m_numNotAcknowledged==5)
- {
- m_numNotAcknowledged = 0;
- if (!m_ipcInterruptionNotified)
- {
- m_ipcInterruptionNotified = true;
- SPELLexecutorStatus st = SPELLexecutor::instance().getStatus();
- if ( st == STATUS_RUNNING )
- {
- ExecutorCommand cmd;
- cmd.id = CMD_PAUSE;
- warning("Communication with controlling GUI interrupted. Procedure paused for safety.", LanguageConstants::SCOPE_SYS);
- warning("You may try to resume execution.", LanguageConstants::SCOPE_SYS);
- SPELLexecutor::instance().command(cmd,false);
- }
- else if ( st == STATUS_WAITING )
- {
- ExecutorCommand cmd;
- cmd.id = CMD_INTERRUPT;
- warning("Communication with controlling GUI interrupted. Procedure interruptedfor safety.", LanguageConstants::SCOPE_SYS);
- warning("You may try to resume execution.", LanguageConstants::SCOPE_SYS);
- SPELLexecutor::instance().command(cmd,false);
- }
- }
- }
- return;
+
+ return false;
}
}
}
- if (!m_ready) return;
+ if (!m_ready) return false;
usleep(52000);
}
}
+ return false;
}
//=============================================================================
@@ -825,7 +857,7 @@ void SPELLserverCif::waitAcknowledge( const SPELLipcMessage& msg )
void SPELLserverCif::specificNotifyError( const std::string& error, const std::string& reason, bool fatal )
{
//LOG_ERROR("[CIF] Error notification: " + error + " (" + reason + ")");
-
+ SPELLsafeThreadOperations ops("Notify");
// prepare error message
SPELLipcMessage errorMsg( MessageId::MSG_ID_ERROR);
errorMsg.setType(MSG_TYPE_ERROR);
@@ -852,71 +884,77 @@ void SPELLserverCif::specificNotifyError( const std::string& error, const std::s
//=============================================================================
// METHOD: SPELLserverCif::specificWrite
//=============================================================================
-void SPELLserverCif::specificWrite( const std::string& msg, unsigned int scope )
+void SPELLserverCif::specificWrite( const std::string& msgText, unsigned int scope )
{
if (isManual())
{
- completeMessage( m_wrMessage );
+ SPELLsafeThreadOperations ops("Notify");
+ SPELLipcMessage msg = m_wrMessage;
+ completeMessage( msg );
std::string timeStr = SPELLutils::timestampUsec();
- m_wrMessage.set(MessageField::FIELD_TEXT,msg);
- m_wrMessage.set(MessageField::FIELD_LEVEL,MessageValue::DATA_SEVERITY_INFO);
- m_wrMessage.set(MessageField::FIELD_MSGTYPE,LanguageConstants::DISPLAY);
- m_wrMessage.set(MessageField::FIELD_TIME, timeStr);
- m_wrMessage.set(MessageField::FIELD_SCOPE, ISTR(scope));
- sendGUIMessage(m_wrMessage);
+ msg.set(MessageField::FIELD_TEXT,msgText);
+ msg.set(MessageField::FIELD_LEVEL,MessageValue::DATA_SEVERITY_INFO);
+ msg.set(MessageField::FIELD_MSGTYPE,LanguageConstants::DISPLAY);
+ msg.set(MessageField::FIELD_TIME, timeStr);
+ msg.set(MessageField::FIELD_SCOPE, ISTR(scope));
+ sendGUIMessage(msg);
}
else
{
- m_buffer->write( msg, scope );
+ m_buffer->write( msgText, scope );
}
}
//=============================================================================
// METHOD: SPELLserverCif::specificWarning
//=============================================================================
-void SPELLserverCif::specificWarning( const std::string& msg, unsigned int scope )
+void SPELLserverCif::specificWarning( const std::string& msgText, unsigned int scope )
{
// We shall not bufferize in manual mode
if (isManual())
{
- completeMessage( m_wrMessage );
+ SPELLsafeThreadOperations ops("Notify");
+ SPELLipcMessage msg = m_wrMessage;
+ completeMessage( msg );
std::string timeStr = SPELLutils::timestampUsec();
- m_wrMessage.set(MessageField::FIELD_TEXT,msg);
- m_wrMessage.set(MessageField::FIELD_LEVEL,MessageValue::DATA_SEVERITY_WARN);
- m_wrMessage.set(MessageField::FIELD_MSGTYPE,LanguageConstants::DISPLAY);
- m_wrMessage.set(MessageField::FIELD_TIME, timeStr);
- m_wrMessage.set(MessageField::FIELD_SCOPE, ISTR(scope));
- sendGUIMessage(m_wrMessage);
+ msg.set(MessageField::FIELD_TEXT,msgText);
+ msg.set(MessageField::FIELD_LEVEL,MessageValue::DATA_SEVERITY_WARN);
+ msg.set(MessageField::FIELD_MSGTYPE,LanguageConstants::DISPLAY);
+ msg.set(MessageField::FIELD_TIME, timeStr);
+ msg.set(MessageField::FIELD_SCOPE, ISTR(scope));
+ sendGUIMessage(msg);
}
else
{
- m_buffer->warning( msg, scope );
+ m_buffer->warning( msgText, scope );
}
}
//=============================================================================
// METHOD: SPELLserverCif::specificError
-//=============================================================================
-void SPELLserverCif::specificError( const std::string& msg, unsigned int scope )
+//==============================b===============================================
+void SPELLserverCif::specificError( const std::string& msgText, unsigned int scope )
{
// We shall not bufferize in manual mode
if (isManual())
{
- completeMessage( m_wrMessage );
+ SPELLsafeThreadOperations ops("Notify");
+ SPELLipcMessage msg = m_wrMessage;
+ completeMessage( msg );
std::string timeStr = SPELLutils::timestampUsec();
- m_wrMessage.set(MessageField::FIELD_TEXT,msg);
- m_wrMessage.set(MessageField::FIELD_LEVEL,MessageValue::DATA_SEVERITY_ERROR);
- m_wrMessage.set(MessageField::FIELD_MSGTYPE,LanguageConstants::DISPLAY);
- m_wrMessage.set(MessageField::FIELD_TIME, timeStr);
- m_wrMessage.set(MessageField::FIELD_SCOPE, ISTR(scope));
- sendGUIMessage(m_wrMessage);
+ msg.set(MessageField::FIELD_TEXT,msgText);
+ msg.set(MessageField::FIELD_LEVEL,MessageValue::DATA_SEVERITY_ERROR);
+ msg.set(MessageField::FIELD_MSGTYPE,LanguageConstants::DISPLAY);
+ msg.set(MessageField::FIELD_TIME, timeStr);
+ msg.set(MessageField::FIELD_SCOPE, ISTR(scope));
+ sendGUIMessage(msg);
}
else
{
- m_buffer->error( msg, scope );
+ m_buffer->error( msgText, scope );
}
} //void SPELLserverCif::specificError( const std::string& msg, unsigned int scope )
@@ -928,6 +966,7 @@ void SPELLserverCif::specificNotifyVariableChange( const std::vector& changed,
const std::vector& deleted )
{
+ SPELLsafeThreadOperations ops("Notify");
m_wovBuffer->variableChange(added,changed,deleted);
}
@@ -938,7 +977,8 @@ void SPELLserverCif::specificNotifyVariableScopeChange( const std::string& scope
const std::vector& globals,
const std::vector& locals )
{
- SPELLipcMessage notifyMsg(ExecutorMessages::MSG_SCOPE_CHANGE);
+ SPELLsafeThreadOperations ops("Notify");
+ SPELLipcMessage notifyMsg(ExecutorMessages::MSG_SCOPE_CHANGE);
notifyMsg.setType(MSG_TYPE_ONEWAY);
std::string names = "";
@@ -989,11 +1029,34 @@ void SPELLserverCif::specificNotifyVariableScopeChange( const std::string& scope
sendGUIMessage(notifyMsg);
}
+//=============================================================================
+// METHOD: SPELLserverCif::specificNotifyResourceChange()
+//=============================================================================
+void SPELLserverCif::specificNotifyResourceChange( const std::vector& changed )
+{
+ SPELLsafeThreadOperations ops("Notify");
+ m_rdotcoBuffer->resourceChange(changed);
+}
+
+//=============================================================================
+// METHOD: SPELLserverCif::specificNotifyResourceList()
+//=============================================================================
+void SPELLserverCif::specificNotifyResourceList( const std::vector& resources )
+{
+ SPELLsafeThreadOperations ops("Notify");
+ m_rdotcoBuffer->resourceList(resources);
+}
+
//=============================================================================
// METHOD: SPELLserverCif::specificPrompt
//=============================================================================
void SPELLserverCif::specificPrompt( const SPELLpromptDefinition& def, std::string& rawAnswer, std::string& answerToShow )
{
+ PyThreadState* m_state;
+ m_state = SPELLpythonHelper::instance().beginSafeAllowThreads();
+ SPELLmonitor m(m_promptLock);
+ SPELLpythonHelper::instance().endSafeAllowThreads( m_state );
+
m_promptDef = def;
std::string timeStr = SPELLutils::timestampUsec();
@@ -1013,7 +1076,7 @@ void SPELLserverCif::specificPrompt( const SPELLpromptDefinition& def, std::stri
DEBUG("[CIF] Prompt typecode " + ISTR(def.typecode));
// the prompt display
- std::string msgToShow = def.message;
+ std::string msgToShow = "";
if ( def.options.size() == 0 )
{
@@ -1030,7 +1093,9 @@ void SPELLserverCif::specificPrompt( const SPELLpromptDefinition& def, std::stri
DEBUG("[CIF] Expected string: " + m_promptMessage.get(MessageField::FIELD_EXPECTED));
// Send the display message via the buffer to ensure synchronization
- m_buffer->prompt(msgToShow, LanguageConstants::SCOPE_PROMPT);
+ m_asRun->writeInfo( getStack(), msgToShow, LanguageConstants::SCOPE_PROMPT );
+
+ m_buffer->prompt(def.message + "\n" + msgToShow, LanguageConstants::SCOPE_PROMPT);
// Ensure buffer is flushed
m_buffer->flush();
@@ -1097,11 +1162,14 @@ void SPELLserverCif::specificPrompt( const SPELLpromptDefinition& def, std::stri
// \todo When there is no controlling client we should keep the child procedure in prompt waiting state
// Send the display message via the buffer to ensure synchronization
- m_buffer->write("Answer: '" + toShow + "'", LanguageConstants::SCOPE_PROMPT);
- m_buffer->flush();
+ if ( (def.typecode & LanguageConstants::PROMPT_PASSWORD)>0)
+ m_buffer->write("Answer: '***'", LanguageConstants::SCOPE_PROMPT);
+ else
+ m_buffer->write("Answer: '" + toShow + "'", LanguageConstants::SCOPE_PROMPT);
+ m_buffer->flush();
- rawAnswer = toProcess;
- answerToShow = toShow;
+ rawAnswer = toProcess;
+ answerToShow = toShow;
}
//=============================================================================
@@ -1109,6 +1177,7 @@ void SPELLserverCif::specificPrompt( const SPELLpromptDefinition& def, std::stri
//=============================================================================
std::string SPELLserverCif::specificOpenSubprocedure( const std::string& procId, int callingLine, const std::string& args, bool automatic, bool blocking, bool visible )
{
+ SPELLsafeThreadOperations ops("Notify");
std::string openModeStr = "{";
DEBUG("[CIF] Open subprocedure options: " + BSTR(automatic) + "," + BSTR(blocking) + "," + BSTR(visible));
openModeStr += (automatic ? (LanguageModifiers::Automatic + ":" + PythonConstants::True) : (LanguageModifiers::Automatic + ":" + PythonConstants::False)) + ",";
@@ -1185,6 +1254,7 @@ std::string SPELLserverCif::specificOpenSubprocedure( const std::string& procId,
//=============================================================================
void SPELLserverCif::specificCloseSubprocedure( const std::string& procId )
{
+ SPELLsafeThreadOperations ops("Notify");
SPELLipcMessage closeMsg(ContextMessages::REQ_CLOSE_EXEC);
closeMsg.setType(MSG_TYPE_REQUEST);
closeMsg.set(MessageField::FIELD_SPROC_ID, procId);
@@ -1197,6 +1267,7 @@ void SPELLserverCif::specificCloseSubprocedure( const std::string& procId )
//=============================================================================
void SPELLserverCif::specificKillSubprocedure( const std::string& procId )
{
+ SPELLsafeThreadOperations ops("Notify");
SPELLipcMessage killMsg(ContextMessages::REQ_KILL_EXEC);
killMsg.setType(MSG_TYPE_REQUEST);
killMsg.set(MessageField::FIELD_SPROC_ID, procId);
@@ -1265,6 +1336,7 @@ void SPELLserverCif::processMessage( const SPELLipcMessage& msg )
if (msgId == MessageId::MSG_ID_ADD_CLIENT)
{
LOG_INFO("Add controlling client");
+ SPELLexecutor::instance().refreshStatus();
if (msg.hasField(MessageField::FIELD_GUI_CONTROL))
{
getExecutorConfig().setHeadless( false );
@@ -1275,6 +1347,16 @@ void SPELLserverCif::processMessage( const SPELLipcMessage& msg )
else if (msgId == MessageId::MSG_ID_REMOVE_CLIENT)
{
LOG_WARN("Controlling client removed");
+
+ // In case of a (Warning) text to submit to GCS send it
+ if (msg.hasField(MessageField::FIELD_TEXT) &&
+ msg.hasField(MessageField::FIELD_GUI_CONTROL) &&
+ msg.get(MessageField::FIELD_GUI_CONTROL) == getExecutorConfig().getControlClient()) {
+ LOG_WARN("[CIF] " + msg.get(MessageField::FIELD_TEXT));
+ SPELLexecutor::instance().getScheduler().raiseWarningEventToGCS(msg.get(MessageField::FIELD_TEXT));
+ }
+
+ SPELLexecutor::instance().refreshStatus();
switch(SPELLexecutor::instance().getStatus())
{
case STATUS_FINISHED:
@@ -1315,6 +1397,14 @@ void SPELLserverCif::processMessage( const SPELLipcMessage& msg )
{
SPELLexecutor::instance().getVariableManager().setEnabled(false);
}
+ else if (msgId == MessageId::MSG_ID_DRESOURCES_ENABLE)
+ {
+ SPELLexecutor::instance().getResourceManager().setEnabled(true);
+ }
+ else if (msgId == MessageId::MSG_ID_DRESOURCES_DISABLE)
+ {
+ SPELLexecutor::instance().getResourceManager().setEnabled(false);
+ }
else
{
processMessageCommand(msg);
@@ -1446,6 +1536,18 @@ SPELLipcMessage SPELLserverCif::processRequest( const SPELLipcMessage& msg )
{
m_processor.processCheckVariablesEnabled(msg, response);
}
+ else if (requestId == ExecutorMessages::REQ_GET_RESOURCES)
+ {
+ m_processor.processGetResources(msg, response);
+ }
+ else if (requestId == ExecutorMessages::REQ_CHANGE_RESOURCE)
+ {
+ m_processor.processChangeResource(msg, response);
+ }
+ else if (requestId == ExecutorMessages::REQ_DRESOURCES_ENABLED)
+ {
+ m_processor.processCheckResourcesEnabled(msg, response);
+ }
else if (requestId == ExecutorMessages::REQ_GET_DICTIONARY)
{
m_processor.processGetDictionary(msg, response);
@@ -1468,6 +1570,20 @@ void SPELLserverCif::processConnectionError( int clientKey, std::string error, s
{
if (!isClosing())
{
+ // send an alert to the GCS if context disconnect in transitionning states
+ switch(SPELLexecutor::instance().getStatus())
+ {
+ case STATUS_FINISHED:
+ case STATUS_PAUSED:
+ case STATUS_ABORTED:
+ case STATUS_ERROR:
+ case STATUS_PROMPT:
+ case STATUS_INTERRUPTED:
+ break;
+ default:
+ SPELLexecutor::instance().getScheduler().raiseWarningEventToGCS("Procedure lost SPELL Context, check and resume: "+ getProcId());
+ }
+
m_ready = false;
LOG_ERROR("IPC error: " + error + ": " + reason);
SPELLexecutor::instance().pause();
@@ -1578,7 +1694,7 @@ void SPELLserverCif::waitPromptAnswer()
// Finish the prompt state
SPELLexecutor::instance().getScheduler().finishPrompt();
-
+ //SPELLexecutor::instance().getScheduler().wait();
m_promptMessage = VOID_MESSAGE;
}
@@ -1800,4 +1916,42 @@ void SPELLserverCif::removeSharedDataScopes()
{
THROW_EXCEPTION(response.get(MessageField::FIELD_ERROR),response.get(MessageField::FIELD_REASON), SPELL_ERROR_ENVIRONMENT);
}
+
+}
+SPELLipcMessage SPELLserverCif::getPingMessage()
+{
+ if (SPELLexecutor::instance().hasController()) {
+ SPELLcontrollerIF& controller =
+ SPELLexecutor::instance().getController();
+
+ SPELLstatusInfo st(controller.getStatus());
+ st.condition = controller.getCondition();
+ st.actionLabel = SPELLexecutor::instance().getUserAction().getLabel();
+ st.actionEnabled =
+ SPELLexecutor::instance().getUserAction().isEnabled();
+
+ m_stMessage.set(MessageField::FIELD_EXEC_STATUS,
+ SPELLexecutorUtils::statusToString(st.status));
+ completeMessage(m_stMessage);
+
+ // Set message Condition information
+ if (st.condition.size() > 0) {
+ m_stMessage.set(MessageField::FIELD_CONDITION, st.condition);
+ }
+
+ // Set message Action information
+ if (st.actionLabel != "") {
+ m_stMessage.set(MessageField::FIELD_ACTION_LABEL, st.actionLabel);
+ m_stMessage.set(MessageField::FIELD_ACTION_ENABLED,
+ st.actionEnabled ?
+ MessageValue::DATA_TRUE : MessageValue::DATA_FALSE);
+ }
+
+ return m_stMessage;
+ }
+ else
+ {
+ return SPELLipcMessage();
+ }
+
}
diff --git a/lib/SPELL_CIFS/src/SPELLvariableBuffer.C b/lib/SPELL_CIFS/src/SPELLvariableBuffer.C
index a0ff793..2517521 100644
--- a/lib/SPELL_CIFS/src/SPELLvariableBuffer.C
+++ b/lib/SPELL_CIFS/src/SPELLvariableBuffer.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the WOV messages buffer
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_CTX/Makefile.am b/lib/SPELL_CTX/Makefile.am
index 9272c3c..8bb4801 100644
--- a/lib/SPELL_CTX/Makefile.am
+++ b/lib/SPELL_CTX/Makefile.am
@@ -1,51 +1,72 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
include ${top_srcdir}/common.mk
-#libSPELL_EXC_la_CPPFLAGS = ${AM_CPPFLAGS} -DWITH_DEBUG
-
-lib_LTLIBRARIES= libSPELL_CTX.la
-libSPELL_CTX_la_LDFLAGS = -version-info 3:0:0
-libSPELL_CTX_la_SOURCES = \
- src/SPELLclient.C \
- src/SPELLclientInterestList.C \
- src/SPELLclientIPC.C \
- src/SPELLclientManager.C \
- src/SPELLclientNotifier.C \
- src/SPELLcontext.C \
- src/SPELLdataHelper.C \
- src/SPELLexecutor.C \
- src/SPELLexecutorIPC.C \
- src/SPELLexecutorOperation.C \
- src/SPELLexecutorManager.C \
- src/SPELLexecutorModel.C \
- src/SPELLlistenerIPC.C \
- src/SPELLpersistencyTable.C \
- src/SPELLsharedData.C \
- src/SPELLdataTable.C
-
-
\ No newline at end of file
+lib_LTLIBRARIES = libSPELL_CTX_v2.la libSPELL_CTX_v3.la
+
+libSPELL_CTX_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+
+libSPELL_CTX_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_CTX_v2_la_SOURCES = src/SPELLclient.C \
+ src/SPELLclientInterestList.C \
+ src/SPELLclientIPC.C \
+ src/SPELLclientManager.C \
+ src/SPELLclientNotifier.C \
+ src/SPELLcontext.C \
+ src/SPELLdataHelper.C \
+ src/SPELLexecutor.C \
+ src/SPELLexecutorIPC.C \
+ src/SPELLexecutorOperation.C \
+ src/SPELLexecutorManager.C \
+ src/SPELLexecutorModel.C \
+ src/SPELLservice.C \
+ src/SPELLserviceManager.C \
+ src/SPELLlistenerIPC.C \
+ src/SPELLpersistencyTable.C \
+ src/SPELLsharedData.C \
+ src/SPELLdataTable.C
+
+
+libSPELL_CTX_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS}
+
+libSPELL_CTX_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_CTX_v3_la_SOURCES = src/SPELLclient.C \
+ src/SPELLclientInterestList.C \
+ src/SPELLclientIPC.C \
+ src/SPELLclientManager.C \
+ src/SPELLclientNotifier.C \
+ src/SPELLcontext.C \
+ src/SPELLdataHelper.C \
+ src/SPELLexecutor.C \
+ src/SPELLexecutorIPC.C \
+ src/SPELLexecutorOperation.C \
+ src/SPELLexecutorManager.C \
+ src/SPELLexecutorModel.C \
+ src/SPELLservice.C \
+ src/SPELLserviceManager.C \
+ src/SPELLlistenerIPC.C \
+ src/SPELLpersistencyTable.C \
+ src/SPELLsharedData.C \
+ src/SPELLdataTable.C
+
\ No newline at end of file
diff --git a/lib/SPELL_CTX/src/SPELLclient.C b/lib/SPELL_CTX/src/SPELLclient.C
index e77382b..5b24327 100644
--- a/lib/SPELL_CTX/src/SPELLclient.C
+++ b/lib/SPELL_CTX/src/SPELLclient.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the client
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -179,6 +179,10 @@ SPELLipcMessage SPELLclient::processRequestFromClient( const SPELLipcMessage& ms
{
resp = SPELLcontext::instance().getExecutorList( msg );
}
+ else if (msg.getId() == ContextMessages::REQ_SERVICE_LIST)
+ {
+ resp = SPELLcontext::instance().getServiceList( msg );
+ }
else if (msg.getId() == ContextMessages::REQ_PROC_PROP)
{
resp = SPELLcontext::instance().getProcedureProperties( msg );
@@ -191,6 +195,10 @@ SPELLipcMessage SPELLclient::processRequestFromClient( const SPELLipcMessage& ms
{
resp = SPELLcontext::instance().getExecutorInfo( msg );
}
+ else if (msg.getId() == ContextMessages::REQ_SERVICE_INFO)
+ {
+ resp = SPELLcontext::instance().getServiceInfo( msg );
+ }
else if (msg.getId() == ContextMessages::REQ_CLIENT_INFO)
{
resp = SPELLcontext::instance().getClientInfo( msg );
diff --git a/lib/SPELL_CTX/src/SPELLclientIPC.C b/lib/SPELL_CTX/src/SPELLclientIPC.C
index 4095686..56ba56f 100644
--- a/lib/SPELL_CTX/src/SPELLclientIPC.C
+++ b/lib/SPELL_CTX/src/SPELLclientIPC.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the client IPC interface
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -47,8 +47,11 @@
//=============================================================================
SPELLclientIPC::SPELLclientIPC()
: SPELLipcInterfaceListener(),
+#ifdef WITH_KUBERNETES
+ m_ipc("CTX-TO-GUI", 888, 19888)
+#else
m_ipc("CTX-TO-GUI", 888, 0)
-
+#endif
{
SPELLclientManager::instance().setIPC(this);
}
@@ -133,6 +136,7 @@ void SPELLclientIPC::unregisterInterest( int clientKey, SPELLclientListener* lis
//=============================================================================
void SPELLclientIPC::processMessage( const SPELLipcMessage& msg )
{
+ LOG_INFO("[CLTRCV] Received message from client " + ISTR(msg.getKey()) + ": " + msg.getId() + " for ("+msg.get("User")+")");
// Get the peer key
int clientKey = msg.getKey();
@@ -148,8 +152,9 @@ void SPELLclientIPC::processMessage( const SPELLipcMessage& msg )
//=============================================================================
SPELLipcMessage SPELLclientIPC::processRequest( const SPELLipcMessage& msg )
{
+ if (msg.getId() != ContextMessages::REQ_CURRENT_TIME)
+ LOG_INFO("[CLTRCV] Received request from client " + ISTR(msg.getKey()) + ": " + msg.getId() + " for ("+msg.get("User")+")");
int clientKey = msg.getKey();
- DEBUG("[CLTRCV] Received request from client: " + msg.getId());
SPELLipcMessage resp = VOID_MESSAGE;
SPELLclientInterestList* list = getClientInterestList(clientKey);
// If the message is a login message, redirect it to the client manager
@@ -193,7 +198,12 @@ SPELLipcMessage SPELLclientIPC::processRequest( const SPELLipcMessage& msg )
}
else
{
- LOG_ERROR("No listeners for client " + ISTR(clientKey) + " to distribute request: " + msg.getId());
+ if (msg.getId() == ContextMessages::REQ_CURRENT_TIME) {
+ resp = SPELLcontext::instance().getCurrentTime(msg);
+ return resp;
+ } else {
+ LOG_ERROR("No listeners for client " + ISTR(clientKey) + " to distribute request: " + msg.getId());
+ }
}
return resp;
}
diff --git a/lib/SPELL_CTX/src/SPELLclientInterestList.C b/lib/SPELL_CTX/src/SPELLclientInterestList.C
index 0d8ba7f..df78699 100644
--- a/lib/SPELL_CTX/src/SPELLclientInterestList.C
+++ b/lib/SPELL_CTX/src/SPELLclientInterestList.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the client interest list
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_CTX/src/SPELLclientManager.C b/lib/SPELL_CTX/src/SPELLclientManager.C
index f5fd20c..48ca00d 100644
--- a/lib/SPELL_CTX/src/SPELLclientManager.C
+++ b/lib/SPELL_CTX/src/SPELLclientManager.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Client manager implementation
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -29,12 +29,15 @@
#include "SPELL_CTX/SPELLclientManager.H"
#include "SPELL_CTX/SPELLclient.H"
#include "SPELL_CTX/SPELLdataHelper.H"
+#include "SPELL_CTX/SPELLexecutorManager.H"
// Project includes --------------------------------------------------------
#include "SPELL_SYN/SPELLmonitor.H"
#include "SPELL_UTIL/SPELLlog.H"
#include "SPELL_UTIL/SPELLutils.H"
#include "SPELL_IPC/SPELLipc_Context.H"
#include "SPELL_IPC/SPELLipc_Executor.H"
+#include "SPELL_UTIL/SPELLerror.H"
+#include "SPELL_PRD/SPELLprocedureManager.H"
// System includes ---------------------------------------------------------
@@ -46,7 +49,7 @@ SPELLclientManager* SPELLclientManager::s_instance = NULL;
//=============================================================================
SPELLclientManager::SPELLclientManager()
{
-
+ m_ipc = NULL;
}
//=============================================================================
@@ -98,7 +101,7 @@ void SPELLclientManager::clientLogin( int clientKey, const std::string& host )
SPELLclient* client = new SPELLclient( clientKey, host, *m_ipc );
m_clientMap.insert( std::make_pair( clientKey, client ));
- DEBUG("[CMGR] Client logged in: " + ISTR(clientKey));
+ LOG_INFO("[CMGR] Client logged in: " + ISTR(clientKey) + " running on " + host);
notifyClientOperation( clientKey, host, CLIENT_OP_LOGIN );
}
@@ -118,6 +121,29 @@ void SPELLclientManager::clientLogout( int clientKey )
if (it != m_clientMap.end())
{
SPELLclient* client = it->second;
+
+ SPELLclient::ProcedureList procs = client->getProcedures();
+ SPELLclient::ProcedureList::iterator pit;
+ for ( pit = procs.begin(); pit != procs.end(); pit++ )
+ {
+ try
+ {
+ SPELLexecutor* exec = SPELLexecutorManager::instance().getExecutor( pit->first );
+ if (pit->second == CLIENT_MODE_CONTROL )
+ {
+ SPELLclientManager::instance().removeExecutorController(client, exec, true, true);
+ LOG_WARN("Client " + ISTR(clientKey) + " stop controlling executor " + exec->getModel().getInstanceId());
+ }
+ else
+ {
+ SPELLclientManager::instance().stopMonitorExecutor(client, exec);
+ LOG_INFO("Client " + ISTR(clientKey) + " stop monitoring executor " + exec->getModel().getInstanceId());
+ }
+ }
+ catch(SPELLcoreException& ex){};
+ }
+ DEBUG("Client " + ISTR(clientKey) + " logged out, stopping procedures done");
+
std::string host = client->getClientHost();
LOG_INFO("Client logged out: " + ISTR(clientKey) + ":" + host);
delete client;
@@ -141,6 +167,27 @@ void SPELLclientManager::clientLost( int clientKey )
if (it != m_clientMap.end())
{
SPELLclient* client = it->second;
+ SPELLclient::ProcedureList procs = client->getProcedures();
+ SPELLclient::ProcedureList::iterator pit;
+ for ( pit = procs.begin(); pit != procs.end(); pit++ )
+ {
+ try
+ {
+ SPELLexecutor* exec = SPELLexecutorManager::instance().getExecutor( pit->first );
+ if (pit->second == CLIENT_MODE_CONTROL )
+ {
+ SPELLclientManager::instance().removeExecutorController(client, exec, true, true);
+ LOG_WARN("Client lost:" + ISTR(clientKey) + " stop controlling executor " + exec->getModel().getInstanceId());
+ }
+ else
+ {
+ SPELLclientManager::instance().stopMonitorExecutor(client, exec);
+ LOG_INFO("Client lost:" + ISTR(clientKey) + " stop monitoring executor " + exec->getModel().getInstanceId());
+ }
+ }
+ catch(SPELLcoreException& ex){};
+ }
+
std::string host = client->getClientHost();
LOG_WARN("Client lost: " + ISTR(clientKey) + ":" + host);
delete client;
@@ -244,6 +291,8 @@ void SPELLclientManager::stopMonitorExecutor( SPELLclient* client, SPELLexecutor
}
}
+
+
//=============================================================================
// METHOD: SPELLclientManager::
//=============================================================================
@@ -262,6 +311,11 @@ std::list SPELLclientManager::getMonitoringClients( const std::stri
monitoring.push_back(id);
}
}
+ if (monitoring.empty() && procId.find("#") != std::string::npos)
+ {
+ std::string newId = noInstanceId(procId);
+ return getMonitoringClients(newId);
+ }
return monitoring;
}
@@ -282,6 +336,11 @@ std::list SPELLclientManager::getMonitoringClientsKeys( const std::string&
keys.push_back(notifier->getClientKey());
}
}
+ if (keys.empty() && procId.find("#") != std::string::npos)
+ {
+ std::string newId = noInstanceId(procId);
+ return getMonitoringClientsKeys(newId);
+ }
return keys;
}
@@ -316,9 +375,9 @@ void SPELLclientManager::notifyClientOperation( int clientKey,
notification.set( MessageField::FIELD_GUI_KEY, ISTR(clientKey));
notification.set( MessageField::FIELD_CLOP, SPELLdataHelper::clientOperationToString(operation) );
notification.set( MessageField::FIELD_HOST, host );
-
ClientMap::const_iterator it;
- for( it = m_clientMap.begin(); it != m_clientMap.end(); it++ )
+ ClientMap clientMap = m_clientMap;
+ for( it = clientMap.begin(); it != clientMap.end(); it++ )
{
SPELLclient* client = it->second;
if (client->getClientKey() == clientKey) continue;
@@ -336,7 +395,8 @@ void SPELLclientManager::notifyClients( const SPELLipcMessage& msg )
SPELLmonitor m(m_clientLock);
DEBUG("Notify clients IN");
ClientMap::const_iterator it;
- for( it = m_clientMap.begin(); it != m_clientMap.end(); it++ )
+ ClientMap clientMap = m_clientMap;
+ for( it = clientMap.begin(); it != clientMap.end(); it++ )
{
SPELLclient* client = it->second;
DEBUG(" - client " + ISTR(it->first));
@@ -355,7 +415,8 @@ void SPELLclientManager::notifyMonitoringClients( const SPELLipcMessage& msg )
DEBUG("Notify monitoring clients IN");
ClientMap::const_iterator it;
int controllingKey = msg.getKey();
- for( it = m_clientMap.begin(); it != m_clientMap.end(); it++ )
+ ClientMap clientMap = m_clientMap;
+ for( it = clientMap.begin(); it != clientMap.end(); it++ )
{
SPELLclient* client = it->second;
if (it->first == controllingKey) continue;
diff --git a/lib/SPELL_CTX/src/SPELLclientNotifier.C b/lib/SPELL_CTX/src/SPELLclientNotifier.C
index e783c75..af069c0 100644
--- a/lib/SPELL_CTX/src/SPELLclientNotifier.C
+++ b/lib/SPELL_CTX/src/SPELLclientNotifier.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the client notifier
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_CTX/src/SPELLcontext.C b/lib/SPELL_CTX/src/SPELLcontext.C
index 4383e40..966945c 100644
--- a/lib/SPELL_CTX/src/SPELLcontext.C
+++ b/lib/SPELL_CTX/src/SPELLcontext.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the context main class
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -26,11 +26,12 @@
// FILES TO INCLUDE ////////////////////////////////////////////////////////
// Local includes ----------------------------------------------------------
+#include "SPELL_PRD/SPELLservicePython.H"
#include "SPELL_CTX/SPELLcontext.H"
#include "SPELL_CTX/SPELLclientManager.H"
#include "SPELL_CTX/SPELLexecutorManager.H"
+#include "SPELL_CTX/SPELLserviceManager.H"
#include "SPELL_CTX/SPELLdataHelper.H"
-// Project includes --------------------------------------------------------
#include "SPELL_SYN/SPELLmonitor.H"
#include "SPELL_WRP/SPELLconstants.H"
#include "SPELL_WRP/SPELLdriverManager.H"
@@ -46,9 +47,9 @@
#include "SPELL_IPC/SPELLipc_Context.H"
#include "SPELL_IPC/SPELLipc_Listener.H"
#include "SPELL_SDB/SPELLdatabaseFactory.H"
+#include "SPELL_WRP/SPELLdatabaseManager.H"
// System includes ---------------------------------------------------------
-
// DEFINES /////////////////////////////////////////////////////////////////
#define NAME std::string("[CTX] ")
@@ -56,7 +57,26 @@ SPELLcontext* SPELLcontext::s_instance = NULL;
const std::string USE_DRIVER_TIME = "UseDriverTime";
-
+extern "C" {
+ void checkService(std::string& serviceId) {
+ SPELLsafeThreadOperations ops("checkService");
+ SPELLserviceManager::ServiceList runningServices = SPELLserviceManager::instance().getServiceList();
+ for(SPELLserviceManager::ServiceList::iterator it = runningServices.begin();it != runningServices.end();++it)
+ {
+ //LOG_INFO("Service " + (*it) + " found!");
+ if (*it == serviceId)
+ {
+ SPELLservice* service = SPELLserviceManager::instance().getService(serviceId);
+ if (service && service->isActive())
+ {
+ return;
+ }
+ }
+ }
+
+ SPELLcontext::instance().openService(serviceId);
+ }
+}
//=============================================================================
// CONSTRUCTOR: SPELLcontext::SPELLcontext()
//=============================================================================
@@ -100,6 +120,7 @@ void SPELLcontext::start( const SPELLcontextConfiguration& config )
// Setup the configuration
SPELLconfiguration::instance().loadConfig(m_config.configFile);
+
// Configure the time format if defined in configuration
std::string format = SPELLconfiguration::instance().getCommonParameter("TdsTimeFormat");
if (format.length()!=0)
@@ -126,8 +147,11 @@ void SPELLcontext::start( const SPELLcontextConfiguration& config )
m_executorDefaults.setPromptWarningDelay( STRI(srvConfig.getExecutorParameter(ExecutorConstants::PromptDelay)) );
m_executorDefaults.setByStep( srvConfig.getExecutorParameter(ExecutorConstants::ByStep) == ExecutorConstants::TRUE_VALUE );
m_executorDefaults.setForceTcConfirm( srvConfig.getExecutorParameter(ExecutorConstants::ForceTcConfirm) == ExecutorConstants::TRUE_VALUE );
+ m_executorDefaults.setForcePromptConfirm( srvConfig.getExecutorParameter(ExecutorConstants::ForcePromptConfirm) == ExecutorConstants::TRUE_VALUE );
m_executorDefaults.setSaveStateMode( srvConfig.getExecutorParameter(ExecutorConstants::SaveStateMode) );
m_executorDefaults.setWatchVariables( srvConfig.getExecutorParameter(ExecutorConstants::WatchVariables) == ExecutorConstants::ENABLED );
+ m_executorDefaults.setResourcesDisplay( srvConfig.getExecutorParameter(ExecutorConstants::ResourcesDisplay) == ExecutorConstants::ENABLED );
+ m_executorDefaults.setLocalResourcesSupported( srvConfig.getExecutorParameter(ExecutorConstants::LocalResourcesSupported) == ExecutorConstants::TRUE_VALUE );
m_executorDefaults.setMaxVerbosity( STRI(srvConfig.getExecutorParameter(ExecutorConstants::MaxVerbosity)) );
m_executorDefaults.setBrowsableLibStr( srvConfig.getExecutorParameter(ExecutorConstants::BrowsableLib) );
@@ -141,11 +165,17 @@ void SPELLcontext::start( const SPELLcontextConfiguration& config )
if( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::ByStep) != "" )
m_executorDefaults.setByStep( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::ByStep) == ExecutorConstants::TRUE_VALUE );
if( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::ForceTcConfirm) != "" )
- m_executorDefaults.setForceTcConfirm( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::ForceTcConfirm) == ExecutorConstants::TRUE_VALUE );
+ m_executorDefaults.setForceTcConfirm( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::ForceTcConfirm) == ExecutorConstants::TRUE_VALUE );
+ if( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::ForcePromptConfirm) != "" )
+ m_executorDefaults.setForcePromptConfirm( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::ForcePromptConfirm) == ExecutorConstants::TRUE_VALUE );
if( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::SaveStateMode) != "" )
m_executorDefaults.setSaveStateMode( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::SaveStateMode) );
if( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::SaveStateMode) != "" )
m_executorDefaults.setWatchVariables( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::WatchVariables) == ExecutorConstants::ENABLED );
+ if( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::ResourcesDisplay) != "" )
+ m_executorDefaults.setResourcesDisplay( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::ResourcesDisplay) == ExecutorConstants::ENABLED );
+ if( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::LocalResourcesSupported) != "" )
+ m_executorDefaults.setLocalResourcesSupported( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::LocalResourcesSupported) == ExecutorConstants::TRUE_VALUE );
if( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::MaxVerbosity) != "" )
m_executorDefaults.setMaxVerbosity( STRI(srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::MaxVerbosity)) );
if( srvConfig.getContext(getContextName()).getExecutorParameter(ExecutorConstants::BrowsableLib) != "" )
@@ -160,30 +190,52 @@ void SPELLcontext::start( const SPELLcontextConfiguration& config )
// Initialize Python support (some client requests require Python API)
SPELLpythonHelper::instance().initialize();
+ SPELLsafePythonOperations ops("Context Init");
+ SpellService_Install();
+
+ SPELLconfiguration::instance().loadPythonConfig(m_config.configFile);
+ if (SPELLconfiguration::instance().getContextParameter(USE_DRIVER_TIME) == "true")
+ {
+ // Setup the TIME driver for getCurrentTime (need to load Python config first)
+ SPELLdriverManager::instance().setup(getContextName(), "TIME");
+ }
+ else
+ {
+ SPELLdriverManager::instance().setup(getContextName(), "CONFIG");
+ }
+
+ SPELLpythonHelper::instance().loadFramework();
+ SPELLdatabaseManager::instance().loadBuiltinDatabases();
// Setup the procedure manager
SPELLprocedureManager::instance().setup( getContextName() );
- // Setup the executor manager. This may take time to come back, if
- // there are executors to reconnect to. The listener login message will be sent after this stage.
- SPELLexecutorManager::instance().setup( getContextName() );
-
- if (SPELLconfiguration::instance().getContextParameter(USE_DRIVER_TIME) == "true")
- {
- // Setup the TIME driver for getCurrentTime (need to load Python config first)
- SPELLconfiguration::instance().loadPythonConfig(m_config.configFile);
- SPELLdriverManager::instance().setup(getContextName(), "TIME");
- }
// Setup the IPC interfaces to clients and listener. The listener one logs in.
m_clientIPC.setup();
- m_listenerIPC.setup();
+ m_listenerIPC.setup();
+
+ // Setup the executor manager. This may take time to come back, if
+ // there are executors to reconnect to. The listener login message will be sent after this stage.
+ SPELLexecutorManager::instance().setup(getContextName());
+ SPELLserviceManager::instance().setup(getContextName());
- LOG_INFO("Context " + getContextName() + " ready" );
+ LOG_INFO("Context " + getContextName() + " ready" );
// SPELLpythonHelper::initialize has acquired the GIL. Release it so
// that operations in other threads (messages) can use it too.
- PyEval_ReleaseLock();
+
+
+ std::list serviceList = SPELLprocedureManager::instance().getServiceList();
+ std::list::iterator it = serviceList.begin();
+ for (; it != serviceList.end(); ++it)
+ {
+ LOG_INFO("Starting Service " + (*it) + "." );
+ //openService(*it);
+ SPELLpyService& exec = SPELLprocedureManager::instance().getService(*it);
+ exec.startWatchDog(&checkService);
+ }
+
}
//=============================================================================
@@ -291,8 +343,9 @@ SPELLipcMessage SPELLcontext::openExecutor( const SPELLipcMessage& msg, SPELLcli
std::string theOriginId = "GUI";
if (msg.hasField( MessageField::FIELD_ORIGIN_ID ))
{
- theOriginId = msg.get( MessageField::FIELD_ORIGIN_ID );
+ theOriginId = msg.get( MessageField::FIELD_ORIGIN_ID ) ;
}
+ theOriginId = theOriginId + " ("+msg.get("User")+")";
SPELLexecutorStartupParams config(theInstanceId, SPELLutils::fileTimestamp() );
@@ -322,6 +375,18 @@ SPELLipcMessage SPELLcontext::openExecutor( const SPELLipcMessage& msg, SPELLcli
try
{
+ SPELLprocedureManager::ProcList services = SPELLprocedureManager::instance().getServiceList();
+ SPELLprocedureManager::ProcList::const_iterator it = services.begin();
+ for (;it != services.end();++it)
+ {
+ if (config.getProcId() == *it)
+ {
+ resp = SPELLipcHelper::createErrorResponse( ContextMessages::RSP_OPEN_EXEC, msg );
+ resp.set( MessageField::FIELD_ERROR, "Cannot open selected service");
+ resp.set( MessageField::FIELD_REASON, "The select entry is a service and can't be started manually." );
+ return resp;
+ }
+ }
SPELLexecutorManager::instance().startExecutor( config, controllingClient );
resp = SPELLipcHelper::createResponse( ContextMessages::RSP_OPEN_EXEC, msg );
@@ -367,6 +432,86 @@ SPELLipcMessage SPELLcontext::openExecutor( const SPELLipcMessage& msg, SPELLcli
return resp;
}
+bool SPELLcontext::openService( const std::string serviceName )
+{
+ LOG_INFO( "Requested opening new service" );
+
+ // Get the information about procedure instance identifiers. Note that if the procedure
+ // has been started by another one, there will be a parent instance identifier in the request message.
+ //
+ // - The identifier of the child (subprocedure) will be in SPROC_ID in this case,
+ // - The identifier of the parent will be in the PROC_ID.
+ std::string theInstanceId = "";
+ std::string theParentInstanceId = "";
+ // Note that the group id matches the instance id for standalone procedures, but it is
+ // the id of the original main procedure for all the children down a dependency tree.
+ std::string theGroupId = serviceName;
+
+ // The following condition is for the case when we have a subprocedure being started.
+ int callingLine = 0;
+ theInstanceId = serviceName;
+
+ // Origin ID is just informative for SPELL and it is optional
+ std::string theOriginId = "SERVICE";
+
+ SPELLserviceStartupParams config(theInstanceId, SPELLutils::fileTimestamp() );
+
+ config.setArguments("");
+ config.setCondition("");
+ std::string cMode = MessageValue::DATA_GUI_MODE_B;
+ config.setClientMode(SPELLdataHelper::clientModeFromString(cMode));
+ std::string oMode = "1";
+ config.setOpenMode(SPELLdataHelper::openModeFromString(oMode));
+ config.setParentInstanceId(theParentInstanceId);
+ config.setParentCallingLine(callingLine);
+ config.setGroupId( theGroupId );
+ config.setOriginId( theOriginId );
+
+ LOG_INFO(" - Instance Id : " + config.getInstanceId());
+ LOG_INFO(" - Client mode : " + cMode);
+ LOG_INFO(" - Group Id : " + config.getGroupId());
+ LOG_INFO(" - Origin Id : " + config.getOriginId());
+ LOG_INFO(" - Calling line: " + ISTR(config.getParentCallingLine()) );
+ LOG_INFO(" - Time Id : " + config.getTimeId());
+ LOG_INFO(" - Proc Id : " + config.getProcId());
+ LOG_INFO(" - Instance num: " + ISTR(config.getInstanceNum()));
+ LOG_INFO(" - Arguments : " + config.getArguments());
+ LOG_INFO(" - Condition : " + config.getCondition());
+ LOG_INFO(" - Open mode : " + oMode);
+ LOG_INFO(" - Parent : " + config.getParentInstanceId());
+
+ try
+ {
+ SPELLserviceManager::instance().startService( config );
+
+ SPELLservice* exec = SPELLserviceManager::instance().getService(config.getInstanceId());
+ SPELLexecutorStatus initialStatus = exec->getStatus();
+
+ config.setClientMode(CLIENT_MODE_BACKGROUND);
+
+ // Notify other clients
+ SPELLexecutorOperation op;
+ op.instanceId = config.getInstanceId();
+ op.parentId = theParentInstanceId;
+ op.groupId = config.getGroupId();
+ op.originId = config.getOriginId();
+ op.clientKey = -1;
+ op.clientMode = config.getClientMode();
+ op.status = initialStatus;
+ op.condition = config.getCondition();
+ op.type = SPELLexecutorOperation::EXEC_OP_OPEN;
+ notifyExecutorOperation( op );
+
+ }
+ catch( SPELLcoreException& err )
+ {
+ err.loggit();
+ return false;
+ }
+ return true;
+}
+
+
//=============================================================================
// METHOD: SPELLcontext::
//=============================================================================
@@ -643,6 +788,8 @@ SPELLipcMessage SPELLcontext::getProcedureList( const SPELLipcMessage& msg )
SPELLprocedureManager::instance().refresh();
}
}
+
+
SPELLprocedureManager::ProcList list = SPELLprocedureManager::instance().getProcList();
std::string listStr = "";
@@ -652,6 +799,15 @@ SPELLipcMessage SPELLcontext::getProcedureList( const SPELLipcMessage& msg )
if (listStr != "") listStr += LIST_SEPARATOR;
listStr += *it;
}
+
+ list = SPELLprocedureManager::instance().getServiceList();
+
+ for( it = list.begin(); it != list.end(); it++)
+ {
+ if (listStr != "") listStr += LIST_SEPARATOR;
+ listStr += *it + "|" + *it;
+ }
+
resp = SPELLipcHelper::createResponse( ContextMessages::RSP_PROC_LIST, msg );
resp.set( MessageField::FIELD_PROC_LIST, listStr );
return resp;
@@ -750,13 +906,18 @@ SPELLipcMessage SPELLcontext::listFiles( const SPELLipcMessage& msg )
if (fileList.size()>0) fileList += LIST_SEPARATOR;
fileList += "+" + *it;
}
+ resp = SPELLipcHelper::createResponse( ContextMessages::RSP_LIST_FILES, msg );
+ resp.set( MessageField::FIELD_FILE_LIST, fileList );
}
else
{
LOG_ERROR("Path does not exist, cannot list files: '" + dir + "'");
+ resp = SPELLipcHelper::createErrorResponse( ContextMessages::RSP_LIST_FILES, msg );
+ resp.set( MessageField::FIELD_FILE_LIST, "" );
+ resp.set( MessageField::FIELD_ERROR, "Cannot list files");
+ resp.set( MessageField::FIELD_REASON, "Path does not exist: '" + dir + "'");
+ resp.set( MessageField::FIELD_FATAL, "false");
}
- resp = SPELLipcHelper::createResponse( ContextMessages::RSP_LIST_FILES, msg );
- resp.set( MessageField::FIELD_FILE_LIST, fileList );
return resp;
}
@@ -860,11 +1021,38 @@ SPELLipcMessage SPELLcontext::getExecutorList( const SPELLipcMessage& msg )
DEBUG(" found " + *it);
listStr += *it;
}
+
+ SPELLserviceManager::ServiceList serviceList = SPELLserviceManager::instance().getServiceList();
+
+ SPELLserviceManager::ServiceList::const_iterator sit;
+ for( sit = serviceList.begin(); sit != serviceList.end(); sit++)
+ {
+ if (listStr != "") listStr += LIST_SEPARATOR;
+ DEBUG(" found " + *sit);
+ listStr += *sit + "#0";
+ }
+
+
resp = SPELLipcHelper::createResponse( ContextMessages::RSP_EXEC_LIST, msg );
resp.set( MessageField::FIELD_EXEC_LIST, listStr );
return resp;
}
+//=============================================================================
+// METHOD: SPELLcontext::
+//=============================================================================
+SPELLipcMessage SPELLcontext::getServiceList( const SPELLipcMessage& msg )
+{
+ DEBUG( NAME + "Requested list of services");
+ SPELLipcMessage resp = VOID_MESSAGE;
+ SPELLserviceManager::ServiceList list = SPELLserviceManager::instance().getServiceList();
+ std::string listStr = "";
+
+ resp = SPELLipcHelper::createResponse( ContextMessages::RSP_SERVICE_LIST, msg );
+ resp.set( MessageField::FIELD_EXEC_LIST, listStr );
+ return resp;
+}
+
//=============================================================================
// METHOD: SPELLcontext::
//=============================================================================
@@ -899,6 +1087,19 @@ SPELLipcMessage SPELLcontext::getExecutorInfo( const SPELLipcMessage& msg )
return resp;
}
+//=============================================================================
+// METHOD: SPELLcontext::
+//=============================================================================
+SPELLipcMessage SPELLcontext::getServiceInfo( const SPELLipcMessage& msg )
+{
+ std::string instanceId = msg.get( MessageField::FIELD_PROC_ID );
+ SPELLipcMessage resp = SPELLipcHelper::createResponse( ContextMessages::RSP_EXEC_INFO, msg);
+ DEBUG( NAME + "Requested service information: " + instanceId);
+ SPELLserviceManager::instance().buildServiceInfo( instanceId, resp );
+
+ return resp;
+}
+
//=============================================================================
// METHOD: SPELLcontext::getExecutorDefaults
@@ -953,7 +1154,11 @@ SPELLipcMessage SPELLcontext::setExecutorDefaults( const SPELLipcMessage& msg )
LOG_INFO(" - TC confirm : " + msg.get(MessageField::FIELD_FORCE_TC_CONFIRM) );
m_executorDefaults.setForceTcConfirm( msg.get(MessageField::FIELD_FORCE_TC_CONFIRM) == ExecutorConstants::TRUE_VALUE );
}
-
+ if( msg.hasField(MessageField::FIELD_FORCE_PROMPT_CONFIRM) )
+ {
+ LOG_INFO(" - Prompt confirm: " + msg.get(MessageField::FIELD_FORCE_PROMPT_CONFIRM) );
+ m_executorDefaults.setForcePromptConfirm( msg.get(MessageField::FIELD_FORCE_PROMPT_CONFIRM) == ExecutorConstants::TRUE_VALUE );
+ }
if( msg.hasField(MessageField::FIELD_SAVE_STATE_MODE) )
{
LOG_INFO(" - Save state : " + msg.get(MessageField::FIELD_SAVE_STATE_MODE) );
@@ -966,6 +1171,18 @@ SPELLipcMessage SPELLcontext::setExecutorDefaults( const SPELLipcMessage& msg )
m_executorDefaults.setWatchVariables( msg.get(MessageField::FIELD_WATCH_VARIABLES) == ExecutorConstants::TRUE_VALUE );
}
+ if( msg.hasField(MessageField::FIELD_RESOURCES_DISPLAY) )
+ {
+ LOG_INFO(" - Resource disp: " + msg.get(MessageField::FIELD_RESOURCES_DISPLAY) );
+ m_executorDefaults.setResourcesDisplay( msg.get(MessageField::FIELD_RESOURCES_DISPLAY) == ExecutorConstants::TRUE_VALUE );
+ }
+
+ if( msg.hasField(MessageField::FIELD_LOCAL_RESOURCE_SUPPORTED) )
+ {
+ LOG_INFO(" - Local resource support: " + msg.get(MessageField::FIELD_LOCAL_RESOURCE_SUPPORTED) );
+ m_executorDefaults.setLocalResourcesSupported( msg.get(MessageField::FIELD_LOCAL_RESOURCE_SUPPORTED) == ExecutorConstants::TRUE_VALUE );
+ }
+
if( msg.hasField(MessageField::FIELD_MAX_VERBOSITY) )
{
LOG_INFO(" - Verbosity : " + msg.get(MessageField::FIELD_MAX_VERBOSITY) );
@@ -993,8 +1210,11 @@ void SPELLcontext::fillExecutorDefaults( SPELLipcMessage& msg )
msg.set( MessageField::FIELD_PROMPT_DELAY, ISTR(m_executorDefaults.getPromptWarningDelay()) );
msg.set( MessageField::FIELD_BY_STEP, (m_executorDefaults.isByStep() ? ExecutorConstants::TRUE_VALUE : ExecutorConstants::FALSE_VALUE) );
msg.set( MessageField::FIELD_FORCE_TC_CONFIRM, (m_executorDefaults.isForceTcConfirm() ? ExecutorConstants::TRUE_VALUE : ExecutorConstants::FALSE_VALUE) );
+ msg.set( MessageField::FIELD_FORCE_PROMPT_CONFIRM, (m_executorDefaults.isForcePromptConfirm() ? ExecutorConstants::TRUE_VALUE : ExecutorConstants::FALSE_VALUE) );
msg.set( MessageField::FIELD_SAVE_STATE_MODE, m_executorDefaults.getSaveStateMode() );
msg.set( MessageField::FIELD_WATCH_VARIABLES, (m_executorDefaults.isWatchVariables() ? ExecutorConstants::TRUE_VALUE : ExecutorConstants::FALSE_VALUE) );
+ msg.set( MessageField::FIELD_RESOURCES_DISPLAY, (m_executorDefaults.isResourcesDisplay() ? ExecutorConstants::TRUE_VALUE : ExecutorConstants::FALSE_VALUE) );
+ msg.set( MessageField::FIELD_LOCAL_RESOURCE_SUPPORTED, (m_executorDefaults.isLocalResourcesSupported() ? ExecutorConstants::TRUE_VALUE : ExecutorConstants::FALSE_VALUE) );
msg.set( MessageField::FIELD_MAX_VERBOSITY, ISTR(m_executorDefaults.getMaxVerbosity()) );
msg.set( MessageField::FIELD_BROWSABLE_LIB, m_executorDefaults.getBrowsableLibStr() );
@@ -1083,11 +1303,58 @@ SPELLipcMessage SPELLcontext::attachExecutor( const SPELLipcMessage& msg, SPELLc
}
catch( SPELLcoreException& ex )
{
- LOG_ERROR("Cannot attach: " + std::string(ex.what()) );
- resp = SPELLipcHelper::createErrorResponse( ContextMessages::RSP_ATTACH_EXEC, msg );
- resp.set( MessageField::FIELD_ERROR, "Cannot attach to executor");
- resp.set( MessageField::FIELD_REASON, ex.what());
- resp.set( MessageField::FIELD_FATAL, PythonConstants::True );
+
+ try
+ {
+ SPELLservice* exec = SPELLserviceManager::instance().getService(instanceId);
+ std::string groupId = exec->getModel().getGroupId();
+ std::string originId = exec->getModel().getOriginId();
+
+ if (mode == CLIENT_MODE_CONTROL)
+ {
+ LOG_ERROR("Cannot take control of Service! Not supported for service: " + instanceId );
+ resp = SPELLipcHelper::createErrorResponse( ContextMessages::RSP_ATTACH_EXEC, msg );
+ resp.set( MessageField::FIELD_ERROR, "Cannot attach to service in controlling mode");
+ resp.set( MessageField::FIELD_REASON, "Not supported for service" );
+ resp.set( MessageField::FIELD_FATAL, PythonConstants::True );
+ }
+ else
+ {
+ // Set the procedure controlling client on the client model
+ client->addProcedure(instanceId, CLIENT_MODE_MONITOR);
+
+ LOG_INFO("Client " + ISTR(client->getClientKey()) + " monitoring service " + instanceId);
+
+ resp = SPELLipcHelper::createResponse( ContextMessages::RSP_ATTACH_EXEC, msg );
+ // Add the executor information
+ SPELLexecutorManager::instance().buildExecutorInfo( instanceId, resp );
+ // Add the GUI list
+ SPELLclientManager::instance().completeMonitoringInfo( instanceId, resp );
+ // Monitor the executor
+ SPELLclientManager::instance().startMonitorExecutor(client, exec );
+ // Notify other clients
+ SPELLexecutorOperation op;
+ op.instanceId = instanceId;
+ op.parentId = exec->getParentInstanceId();
+ op.groupId = groupId;
+ op.originId = originId;
+ op.clientKey = msg.getKey();
+ op.clientMode = CLIENT_MODE_MONITOR;
+ op.status = exec->getStatus();
+ op.type = SPELLexecutorOperation::EXEC_OP_ATTACH;
+ notifyExecutorOperation( op );
+ }
+ }
+ catch( SPELLcoreException& ex )
+ {
+
+
+ LOG_ERROR("Cannot attach: " + std::string(ex.what()) );
+ resp = SPELLipcHelper::createErrorResponse( ContextMessages::RSP_ATTACH_EXEC, msg );
+ resp.set( MessageField::FIELD_ERROR, "Cannot attach to executor");
+ resp.set( MessageField::FIELD_REASON, ex.what());
+ resp.set( MessageField::FIELD_FATAL, PythonConstants::True );
+ }
}
return resp;
}
@@ -1183,6 +1450,45 @@ void SPELLcontext::executorLost( const std::string& instanceId )
catch(SPELLcoreException& ex){};
}
+//=============================================================================
+// METHOD: SPELLcontext::
+//=============================================================================
+void SPELLcontext::serviceLost( const std::string& instanceId )
+{
+ try
+ {
+ LOG_ERROR("Service lost: " + instanceId);
+ SPELLservice* exec = SPELLserviceManager::instance().getService( instanceId );
+ std::string groupId = exec->getModel().getGroupId();
+ std::string originId = exec->getModel().getOriginId();
+ std::string parentId = exec->getModel().getParentInstanceId();
+ std::string name = exec->getModel().getProcId();
+ LOG_ERROR(" - Group ID : " + groupId);
+ LOG_ERROR(" - Origin ID: " + originId);
+ LOG_ERROR(" - Parent ID: " + parentId);
+
+ LOG_ERROR("Notify clients about executor lost");
+
+ // Notify all GUIs in the system
+ SPELLexecutorOperation op;
+ op.instanceId = instanceId;
+ op.status = STATUS_ERROR;
+ op.groupId = groupId;
+ op.originId = originId;
+ op.parentId = parentId;
+ op.type = SPELLexecutorOperation::EXEC_OP_CRASH;
+ notifyExecutorOperation( op );
+
+ // Mark the model to be removed (cannot delete now, since this operation is
+ // triggered from the process model itself
+ SPELLserviceManager::instance().closeService( instanceId );
+
+// openService(instanceId);
+
+ }
+ catch(SPELLcoreException& ex){};
+}
+
//=============================================================================
// METHOD: SPELLcontext::
//=============================================================================
@@ -1228,12 +1534,39 @@ SPELLipcMessage SPELLcontext::detachExecutor( const SPELLipcMessage& msg, SPELLc
}
catch( SPELLcoreException& ex )
{
- LOG_ERROR("Cannot detach: " + std::string(ex.what()) );
- resp = SPELLipcHelper::createErrorResponse( ContextMessages::RSP_DETACH_EXEC, msg );
- resp.set( MessageField::FIELD_ERROR, "Cannot detach from executor");
- resp.set( MessageField::FIELD_REASON, ex.what() );
- resp.set( MessageField::FIELD_FATAL, PythonConstants::True );
- }
+ try
+ {
+ SPELLservice* exec = SPELLserviceManager::instance().getService(instanceId);
+ std::string groupId = exec->getModel().getGroupId();
+ std::string originId = exec->getModel().getOriginId();
+
+ LOG_INFO("Client " + ISTR(client->getClientKey()) + " detached from service " + instanceId);
+
+ // To notify to other clients
+ SPELLexecutorOperation op;
+ op.instanceId = instanceId;
+ op.clientKey = msg.getKey();
+ op.groupId = groupId;
+ op.originId = originId;
+ op.status = exec->getStatus();
+ op.type = SPELLexecutorOperation::EXEC_OP_DETACH;
+
+ resp = SPELLipcHelper::createResponse(ContextMessages::RSP_DETACH_EXEC, msg);
+
+ SPELLclientManager::instance().stopMonitorExecutor(client, exec);
+ op.clientMode = CLIENT_MODE_MONITOR;
+
+
+ notifyExecutorOperation(op);
+ } catch (SPELLcoreException& ex)
+ {
+ LOG_ERROR("Cannot detach: " + std::string(ex.what()));
+ resp = SPELLipcHelper::createErrorResponse(ContextMessages::RSP_DETACH_EXEC, msg);
+ resp.set(MessageField::FIELD_ERROR, "Cannot detach from executor");
+ resp.set(MessageField::FIELD_REASON, ex.what());
+ resp.set(MessageField::FIELD_FATAL, PythonConstants::True);
+ }
+ }
return resp;
}
diff --git a/lib/SPELL_CTX/src/SPELLdataHelper.C b/lib/SPELL_CTX/src/SPELLdataHelper.C
index 33b7a5b..706aca8 100644
--- a/lib/SPELL_CTX/src/SPELLdataHelper.C
+++ b/lib/SPELL_CTX/src/SPELLdataHelper.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Data handling utilities
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_CTX/src/SPELLdataTable.C b/lib/SPELL_CTX/src/SPELLdataTable.C
index c8d54a0..e09e8b8 100644
--- a/lib/SPELL_CTX/src/SPELLdataTable.C
+++ b/lib/SPELL_CTX/src/SPELLdataTable.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the shared data tables
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_CTX/src/SPELLexecutor.C b/lib/SPELL_CTX/src/SPELLexecutor.C
index b2c7986..7a54a20 100644
--- a/lib/SPELL_CTX/src/SPELLexecutor.C
+++ b/lib/SPELL_CTX/src/SPELLexecutor.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the executor manager
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -42,53 +42,42 @@
#include "SPELL_UTIL/SPELLtime.H"
#include "SPELL_IPC/SPELLipc_Executor.H"
#include "SPELL_IPC/SPELLipc_Context.H"
+#include "SPELL_PRD/SPELLprocedureManager.H"
// System includes ---------------------------------------------------------
-class LoginMonitor : public SPELLthread
-{
-public:
- LoginMonitor( SPELLexecutor& exec )
- : SPELLthread("login-" + exec.getModel().getInstanceId() ),
- m_exec( exec )
- {}
- void run()
- {
- SPELLtime checkStart;
- for(;;)
- {
- SPELLtime now;
- SPELLtime delta = now - checkStart;
- if (delta.getSeconds()>120)
- {
- SPELLexecutorManager::instance().callback_executorNotReconnected( m_exec.getModel().getInstanceId() );
- return;
- }
- else
- {
- if (m_exec.isLoggedIn())
- {
- SPELLexecutorManager::instance().callback_executorReconnected( m_exec.getModel().getInstanceId() );
- return;
- }
- else
- {
- usleep(30000);
- }
- }
- }
- }
-
-private:
- SPELLexecutor& m_exec;
-};
// DEFINES /////////////////////////////////////////////////////////////////
#define DEFAULT_START_TIMEOUT 20
#define DEFAULT_LOGIN_TIMEOUT 60
-
+void LoginMonitor::run()
+{
+ SPELLtime checkStart;
+ for (;;)
+ {
+ SPELLtime now;
+ SPELLtime delta = now - checkStart;
+ if (delta.getSeconds() > 120)
+ {
+ SPELLexecutorManager::instance().callback_executorNotReconnected(m_exec.getModel().getInstanceId());
+ return;
+ }
+ else
+ {
+ if (m_exec.isLoggedIn())
+ {
+ SPELLexecutorManager::instance().callback_executorReconnected(m_exec.getModel().getInstanceId());
+ return;
+ }
+ else
+ {
+ usleep(30000);
+ }
+ }
+ }
+}
//=============================================================================
// CONSTRUCTOR: SPELLexecutor::SPELLexecutor()
//=============================================================================
@@ -112,6 +101,10 @@ SPELLexecutor::SPELLexecutor( const SPELLexecutorStartupParams& config, SPELLcli
m_reconnecting = config.isReconnecting();
m_loggedIn = false;
m_loginMonitor = NULL;
+ m_notAckNotifications = 0;
+ m_status = STATUS_UNINIT;
+ m_processStatus = PSTATUS_INITIAL;
+
}
//=============================================================================
@@ -150,6 +143,15 @@ void SPELLexecutor::start()
THROW_EXCEPTION("Cannot launch executor", "No executor command defined in configuration", SPELL_ERROR_CONFIG);
}
+ std::string pyVersion = SPELLprocedureManager::instance().getProperty(m_model.getProcId(),"PYTHON VERSION");
+ if (pyVersion.empty())
+ pyVersion = "2";
+ LOG_INFO("Requested executor for python version " + pyVersion);
+ if (pyVersion.find("3") == 0)
+ {
+ command += "_v3";
+ }
+
int startTimeout = -1;
int loginTimeout = -1;
std::string startTimeoutStr = SPELLconfiguration::instance().getContextParameter( SPELLcontextConfig::ExecutorStartTimeout );
@@ -177,7 +179,8 @@ void SPELLexecutor::start()
{
command += " -r " + m_model.getWsFilename();
}
-
+ if (SPELLprocessManager::instance().checkProcessExist(m_model.getInstanceId() ))
+ SPELLprocessManager::instance().killProcess( m_model.getInstanceId() );
SPELLprocessManager::instance().clearProcess( m_model.getInstanceId() );
SPELLprocessManager::instance().startProcess( m_model.getInstanceId(), command );
@@ -355,7 +358,12 @@ SPELLipcMessage SPELLexecutor::sendRequestToExecutor( const SPELLipcMessage& msg
SPELLipcMessage response = VOID_MESSAGE;
if (processOk())
{
- response = m_ipc.sendRequest( m_model.getInstanceId(), msg, 5000 );
+ int timeout = 3000;
+ if (msg.getId() == ExecutorMessages::REQ_WVARIABLES_ENABLED)
+ {
+ timeout = 500;
+ }
+ response = m_ipc.sendRequest( m_model.getInstanceId(), msg, timeout );
}
else
{
@@ -496,7 +504,7 @@ SPELLipcMessage SPELLexecutor::processRequestFromExecutor( SPELLipcMessage msg )
//=============================================================================
// METHOD: SPELLexecutor::
//=============================================================================
-void SPELLexecutor::processStarted( const std::string& identifier )
+void SPELLexecutor::processStarted( const std::string identifier )
{
DEBUG("Callback - Executor process started: " + identifier);
m_processStatus = PSTATUS_RUNNING;
@@ -506,7 +514,7 @@ void SPELLexecutor::processStarted( const std::string& identifier )
//=============================================================================
// METHOD: SPELLexecutor::
//=============================================================================
-void SPELLexecutor::processFinished( const std::string& identifier, const int& retValue )
+void SPELLexecutor::processFinished( const std::string identifier, const int& retValue )
{
LOG_INFO("Executor process finished: " + identifier);
m_processStatus = PSTATUS_FINISHED;
@@ -517,7 +525,7 @@ void SPELLexecutor::processFinished( const std::string& identifier, const int& r
//=============================================================================
// METHOD: SPELLexecutor::
//=============================================================================
-void SPELLexecutor::processKilled( const std::string& identifier )
+void SPELLexecutor::processKilled( const std::string identifier )
{
LOG_ERROR("Executor process killed: " + identifier);
m_model.setStatus(STATUS_ERROR);
@@ -547,7 +555,7 @@ void SPELLexecutor::processKilled( const std::string& identifier )
//=============================================================================
// METHOD: SPELLexecutor::
//=============================================================================
-void SPELLexecutor::processFailed( const std::string& identifier )
+void SPELLexecutor::processFailed( const std::string identifier )
{
LOG_ERROR("Executor process failed startup: " + identifier);
m_model.setStatus(STATUS_ABORTED);
@@ -654,6 +662,11 @@ bool SPELLexecutor::isActive()
DEBUG("Executor " + m_model.getInstanceId() + " active: " + SPELLdataHelper::executorStatusToString(getStatus()));
return true;
}
+ if (m_reconnecting)
+ {
+ DEBUG("Executor " + m_model.getInstanceId() + " is reconnecting: " + SPELLdataHelper::executorStatusToString(getStatus()));
+ return true;
+ }
return false;
}
@@ -723,6 +736,9 @@ void SPELLexecutor::removeControllingClient( bool clientLost )
removeClient.set( MessageField::FIELD_PROC_ID, m_model.getInstanceId() );
removeClient.set( MessageField::FIELD_GUI_CONTROL, ISTR(cKey));
removeClient.set( MessageField::FIELD_GUI_CONTROL_HOST, cHost);
+ if (clientLost) {
+ removeClient.set( MessageField::FIELD_TEXT, "Procedure GUI disconnected from SPELL Context: " + m_model.getInstanceId());
+ }
sendMessageToExecutor(removeClient);
LOG_INFO("Controlling client removed");
@@ -752,6 +768,8 @@ void SPELLexecutor::forcePause()
}
else if (getStatus() == STATUS_RUNNING)
{
+ if (m_executorStatusEvent.isClear())
+ return;
cmd.id = CMD_PAUSE;
LOG_WARN("Pausing procedure (force stop)");
command(cmd);
@@ -974,12 +992,16 @@ SPELLipcMessage SPELLexecutor::executorLogin( const SPELLipcMessage& msg )
DEBUG("Received executor login: " + m_model.getInstanceId() );
m_loggedIn = true;
+ m_model.setStatus(STATUS_UNINIT);
// Store the information given by the executor
+ LOG_INFO("Executor login provided: " + m_model.getInstanceId());
m_model.setIpcKey(msg.getKey());
- m_model.setStatus(SPELLdataHelper::stringToExecutorStatus( msg.get( MessageField::FIELD_EXEC_STATUS )));
+ LOG_INFO(" IPC key: " + msg.getKey());
m_model.setAsRunFilename( msg.get( MessageField::FIELD_ASRUN_NAME ));
+ LOG_INFO(" ASRUN : " + msg.get( MessageField::FIELD_ASRUN_NAME ));
m_model.setLogFilename( msg.get( MessageField::FIELD_LOG_NAME ));
+ LOG_INFO(" LOG : " + msg.get( MessageField::FIELD_LOG_NAME ));
//TODO
//m_model.wsFileName = msg.get( MessageField::FIELD_WS_NAME );
@@ -1110,7 +1132,7 @@ void SPELLexecutor::executorNotification( const SPELLipcMessage& nmsg )
// Force an additional status notification upon line notifications where
// the stage title changes
- if (getModel().getStageId() != id)
+ if (getModel().getStageId() != id || getModel().getStageTitle() != tl)
{
getModel().setStage(id,tl);
SPELLexecutorOperation op;
diff --git a/lib/SPELL_CTX/src/SPELLexecutorIPC.C b/lib/SPELL_CTX/src/SPELLexecutorIPC.C
index 5543ca3..07d289c 100644
--- a/lib/SPELL_CTX/src/SPELLexecutorIPC.C
+++ b/lib/SPELL_CTX/src/SPELLexecutorIPC.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the executor IPC interface
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -59,10 +59,10 @@ SPELLexecutorIPC::SPELLexecutorIPC( SPELLexecutor& controller, const SPELLexecut
//=============================================================================
SPELLexecutorIPC::~SPELLexecutorIPC()
{
- DEBUG("[EXCIPC] Destroying");
+ //DEBUG("[EXCIPC] Destroying");
m_ipc.removeListener();
m_ipc.join();
- DEBUG("[EXCIPC] Destroyed");
+ //DEBUG("[EXCIPC] Destroyed");
}
//=============================================================================
@@ -70,7 +70,7 @@ SPELLexecutorIPC::~SPELLexecutorIPC()
//=============================================================================
void SPELLexecutorIPC::setup()
{
- DEBUG("[EXCIPC] Setup");
+ //DEBUG("[EXCIPC] Setup");
m_ipc.initialize(&*this);
m_ipc.connect();
m_ipc.start();
@@ -83,13 +83,13 @@ void SPELLexecutorIPC::setup()
void SPELLexecutorIPC::cleanup()
{
SPELLmonitor m(m_notifyLock);
- DEBUG("[EXCIPC] Cleanup");
+ //DEBUG("[EXCIPC] Cleanup");
m_connected = false;
- DEBUG("[EXCIPC] Close executor connection");
+ //DEBUG("[EXCIPC] Close executor connection");
m_ipc.removeListener();
- DEBUG("[EXCIPC] Perform disconnection");
+ //DEBUG("[EXCIPC] Perform disconnection");
m_ipc.disconnect();
- DEBUG("[EXCIPC] Close executor connection done");
+ //DEBUG("[EXCIPC] Close executor connection done");
}
//=============================================================================
@@ -138,21 +138,21 @@ SPELLipcMessage SPELLexecutorIPC::sendRequest( const std::string& executorId, co
void SPELLexecutorIPC::processMessage( const SPELLipcMessage& msg )
{
TICK_IN;
- DEBUG("[EXCIPC] Received message from executor: " + msg.dataStr());
+ //DEBUG("[EXCIPC] Received message from executor: " + msg.dataStr());
// Certain messages are for monitoring clients only
if ((msg.getId() != MessageId::MSG_ID_PROMPT_START)&&(msg.getId() != MessageId::MSG_ID_PROMPT_END))
{
- DEBUG("[EXCIPC] Forward message to controller");
+ //DEBUG("[EXCIPC] Forward message to controller");
m_controller.processMessageFromExecutor(msg);
}
if (msg.getId() != ExecutorMessages::MSG_NOTIF_EXEC_CLOSE)
{
- DEBUG("[EXCIPC] Forward message to monitoring clients");
+ //DEBUG("[EXCIPC] Forward message to monitoring clients");
notifyMessage(msg);
}
- DEBUG("[EXCIPC] Message processed");
+ //DEBUG("[EXCIPC] Message processed");
TICK_OUT;
}
@@ -163,21 +163,21 @@ SPELLipcMessage SPELLexecutorIPC::processRequest( const SPELLipcMessage& msg )
{
TICK_IN;
- DEBUG("[EXCIPC] Received request from executor: " + msg.dataStr());
+ //DEBUG("[EXCIPC] Received request from executor: " + msg.dataStr());
SPELLipcMessage resp = VOID_MESSAGE;
- DEBUG("[EXCIPC] Forward request to controller");
+ //DEBUG("[EXCIPC] Forward request to controller");
resp = m_controller.processRequestFromExecutor(msg);
// Certain requests are to be sent to controlling clients only
if ( shouldForwardToMonitoring(msg) )
{
- DEBUG("[EXCIPC] Forward to monitoring clients");
+ //DEBUG("[EXCIPC] Forward to monitoring clients");
// Notify request
notifyRequest(msg);
}
- DEBUG("[EXCIPC] Request processed");
+ //DEBUG("[EXCIPC] Request processed");
TICK_OUT;
return resp;
}
@@ -205,6 +205,10 @@ bool SPELLexecutorIPC::shouldForwardToMonitoring( const SPELLipcMessage& msg )
{
return false;
}
+ else if ( requestId == ContextMessages::REQ_SERVICE_INFO )
+ {
+ return false;
+ }
else if ( requestId == ContextMessages::REQ_DEL_SHARED_DATA )
{
return false;
@@ -257,9 +261,9 @@ void SPELLexecutorIPC::notifyMessage( const SPELLipcMessage& msg )
{
if (m_connected)
{
+ SPELLmonitor m(m_notifyLock);
for( NotifierMap::iterator it = m_notifiers.begin(); it != m_notifiers.end(); it++)
{
- SPELLmonitor m(m_notifyLock);
if (it->second!=NULL) it->second->processMessageFromExecutor(msg);
}
}
@@ -272,9 +276,9 @@ void SPELLexecutorIPC::notifyRequest( const SPELLipcMessage& msg )
{
if (m_connected)
{
+ SPELLmonitor m(m_notifyLock);
for( NotifierMap::iterator it = m_notifiers.begin(); it != m_notifiers.end(); it++)
{
- SPELLmonitor m(m_notifyLock);
if (it->second!=NULL) it->second->processRequestFromExecutor(msg);
}
}
@@ -288,7 +292,7 @@ void SPELLexecutorIPC::registerExecutorNotifier( std::string id, SPELLexecutorLi
SPELLmonitor m(m_notifyLock);
LOG_INFO("[EXCIPC] #### Register notifier listener: " + id);
NotifierMap::iterator it = m_notifiers.find(id);
- if (it == m_notifiers.end())
+ if (it == m_notifiers.end() || it->second != notifier)
{
m_notifiers[id] = notifier;
}
@@ -304,6 +308,8 @@ void SPELLexecutorIPC::deregisterExecutorNotifier( std::string id )
NotifierMap::iterator it = m_notifiers.find(id);
if (it != m_notifiers.end())
{
- m_notifiers.erase(it);
+ // Don't invalidate iterators by just setting the entry to NULL
+ //m_notifiers.erase(it);
+ m_notifiers[id] = NULL;
}
}
diff --git a/lib/SPELL_CTX/src/SPELLexecutorManager.C b/lib/SPELL_CTX/src/SPELLexecutorManager.C
index a8a194b..5e10bf3 100644
--- a/lib/SPELL_CTX/src/SPELLexecutorManager.C
+++ b/lib/SPELL_CTX/src/SPELLexecutorManager.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the executor manager
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -40,6 +40,7 @@
#include "SPELL_IPC/SPELLipc_Context.H"
#include "SPELL_IPC/SPELLipc_Executor.H"
#include "SPELL_WRP/SPELLconstants.H"
+#include "SPELL_CTX/SPELLserviceManager.H"
// System includes ---------------------------------------------------------
@@ -79,7 +80,7 @@ SPELLexecutorManager& SPELLexecutorManager::instance()
void SPELLexecutorManager::setup( const std::string& ctxName )
{
m_contextName = ctxName;
- m_persisTable = new SPELLpersistencyTable(ctxName);
+ m_persisTable = new SPELLpersistencyTable(ctxName + "_executors");
if (m_persisTable->load())
{
reconnectExecutors();
@@ -199,6 +200,8 @@ void SPELLexecutorManager::callback_executorReconnected( const std::string& inst
SPELLexecutor* exec = it->second;
addInstanceNumber( exec->getModel().getProcId(), exec->getModel().getInstanceNum() );
addExecutorModel( exec );
+ SPELLprocessManager::instance().attachProcess( exec->getModel().getInstanceId(), exec->getModel().getPID() );
+
m_pendingLogin.erase(it);
SPELLexecutorOperation op;
@@ -318,7 +321,13 @@ void SPELLexecutorManager::deleteExecutorFiles( const SPELLexecutorStartupParams
//=============================================================================
void SPELLexecutorManager::addExecutorModel( SPELLexecutor* exec )
{
- m_executors.insert( std::make_pair( exec->getModel().getInstanceId(), exec ));
+ const std::string id = exec->getModel().getInstanceId();
+ if (m_executors.count(id) > 0)
+ {
+ delete m_executors[id];
+ m_executors.erase(id);
+ }
+ m_executors.insert( std::make_pair(id, exec ));
DEBUG("[EMGR] Added executor: '" + exec->getModel().getInstanceId() + "'");
m_persisTable->registerExecutor(exec->getModel().getInstanceId(),
exec->getModel().getTimeId(),
@@ -337,13 +346,17 @@ void SPELLexecutorManager::removeExecutorModel( const std::string& instanceId )
{
DEBUG("[EMGR] Removing executor model: '" + instanceId + "'");
m_persisTable->deregisterExecutor(it->second->getModel().getInstanceId());
+ m_lock.unlock();
delete it->second;
+ m_lock.lock();
+
m_executors.erase(it);
DEBUG("[EMGR] Removed executor: '" + instanceId + "'");
}
else
{
- LOG_ERROR("[EMGR]: No executor to remove: '" + instanceId + "'");
+ SPELLserviceManager::instance().removeServiceModel(instanceId);
+ //LOG_ERROR("[EMGR]: No executor to remove: '" + instanceId + "'");
}
}
@@ -353,6 +366,15 @@ void SPELLexecutorManager::removeExecutorModel( const std::string& instanceId )
std::string SPELLexecutorManager::getInstanceId( const std::string& procId )
{
SPELLmonitor m(m_lock);
+
+ // We never remove instance numbers but we can live with it - memory consumption
+ // is not big and do not need to be concerned with race conditions between add and get
+ // due to simultaneous requests from *different* clients (e.g .GUI and Parent Exec).
+
+ // Nevertheless attempt to clean now, protected by the lock, before getting an instance id.
+ // Just clean if no executors running.
+ if (m_executors.size()==0) m_instances.clear();
+
std::string instanceId = "";
InstanceMap::iterator it = m_instances.find(procId);
if ( it == m_instances.end() )
@@ -363,9 +385,10 @@ std::string SPELLexecutorManager::getInstanceId( const std::string& procId )
{
int instanceNum = 0;
while(hasInstanceNumber(procId, instanceNum)) instanceNum++;
+ addInstanceNumber(procId, instanceNum);
instanceId = procId + "#" + ISTR(instanceNum);
}
- DEBUG("[EMGR] Found instance id: '" + instanceId + "'");
+ LOG_INFO("Assigned instance id: '" + instanceId + "'");
return instanceId;
}
@@ -401,43 +424,18 @@ bool SPELLexecutorManager::hasInstanceNumber( const std::string& procId, int ins
return false;
}
-//=============================================================================
-// METHOD: SPELLexecutorManager::removeInstanceNumber()
-//=============================================================================
-void SPELLexecutorManager::removeInstanceNumber( const std::string& procId, int instanceNum )
-{
- InstanceMap::iterator it = m_instances.find(procId);
- if (it != m_instances.end())
- {
- InstanceList::iterator toRemove = it->second.end();
- InstanceList::iterator lit;
- for( lit = it->second.begin(); lit != it->second.end(); lit++ )
- {
- if (*lit == instanceNum)
- {
- toRemove = lit;
- break;
- }
- }
- if (toRemove != it->second.end())
- {
- it->second.erase(toRemove);
- }
- }
-}
-
//=============================================================================
// METHOD: SPELLexecutorManager::closeExecutor()
//=============================================================================
void SPELLexecutorManager::closeExecutor( const std::string& instanceId )
{
SPELLmonitor m(m_lock);
+
try
{
// Will raise exception if not found
SPELLexecutor* exec = getExecutor(instanceId);
exec->close();
- removeInstanceNumber( exec->getModel().getProcId(), exec->getModel().getInstanceNum() );
removeExecutorModel( exec->getModel().getInstanceId() );
LOG_INFO("Executor successfully closed: " + instanceId);
}
@@ -466,7 +464,6 @@ void SPELLexecutorManager::killExecutor( const std::string& instanceId )
// Will raise exception if not found
SPELLexecutor* exec = getExecutor(instanceId);
exec->kill();
- removeInstanceNumber( exec->getModel().getProcId(), exec->getModel().getInstanceNum() );
removeExecutorModel( exec->getModel().getInstanceId() );
}
catch(SPELLcoreException& ex)
@@ -499,7 +496,6 @@ void SPELLexecutorManager::clearModels()
try
{
SPELLexecutor* exec = getExecutor(*it);
- removeInstanceNumber( exec->getModel().getProcId(), exec->getModel().getInstanceNum() );
removeExecutorModel( exec->getModel().getInstanceId() );
}
catch(SPELLcoreException& ex)
@@ -509,6 +505,9 @@ void SPELLexecutorManager::clearModels()
}
}
m_toClear.clear();
+ if (m_executors.empty()){
+ m_instances.clear();
+ }
}
}
@@ -520,6 +519,8 @@ SPELLexecutor* SPELLexecutorManager::getExecutor( const std::string& instanceId
//DEBUG("[EMGR] Search for executor: '" + instanceId + "'");
ExecutorMap::iterator it = m_executors.find(instanceId);
if (it != m_executors.end()) return it->second;
+ const std::string id = noInstanceId(instanceId);
+ return SPELLserviceManager::instance().getService(id);
THROW_EXCEPTION("Cannot get executor", "No such id: " + instanceId, SPELL_ERROR_EXECUTION );
return NULL;
}
@@ -591,10 +592,11 @@ void SPELLexecutorManager::buildExecutorInfo( const std::string& procId, SPELLip
{
LOG_INFO("Building executor information for " + procId );
- std::string procName = SPELLprocedureManager::instance().getProcName(procId);
try
{
+ std::string procName = SPELLprocedureManager::instance().getProcName(procId);
+
// Will raise exception if not found
SPELLexecutor* exec = getExecutor(procId);
@@ -675,23 +677,6 @@ void SPELLexecutorManager::buildExecutorInfo( const std::string& procId, SPELLip
}
catch(SPELLcoreException& ex)
{
- LOG_ERROR("No executor found to complete information");
- msg.set( MessageField::FIELD_PROC_ID, procId );
- msg.set( MessageField::FIELD_GROUP_ID, procId );
- msg.set( MessageField::FIELD_ORIGIN_ID, "???" );
- msg.set( MessageField::FIELD_PARENT_PROC, " " );
- msg.set( MessageField::FIELD_PARENT_PROC_LINE, " " );
- msg.set( MessageField::FIELD_PROC_NAME, procName );
- msg.set( MessageField::FIELD_ASRUN_NAME, " " );
- msg.set( MessageField::FIELD_EXEC_STATUS, SPELLdataHelper::executorStatusToString(STATUS_UNINIT) );
- msg.set( MessageField::FIELD_CONDITION, " " );
- msg.set( MessageField::FIELD_GUI_LIST, " " );
- msg.set( MessageField::FIELD_GUI_CONTROL, " " );
- msg.set( MessageField::FIELD_GUI_CONTROL_HOST, " " );
- msg.set( MessageField::FIELD_OPEN_MODE, " " );
- msg.set( MessageField::FIELD_STAGE_ID, " " );
- msg.set( MessageField::FIELD_STAGE_TL, " " );
- msg.set( MessageField::FIELD_CSP, " " );
- msg.set( MessageField::FIELD_CODE_NAME, " " );
+ SPELLserviceManager::instance().buildServiceInfo( procId, msg );
}
}
diff --git a/lib/SPELL_CTX/src/SPELLexecutorModel.C b/lib/SPELL_CTX/src/SPELLexecutorModel.C
index d0ec261..853a115 100644
--- a/lib/SPELL_CTX/src/SPELLexecutorModel.C
+++ b/lib/SPELL_CTX/src/SPELLexecutorModel.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the executor model
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_CTX/src/SPELLexecutorOperation.C b/lib/SPELL_CTX/src/SPELLexecutorOperation.C
index 8e9698e..9fab2aa 100644
--- a/lib/SPELL_CTX/src/SPELLexecutorOperation.C
+++ b/lib/SPELL_CTX/src/SPELLexecutorOperation.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Executor operation notifications
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_CTX/src/SPELLlistenerIPC.C b/lib/SPELL_CTX/src/SPELLlistenerIPC.C
index 4dbc25b..ffb967c 100644
--- a/lib/SPELL_CTX/src/SPELLlistenerIPC.C
+++ b/lib/SPELL_CTX/src/SPELLlistenerIPC.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the listener IPC interface
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -48,6 +48,7 @@
//=============================================================================
SPELLlistenerIPC::SPELLlistenerIPC()
{
+ m_ipc = NULL;
}
//=============================================================================
diff --git a/lib/SPELL_CTX/src/SPELLpersistencyTable.C b/lib/SPELL_CTX/src/SPELLpersistencyTable.C
index 63abf94..5e9c7fe 100644
--- a/lib/SPELL_CTX/src/SPELLpersistencyTable.C
+++ b/lib/SPELL_CTX/src/SPELLpersistencyTable.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the executor persistency table
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -92,7 +92,7 @@ bool SPELLpersistencyTable::load()
pers.timeId = tokens[1];
pers.parentId = parentId;
pers.pid = STRI(tokens[4]);
- m_data.insert( std::make_pair(tokens[0], pers) );
+ m_data[tokens[0]] = pers;
}
else
{
@@ -145,7 +145,7 @@ void SPELLpersistencyTable::registerExecutor( const std::string& instanceId, con
pers.timeId = timeId;
pers.parentId = parentId;
pers.pid = pid;
- m_data.insert( std::make_pair(instanceId, pers) );
+ m_data[instanceId] = pers;
dumpToFile();
}
}
diff --git a/lib/SPELL_CTX/src/SPELLservice.C b/lib/SPELL_CTX/src/SPELLservice.C
new file mode 100644
index 0000000..10f0edb
--- /dev/null
+++ b/lib/SPELL_CTX/src/SPELLservice.C
@@ -0,0 +1,207 @@
+// ################################################################################
+// FILE : SPELLexecutor.C
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Implementation of the executor manager
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// Local includes ----------------------------------------------------------
+#include "SPELL_CTX/SPELLservice.H"
+#include "SPELL_CTX/SPELLserviceManager.H"
+#include "SPELL_CTX/SPELLdataHelper.H"
+#include "SPELL_CTX/SPELLcontext.H"
+#include "SPELL_PRD/SPELLprocedureManager.H"
+// Project includes --------------------------------------------------------
+#include "SPELL_WRP/SPELLconstants.H"
+#include "SPELL_CFG/SPELLconfiguration.H"
+#include "SPELL_SYN/SPELLmonitor.H"
+#include "SPELL_SYN/SPELLthread.H"
+#include "SPELL_IPC/SPELLipcHelper.H"
+#include "SPELL_UTIL/SPELLlog.H"
+#include "SPELL_UTIL/SPELLutils.H"
+#include "SPELL_UTIL/SPELLerror.H"
+#include "SPELL_UTIL/SPELLtime.H"
+#include "SPELL_IPC/SPELLipc_Executor.H"
+#include "SPELL_IPC/SPELLipc_Context.H"
+// System includes ---------------------------------------------------------
+
+// DEFINES /////////////////////////////////////////////////////////////////
+
+#define DEFAULT_START_TIMEOUT 20
+#define DEFAULT_LOGIN_TIMEOUT 60
+
+
+//=============================================================================
+// CONSTRUCTOR: SPELLservice::SPELLservice()
+//=============================================================================
+SPELLservice::SPELLservice( const SPELLserviceStartupParams& config )
+: SPELLexecutor(config,NULL)
+{
+
+}
+
+//=============================================================================
+// DESTRUCTOR: SPELLservice::~SPELLservice()
+//=============================================================================
+SPELLservice::~SPELLservice()
+{
+
+}
+
+//=============================================================================
+// METHOD: SPELLservice::start()
+//=============================================================================
+void SPELLservice::start()
+{
+ LOG_INFO("Starting service " + m_model.getInstanceId());
+ m_ipc.setup();
+ m_model.setIpcPort( m_ipc.getPort() );
+ m_executorLoggedInEvent.clear();
+
+ if (!m_reconnecting)
+ {
+ m_processStartedEvent.clear();
+ std::string command;
+ SPELLpyService& service = SPELLprocedureManager::instance().getService(m_model.getProcId());
+ int startTimeout = -1;
+ int loginTimeout = -1;
+ if (service.useCommandOverride())
+ {
+ std::string startTimeoutStr = SPELLconfiguration::instance().getContextParameter(SPELLcontextConfig::ExecutorStartTimeout);
+ std::string loginTimeoutStr = SPELLconfiguration::instance().getContextParameter(SPELLcontextConfig::ExecutorLoginTimeout);
+ if (startTimeoutStr != "")
+ {
+ startTimeout = STRI(startTimeoutStr);
+ }
+ if (loginTimeoutStr != "")
+ {
+ loginTimeout = STRI(loginTimeoutStr);
+ }
+ if (startTimeout == -1)
+ startTimeout = DEFAULT_START_TIMEOUT;
+ if (loginTimeout == -1)
+ loginTimeout = DEFAULT_LOGIN_TIMEOUT;
+
+ LOG_INFO("Using start timeout: " + ISTR(startTimeout) + " seconds");
+ LOG_INFO("Using login timeout: " + ISTR(loginTimeout) + " seconds");
+
+ std::string config = m_model.getConfigFile();
+ std::string contextName = m_model.getContextName();
+ int ipcPort = m_ipc.getPort();
+ std::string instanceId = m_model.getInstanceId();
+ std::string warmstartFile = "";
+ if (m_model.getWsFilename() != "")
+ {
+ warmstartFile = m_model.getWsFilename();
+ }
+ command = service.getCommandOverride(startTimeout,loginTimeout,config,contextName,ipcPort,instanceId,warmstartFile);
+ }
+ else
+ {
+ command = SPELLconfiguration::instance().getContextParameter( SPELLcontextConfig::ServiceProgram );
+
+ if (command == "")
+ {
+ THROW_EXCEPTION("Cannot launch service", "No service command defined in configuration", SPELL_ERROR_CONFIG);
+ }
+
+
+ std::string startTimeoutStr = SPELLconfiguration::instance().getContextParameter( SPELLcontextConfig::ExecutorStartTimeout );
+ std::string loginTimeoutStr = SPELLconfiguration::instance().getContextParameter( SPELLcontextConfig::ExecutorLoginTimeout );
+ if (startTimeoutStr != "")
+ {
+ startTimeout = STRI(startTimeoutStr);
+ }
+ if (loginTimeoutStr != "")
+ {
+ loginTimeout = STRI(loginTimeoutStr);
+ }
+ if (startTimeout == -1) startTimeout = DEFAULT_START_TIMEOUT;
+ if (loginTimeout == -1) loginTimeout = DEFAULT_LOGIN_TIMEOUT;
+
+ LOG_INFO("Using start timeout: " + ISTR(startTimeout) + " seconds");
+ LOG_INFO("Using login timeout: " + ISTR(loginTimeout) + " seconds");
+
+ command += " -c " + m_model.getConfigFile();
+ command += " -n " + m_model.getContextName();
+ command += " -s " + ISTR(m_ipc.getPort());
+ command += " -p " + m_model.getInstanceId(); // Parent id
+ command += " -w ";
+ if (m_model.getWsFilename() != "")
+ {
+ command += " -r " + m_model.getWsFilename();
+ }
+ }
+ if (SPELLprocessManager::instance().checkProcessExist(m_model.getInstanceId() ))
+ SPELLprocessManager::instance().killProcess( m_model.getInstanceId() );
+ SPELLprocessManager::instance().clearProcess( m_model.getInstanceId() );
+ SPELLprocessManager::instance().startProcess( m_model.getInstanceId(), command );
+
+ DEBUG("Waiting executor process to begin");
+ bool timedOut = m_processStartedEvent.wait( startTimeout * 1000 ); // milliseconds
+ if (timedOut)
+ {
+ THROW_EXCEPTION("Cannot launch executor", "Executor process did not begin in time", SPELL_ERROR_PROCESS);
+ }
+ DEBUG("Start event received");
+
+ m_processStatus = SPELLprocessManager::instance().getProcessStatus( m_model.getInstanceId() );
+ if (m_processStatus == PSTATUS_RUNNING)
+ {
+ if (!m_loggedIn)
+ {
+ DEBUG("Executor process started, waiting for login");
+ bool timeout = m_executorLoggedInEvent.wait( loginTimeout * 1000 ); // milliseconds
+ if (timeout)
+ {
+ THROW_EXCEPTION("Cannot launch executor", "Executor did not login in time", SPELL_ERROR_PROCESS);
+ }
+ }
+ DEBUG("Executor process logged in");
+ m_model.setPID( SPELLprocessManager::instance().getProcessId( m_model.getInstanceId() ));
+ LOG_INFO("Executor started: " + m_model.getInstanceId() + " with pid " + ISTR(m_model.getPID()));
+ }
+ else if (m_processStatus == PSTATUS_FINISHED )
+ {
+ THROW_EXCEPTION("Cannot launch executor", "Executor process finished too quickly", SPELL_ERROR_PROCESS);
+ }
+ else if (m_processStatus == PSTATUS_FAILED )
+ {
+ THROW_EXCEPTION("Cannot launch executor", "Executor process failed to start", SPELL_ERROR_PROCESS);
+ }
+ else if (m_processStatus == PSTATUS_KILLED )
+ {
+ THROW_EXCEPTION("Cannot launch executor", "Executor process crashed or was killed", SPELL_ERROR_PROCESS);
+ }
+ else
+ {
+ THROW_EXCEPTION("Cannot launch executor", "Executor process in unexpected state: " + SPELLprocessUtils::processStatusToString(m_processStatus), SPELL_ERROR_PROCESS);
+ }
+ }
+ else
+ {
+ m_loginMonitor = new LoginMonitor(*this);
+ m_loginMonitor->start();
+ }
+}
+
diff --git a/lib/SPELL_CTX/src/SPELLserviceManager.C b/lib/SPELL_CTX/src/SPELLserviceManager.C
new file mode 100644
index 0000000..fbee805
--- /dev/null
+++ b/lib/SPELL_CTX/src/SPELLserviceManager.C
@@ -0,0 +1,676 @@
+// ################################################################################
+// FILE : SPELLserviceManager.C
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Implementation of the executor manager
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// Local includes ----------------------------------------------------------
+#include "SPELL_CTX/SPELLserviceManager.H"
+#include "SPELL_CTX/SPELLservice.H"
+#include "SPELL_CTX/SPELLclientManager.H"
+#include "SPELL_CTX/SPELLdataHelper.H"
+#include "SPELL_CTX/SPELLcontext.H"
+// Project includes --------------------------------------------------------
+#include "SPELL_PRD/SPELLprocedureManager.H"
+#include "SPELL_SYN/SPELLmonitor.H"
+#include "SPELL_UTIL/SPELLlog.H"
+#include "SPELL_UTIL/SPELLutils.H"
+#include "SPELL_UTIL/SPELLerror.H"
+#include "SPELL_CFG/SPELLconfiguration.H"
+#include "SPELL_IPC/SPELLipc_Context.H"
+#include "SPELL_IPC/SPELLipc_Executor.H"
+#include "SPELL_WRP/SPELLconstants.H"
+// System includes ---------------------------------------------------------
+
+
+// DEFINES /////////////////////////////////////////////////////////////////
+SPELLserviceManager* SPELLserviceManager::s_instance = NULL;
+
+//=============================================================================
+// CONSTRUCTOR: SPELLexecutorManager::SPELLexecutorManager()
+//=============================================================================
+SPELLserviceManager::SPELLserviceManager()
+{
+ m_persisTable = NULL;
+}
+
+//=============================================================================
+// DESTRUCTOR: SPELLexecutorManager::~SPELLexecutorManager()
+//=============================================================================
+SPELLserviceManager::~SPELLserviceManager()
+{
+}
+
+//=============================================================================
+// STATIC: SPELLexecutorManager::instance()
+//=============================================================================
+SPELLserviceManager& SPELLserviceManager::instance()
+{
+ if (s_instance == NULL)
+ {
+ s_instance = new SPELLserviceManager();
+ }
+ return *s_instance;
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::setup()
+//=============================================================================
+void SPELLserviceManager::setup( const std::string& ctxName )
+{
+ m_contextName = ctxName;
+ m_persisTable = new SPELLpersistencyTable(ctxName + "_services");
+ if (m_persisTable->load())
+ {
+ reconnectServices();
+ }
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::setup()
+//=============================================================================
+void SPELLserviceManager::cleanup()
+{
+ if (m_persisTable) delete m_persisTable;
+ for( ServiceMap::iterator it = m_pendingLogin.begin(); it != m_pendingLogin.end(); it++ )
+ {
+ delete it->second;
+ }
+ m_pendingLogin.clear();
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::startExecutor()
+//=============================================================================
+void SPELLserviceManager::startService( SPELLserviceStartupParams& config)
+{
+ DEBUG( "[SMGR] Start service TRY-IN");
+
+ SPELLmonitor m(m_lock);
+ DEBUG( "[SMGR] Start executor IN");
+ config.setContextName(m_contextName);
+ config.setConfigFile(SPELLconfiguration::instance().getFile());
+
+ // Create and start the executor with the given configuration
+
+ // If the open mode does not include VISIBLE, do not pass the controlling client
+ // This way we force the GUI to attach to a proc when it is started in non-visible
+ SPELLservice* exec = NULL;
+
+ DEBUG( "[SMGR] Start executor in background");
+ exec = new SPELLservice(config);
+
+ try
+ {
+ LOG_INFO("Starting service " + exec->getModel().getInstanceId() );
+ exec->start();
+
+ addInstanceNumber( exec->getModel().getProcId(), exec->getModel().getInstanceNum() );
+ addServiceModel( exec );
+
+ LOG_INFO("Service ready");
+ }
+ catch(SPELLcoreException& ex)
+ {
+ // Delete recovery files just created for the new executor file
+ deleteServiceFiles(config);
+ DEBUG( "[SMGR] Start service OUT");
+ THROW_EXCEPTION("Failed to start service", ex.what(), SPELL_ERROR_PROCESS);
+ }
+ DEBUG( "[SMGR] Start executor OUT");
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::reconnectExecutors()
+//=============================================================================
+void SPELLserviceManager::reconnectServices()
+{
+ DEBUG( "[SMGR] Reconnecting orphan services");
+ SPELLmonitor m(m_lock);
+ std::vector ids = m_persisTable->getRegisteredExecutors();
+ m_pendingLogin.clear();
+ for(std::vector::iterator it = ids.begin(); it != ids.end(); it++)
+ {
+ std::string instanceId = *it;
+ SPELLexecutorPersistency pers = m_persisTable->getExecutorPersistency(instanceId);
+
+ if (getpgid(pers.pid) < 0)
+ {
+ DEBUG( "[SMGR] PID " + ISTR(pers.pid) + " for service "+instanceId+" not found");
+ continue;
+ }
+
+ SPELLserviceStartupParams config( instanceId, pers.timeId, true );
+ config.setParentInstanceId(pers.parentId);
+ config.setIpcPort(pers.ipcPort);
+ config.setPID(pers.pid);
+
+ SPELLservice* exec = new SPELLservice(config);
+ try
+ {
+ LOG_WARN("Reconnecting service " + instanceId + " listening on port " + ISTR(pers.ipcPort) );
+ exec->start();
+ m_services.insert( std::make_pair( exec->getModel().getInstanceId(), exec ));
+ m_pendingLogin.insert( std::make_pair( instanceId, exec ) );
+ }
+ catch(SPELLcoreException& ex)
+ {
+ deleteServiceFiles(config);
+ }
+ }
+ DEBUG( "[SMGR] Reconnect services done");
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::callback_executorReconnected()
+//=============================================================================
+void SPELLserviceManager::callback_serviceReconnected( const std::string& instanceId )
+{
+ LOG_WARN("#######################################");
+ LOG_WARN("Service " + instanceId + " reconnected");
+ LOG_WARN("#######################################");
+ SPELLmonitor m(m_lock);
+ ServiceMap::iterator it = m_pendingLogin.find(instanceId);
+ if (it != m_pendingLogin.end())
+ {
+ SPELLservice* exec = it->second;
+ addInstanceNumber( exec->getModel().getProcId(), exec->getModel().getInstanceNum() );
+ addServiceModel( exec );
+ m_pendingLogin.erase(it);
+
+ SPELLexecutorOperation op;
+ op.instanceId = exec->getModel().getInstanceId();
+ op.parentId = exec->getModel().getParentInstanceId();
+ op.groupId = exec->getModel().getGroupId();
+ op.originId = exec->getModel().getOriginId();
+ op.status = exec->getModel().getStatus();
+ op.type = SPELLexecutorOperation::EXEC_OP_OPEN;
+
+ SPELLcontext::instance().notifyExecutorOperation( op );
+ }
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::callback_executorNotReconnected()
+//=============================================================================
+void SPELLserviceManager::callback_serviceNotReconnected( const std::string& instanceId )
+{
+ LOG_ERROR("#######################################");
+ LOG_ERROR("Service " + instanceId + " failed to reconnect");
+ LOG_ERROR("#######################################");
+ SPELLmonitor m(m_lock);
+ ServiceMap::iterator it = m_pendingLogin.find(instanceId);
+ if (it != m_pendingLogin.end())
+ {
+ m_persisTable->deregisterExecutor(it->second->getModel().getInstanceId());
+ delete it->second;
+ m_pendingLogin.erase(it);
+ }
+}
+
+////=============================================================================
+//// METHOD: SPELLexecutorManager::recoverExecutor()
+////=============================================================================
+//void SPELLserviceManager::recoverExecutor( SPELLexecutorStartupParams& config, SPELLclient* controllingClient )
+//{
+// //TODO check maximum number of executors
+// SPELLmonitor m(m_lock);
+// config.setContextName(m_contextName);
+// config.setConfigFile(SPELLconfiguration::instance().getFile());
+//
+// // Create and start the executor with the given configuration
+//
+// // If the open mode does not include VISIBLE, do not pass the controlling client
+// // This way we force the GUI to attach to a proc when it is started in non-visible
+// SPELLexecutor* exec = new SPELLexecutor(config, controllingClient);
+// try
+// {
+// LOG_INFO("Recovering executor " + exec->getModel().getInstanceId() );
+// exec->start();
+//
+// addInstanceNumber( exec->getModel().getProcId(), exec->getModel().getInstanceNum() );
+// addExecutorModel( exec );
+//
+// LOG_INFO("Executor ready");
+// }
+// catch(SPELLcoreException& ex)
+// {
+// // Delete recovery files just created for the new executor file
+// deleteExecutorFiles(config);
+// THROW_EXCEPTION("Failed to recover executor", ex.what(), SPELL_ERROR_PROCESS);
+// }
+//}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::deleteExecutorFiles()
+//=============================================================================
+void SPELLserviceManager::deleteServiceFiles( const SPELLserviceStartupParams& config )
+{
+ SPELLcontextConfig& ctxConfig = SPELLconfiguration::instance().getContext(m_contextName);
+
+ std::string fileName = config.getTimeId() + "_Service_" + config.getInstanceId();
+
+ LOG_INFO("Deleting service files: " + fileName );
+
+ // Delete warmstart files
+ std::string wsDataDir = SPELLutils::getSPELL_DATA() + PATH_SEPARATOR + ctxConfig.getLocationPath("ws");
+ std::list files = SPELLutils::getFilesInDir(wsDataDir);
+
+ for(std::list::const_iterator it = files.begin(); it != files.end(); it++)
+ {
+ std::string completeFilename = *it;
+ if (completeFilename.find(fileName) != std::string::npos)
+ {
+ std::string path = wsDataDir + PATH_SEPARATOR + completeFilename;
+ if (SPELLutils::pathExists(path))
+ {
+ SPELLutils::deleteFile(path);
+ LOG_INFO("Delete " + path );
+ }
+ }
+ }
+
+ // Delete Asrun files
+ std::string arDataDir = SPELLutils::getSPELL_DATA() + PATH_SEPARATOR + ctxConfig.getLocationPath("ar");
+
+ files = SPELLutils::getFilesInDir(arDataDir);
+
+ for(std::list::const_iterator it = files.begin(); it != files.end(); it++)
+ {
+ std::string completeFilename = *it;
+ if (completeFilename.find(fileName) != std::string::npos)
+ {
+ std::string path = arDataDir + PATH_SEPARATOR + completeFilename;
+ if (SPELLutils::pathExists(path))
+ {
+ SPELLutils::deleteFile(path);
+ LOG_INFO("Delete " + path );
+ }
+ }
+ }
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::addExecutorModel()
+//=============================================================================
+void SPELLserviceManager::addServiceModel( SPELLservice* exec )
+{
+ const std::string id = exec->getModel().getInstanceId();
+ if (m_services.count(id) > 0)
+ {
+ delete m_services[id];
+ m_services.erase(id);
+ }
+ m_services.insert( std::make_pair( exec->getModel().getInstanceId(), exec ));
+ DEBUG("[SMGR] Added executor: '" + exec->getModel().getInstanceId() + "'");
+ m_persisTable->registerExecutor(exec->getModel().getInstanceId(),
+ exec->getModel().getTimeId(),
+ exec->getModel().getParentInstanceId(),
+ exec->getModel().getIpcPort(),
+ exec->getModel().getPID() );
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::removeExecutorModel()
+//=============================================================================
+void SPELLserviceManager::removeServiceModel( const std::string& instanceId )
+{
+ ServiceMap::iterator it = m_services.find(instanceId);
+ if (it != m_services.end())
+ {
+ DEBUG("[SMGR] Removing service model: '" + instanceId + "'");
+ m_persisTable->deregisterExecutor(it->second->getModel().getInstanceId());
+ delete it->second;
+ m_services.erase(it);
+ DEBUG("[SMGR] Removed service: '" + instanceId + "'");
+ }
+ else
+ {
+ LOG_ERROR("[SMGR]: No service to remove: '" + instanceId + "'");
+ }
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::getInstanceId()
+//=============================================================================
+std::string SPELLserviceManager::getInstanceId( const std::string& procId )
+{
+ SPELLmonitor m(m_lock);
+
+ // We never remove instance numbers but we can live with it - memory consumption
+ // is not big and do not need to be concerned with race conditions between add and get
+ // due to simultaneous requests from *different* clients (e.g .GUI and Parent Exec).
+
+ // Nevertheless attempt to clean now, protected by the lock, before getting an instance id.
+ // Just clean if no executors running.
+ if (m_services.size()==0) m_instances.clear();
+
+ std::string instanceId = "";
+ InstanceMap::iterator it = m_instances.find(procId);
+ if ( it == m_instances.end() )
+ {
+ instanceId = procId;
+ }
+ else
+ {
+ int instanceNum = 0;
+ while(hasInstanceNumber(procId, instanceNum)) instanceNum++;
+ addInstanceNumber(procId, instanceNum);
+ instanceId = procId;
+ }
+ LOG_INFO("Assigned instance id: '" + instanceId + "'");
+ return instanceId;
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::addInstanceNumber()
+//=============================================================================
+void SPELLserviceManager::addInstanceNumber( const std::string& procId, int instanceNum )
+{
+ InstanceMap::iterator it = m_instances.find(procId);
+ if (it == m_instances.end())
+ {
+ InstanceList list;
+ list.push_back(instanceNum);
+ m_instances.insert( std::make_pair( procId, list ) );
+ }
+ else
+ {
+ it->second.push_back(instanceNum);
+ }
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::hasInstanceNumber()
+//=============================================================================
+bool SPELLserviceManager::hasInstanceNumber( const std::string& procId, int instanceNum )
+{
+ InstanceMap::iterator it = m_instances.find(procId);
+ InstanceList::iterator lit;
+ for( lit = it->second.begin(); lit != it->second.end(); lit++ )
+ {
+ if (*lit == instanceNum) return true;
+ }
+ return false;
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::closeExecutor()
+//=============================================================================
+void SPELLserviceManager::closeService( const std::string& instanceId )
+{
+ SPELLmonitor m(m_lock);
+ try
+ {
+ // Will raise exception if not found
+ SPELLservice* exec = getService(instanceId);
+ exec->close();
+ removeServiceModel( exec->getModel().getInstanceId() );
+ LOG_INFO("Service successfully closed: " + instanceId);
+ }
+ catch(SPELLcoreException& ex)
+ {
+ LOG_ERROR("Unable to find service '" + instanceId + "', cannot close");
+ }
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::executorLost()
+//=============================================================================
+void SPELLserviceManager::serviceLost( SPELLservice& service )
+{
+ LOG_WARN( "[SMGR] Service lost: " + service.getModel().getInstanceId());
+ clearService(service.getModel().getInstanceId());
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::killExecutor()
+//=============================================================================
+void SPELLserviceManager::killService( const std::string& instanceId )
+{
+ try
+ {
+ SPELLmonitor m(m_lock);
+ // Will raise exception if not found
+ SPELLservice* exec = getService(instanceId);
+ exec->kill();
+ removeServiceModel( exec->getModel().getInstanceId() );
+ }
+ catch(SPELLcoreException& ex)
+ {
+ THROW_EXCEPTION("Failed to kill Service '" + instanceId + "' ", ex.what(), SPELL_ERROR_PROCESS);
+ }
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::clearExecutor()
+//=============================================================================
+void SPELLserviceManager::clearService( const std::string& instanceId )
+{
+ SPELLmonitor m(m_lock);
+ m_toClear.push_back(instanceId);
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::clearModels
+//=============================================================================
+void SPELLserviceManager::clearModels()
+{
+ if (m_toClear.size()>0)
+ {
+ IdentifierList::iterator it;
+ for( it = m_toClear.begin(); it != m_toClear.end(); it++)
+ {
+ ServiceMap::iterator eit = m_services.find(*it);
+ if (eit != m_services.end())
+ {
+ try
+ {
+ SPELLservice* exec = getService(*it);
+ removeServiceModel( exec->getModel().getInstanceId() );
+ }
+ catch(SPELLcoreException& ex)
+ {
+ LOG_ERROR("Failed to remove executor model");
+ };
+ }
+ }
+ m_toClear.clear();
+ if (m_services.empty()){
+ m_instances.clear();
+ }
+ }
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::getExecutor()
+//=============================================================================
+SPELLservice* SPELLserviceManager::getService( const std::string& instanceId )
+{
+ DEBUG("[SMGR] Search for service: '" + instanceId + "'");
+ int idx = instanceId.find("#");
+ std::string id = instanceId;
+ if (idx >= 0)
+ id = id.substr(0,idx);
+ ServiceMap::iterator it = m_services.find(id);
+ if (it != m_services.end()) return it->second;
+ THROW_EXCEPTION("Cannot get service", "No such id: " + instanceId, SPELL_ERROR_EXECUTION );
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::killAll()
+//=============================================================================
+void SPELLserviceManager::killAll()
+{
+ DEBUG( "[SMGR] Kill all Services");
+ ServiceList list = getServiceList();
+ ServiceList::iterator lit;
+ for( lit = list.begin(); lit != list.end(); lit++)
+ {
+ try
+ {
+ killService(*lit);
+ }
+ catch(SPELLcoreException& ex)
+ {
+ LOG_ERROR("Could not kill service: " + ex.what());
+ }
+ }
+ DEBUG( "[SMGR] Kill all services done");
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::getNumActiveExecutors()
+//=============================================================================
+unsigned int SPELLserviceManager::getNumActiveServices()
+{
+ DEBUG( "[SMGR] Get number of active services TRY-IN");
+ SPELLmonitor m(m_lock);
+ DEBUG( "[SMGR] Get number of active services IN");
+ clearModels();
+ ServiceMap::iterator it;
+ unsigned int numActive = 0;
+ for( it = m_services.begin(); it != m_services.end(); it++)
+ {
+ if (it->second->isActive()) numActive++;
+ }
+ DEBUG( "[SMGR] Get number of active services OUT");
+ return numActive;
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::getExecutorList()
+//=============================================================================
+SPELLserviceManager::ServiceList SPELLserviceManager::getServiceList()
+{
+ SPELLmonitor m(m_lock);
+ clearModels();
+ ServiceList ids;
+ ServiceMap::iterator it;
+ for( it = m_services.begin(); it != m_services.end(); it++)
+ {
+ ids.push_back(it->first);
+ }
+ //DEBUG( "[SMGR] Get service list OUT");
+ return ids;
+}
+
+//=============================================================================
+// METHOD: SPELLexecutorManager::buildExecutorInfo()
+//=============================================================================
+void SPELLserviceManager::buildServiceInfo( const std::string& serviceId, SPELLipcMessage& msg )
+{
+ LOG_INFO("Building service information for " + serviceId );
+
+ try
+ {
+ // Will raise exception if not found
+ std::string procId;
+ std::string::size_type idx = serviceId.find("#");
+ if (idx != std::string::npos)
+ procId = serviceId.substr(0,idx);
+ else
+ procId = serviceId;
+ SPELLservice* exec = getService(procId);
+ SPELLpyService& service = SPELLprocedureManager::instance().getService(procId);
+
+ msg.set( MessageField::FIELD_PROC_ID, procId);
+ msg.set( MessageField::FIELD_PARENT_PROC, exec->getModel().getParentInstanceId() );
+ msg.set( MessageField::FIELD_PARENT_PROC_LINE, ISTR(exec->getModel().getParentCallingLine()) );
+
+ // The group id of a main (without parent) procedure is the same as proc id.
+ std::string groupId = exec->getModel().getGroupId();
+ if (groupId == "") groupId = procId;
+ msg.set( MessageField::FIELD_GROUP_ID, groupId );
+ // The origin id is optional
+ msg.set( MessageField::FIELD_ORIGIN_ID, exec->getModel().getOriginId() );
+ msg.set( MessageField::FIELD_PROC_NAME, service.getName() + "#0");
+ msg.set( MessageField::FIELD_ASRUN_NAME, exec->getModel().getAsRunFilename() );
+ msg.set( MessageField::FIELD_LOG_NAME, exec->getModel().getLogFilename() );
+ SPELLexecutorStatus st = exec->getStatus();
+ msg.set( MessageField::FIELD_EXEC_STATUS, SPELLdataHelper::executorStatusToString(st) );
+ msg.set( MessageField::FIELD_CONDITION, exec->getModel().getCondition() );
+ msg.set( MessageField::FIELD_STAGE_ID, exec->getModel().getStageId() );
+ msg.set( MessageField::FIELD_STAGE_TL, exec->getModel().getStageTitle() );
+ msg.set( MessageField::FIELD_CSP, exec->getModel().getStack() );
+ msg.set( MessageField::FIELD_CODE_NAME, exec->getModel().getCode() );
+
+ if (exec->getModel().getUserAction().isSet())
+ {
+ std::string action = exec->getModel().getUserAction().getLabel();
+ LOG_INFO("User action: " + action);
+ msg.set( MessageField::FIELD_ACTION_LABEL, action );
+ LOG_INFO("User action enabled: " + BSTR(exec->getModel().getUserAction().isEnabled()));
+ msg.set( MessageField::FIELD_ACTION_ENABLED, exec->getModel().getUserAction().isEnabled() ? "true" : "false" );
+ switch(exec->getModel().getUserAction().getSeverity())
+ {
+ case LanguageConstants::INFORMATION:
+ msg.set( MessageField::FIELD_ACTION_SEVERITY, MessageValue::DATA_SEVERITY_INFO );
+ break;
+ case LanguageConstants::WARNING:
+ msg.set( MessageField::FIELD_ACTION_SEVERITY, MessageValue::DATA_SEVERITY_WARN );
+ break;
+ case LanguageConstants::ERROR:
+ msg.set( MessageField::FIELD_ACTION_SEVERITY, MessageValue::DATA_SEVERITY_ERROR );
+ break;
+ default:
+ msg.set( MessageField::FIELD_ACTION_SEVERITY, MessageValue::DATA_SEVERITY_INFO );
+ break;
+ }
+ }
+
+ LOG_INFO("[SMGR] Parent procedure : " + exec->getModel().getParentInstanceId());
+ LOG_INFO("[SMGR] Status : " + SPELLdataHelper::executorStatusToString(st));
+ LOG_INFO("[SMGR] ASRUN file : " + exec->getModel().getAsRunFilename());
+
+
+ LOG_INFO("[SMGR] Procedure in background");
+ msg.set( MessageField::FIELD_GUI_CONTROL, "" );
+ msg.set( MessageField::FIELD_GUI_CONTROL_HOST, "" );
+
+ msg.set( MessageField::FIELD_OPEN_MODE, SPELLdataHelper::openModeToString(exec->getModel().getOpenMode()) );
+ LOG_INFO("[SMGR] Open mode : " + SPELLdataHelper::openModeToString(exec->getModel().getOpenMode()));
+ }
+ catch(SPELLcoreException& ex)
+ {
+ LOG_ERROR("No service found to complete information");
+ msg.set( MessageField::FIELD_PROC_ID, serviceId );
+ msg.set( MessageField::FIELD_GROUP_ID, serviceId );
+ msg.set( MessageField::FIELD_ORIGIN_ID, "???" );
+ msg.set( MessageField::FIELD_PARENT_PROC, " " );
+ msg.set( MessageField::FIELD_PARENT_PROC_LINE, " " );
+ msg.set( MessageField::FIELD_PROC_NAME, "" );
+ msg.set( MessageField::FIELD_ASRUN_NAME, " " );
+ msg.set( MessageField::FIELD_EXEC_STATUS, SPELLdataHelper::executorStatusToString(STATUS_UNINIT) );
+ msg.set( MessageField::FIELD_CONDITION, " " );
+ msg.set( MessageField::FIELD_GUI_LIST, " " );
+ msg.set( MessageField::FIELD_GUI_CONTROL, " " );
+ msg.set( MessageField::FIELD_GUI_CONTROL_HOST, " " );
+ msg.set( MessageField::FIELD_OPEN_MODE, " " );
+ msg.set( MessageField::FIELD_STAGE_ID, " " );
+ msg.set( MessageField::FIELD_STAGE_TL, " " );
+ msg.set( MessageField::FIELD_CSP, " " );
+ msg.set( MessageField::FIELD_CODE_NAME, " " );
+ }
+}
diff --git a/lib/SPELL_CTX/src/SPELLsharedData.C b/lib/SPELL_CTX/src/SPELLsharedData.C
index 7f27809..41567b4 100644
--- a/lib/SPELL_CTX/src/SPELLsharedData.C
+++ b/lib/SPELL_CTX/src/SPELLsharedData.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the shared data tables container
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_DTA/Makefile.am b/lib/SPELL_DTA/Makefile.am
index 5bc6b10..b831272 100644
--- a/lib/SPELL_DTA/Makefile.am
+++ b/lib/SPELL_DTA/Makefile.am
@@ -1,41 +1,46 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
include ${top_srcdir}/common.mk
+lib_LTLIBRARIES = libSPELL_DTA_v2.la libSPELL_DTA_v3.la
-lib_LTLIBRARIES= libSPELL_DTA.la
+libSPELL_DTA_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
-libSPELL_DTA_la_CPPFLAGS = ${AM_CPPFLAGS} -DWITH_DEBUG
-libSPELL_DTA_la_LDFLAGS = -version-info 1:0:0
+libSPELL_DTA_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
-libSPELL_DTA_la_SOURCES = \
- src/SPELLdtaContainerObjectMethods.C \
- src/SPELLdtaVariableObjectMethods.C \
- src/SPELLdtaVariable.C \
- src/SPELLdtaContainer.C \
- src/SPELLdtaModule.C
-
+libSPELL_DTA_v2_la_SOURCES = src/SPELLdtaContainerObjectMethods.C \
+ src/SPELLdtaVariableObjectMethods.C \
+ src/SPELLdtaVariable.C \
+ src/SPELLdtaContainer.C \
+ src/SPELLdtaModule.C
+
+
+libSPELL_DTA_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS}
+
+libSPELL_DTA_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_DTA_v3_la_SOURCES = src/SPELLdtaContainerObjectMethods.C \
+ src/SPELLdtaVariableObjectMethods.C \
+ src/SPELLdtaVariable.C \
+ src/SPELLdtaContainer.C \
+ src/SPELLdtaModule.C
+
\ No newline at end of file
diff --git a/lib/SPELL_DTA/src/SPELLdtaContainer.C b/lib/SPELL_DTA/src/SPELLdtaContainer.C
index 35927bc..bd0031c 100644
--- a/lib/SPELL_DTA/src/SPELLdtaContainer.C
+++ b/lib/SPELL_DTA/src/SPELLdtaContainer.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Data variable container implementation
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -181,7 +181,7 @@ void SPELLdtaContainer::setValue( PyObject* key, PyObject* value )
{
DEBUG("[DTAC] Creating a new variable to contain the value");
- PyObject* varClass = SPELLpythonHelper::instance().getObject("libSPELL_DTA", "Var");
+ PyObject* varClass = SPELLpythonHelper::instance().getObject(MOD_NAME(libSPELL_DTA), "Var");
Py_INCREF(varClass);
assert(varClass != NULL);
PyObject* dict = PyDict_New();
@@ -233,7 +233,7 @@ PyObject* SPELLdtaContainer::getValue( PyObject* key )
if (!PyDict_Contains(m_dict, key))
{
DEBUG("[DTAC] Variable is missing, asking for a value");
- PyObject* varClass = SPELLpythonHelper::instance().getObject("libSPELL_DTA", "Var");
+ PyObject* varClass = SPELLpythonHelper::instance().getObject(MOD_NAME(libSPELL_DTA), "Var");
Py_XINCREF(varClass);
PyObject* instance = SPELLpythonHelper::instance().newInstance(varClass, NULL, NULL);
Py_XINCREF(instance);
diff --git a/lib/SPELL_DTA/src/SPELLdtaContainerObjectMethods.C b/lib/SPELL_DTA/src/SPELLdtaContainerObjectMethods.C
index 5e3a775..0a95e3f 100644
--- a/lib/SPELL_DTA/src/SPELLdtaContainerObjectMethods.C
+++ b/lib/SPELL_DTA/src/SPELLdtaContainerObjectMethods.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of data container
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -65,7 +65,7 @@ int SPELLdtaContainerObject_Init( SPELLdtaContainerObject* self, PyObject* args,
void SPELLdtaContainerObject_Dealloc( SPELLdtaContainerObject* self )
{
delete self->container;
- self->ob_type->tp_free( (PyObject*) self );
+ Py_TYPE(self)->tp_free( (PyObject*) self );
}
//============================================================================
@@ -326,8 +326,7 @@ static PyMethodDef dictiter_methods[] = {
PyTypeObject SPELLdtaContainerIterator_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, /* ob_size */
+ PyVarObject_HEAD_INIT(&PyType_Type,0)
"container-keyiterator", /* tp_name */
sizeof(SPELLdtaContainerIteratorObject),/* tp_basicsize */
0, /* tp_itemsize */
@@ -380,51 +379,42 @@ PyObject* SPELLdtaContainerObject_NewIterator( SPELLdtaContainerObject* containe
//============================================================================
void SPELLdtaContainerObject_DeallocIterator( SPELLdtaContainerIteratorObject* di )
{
- di->ob_type->tp_free( (PyObject*)di );
+ Py_TYPE(di)->tp_free( (PyObject*)di );
}
//============================================================================
// FUNCTION : SPELLdtaContainerObject_NextKey
//============================================================================
-PyObject* SPELLdtaContainerObject_NextKey( SPELLdtaContainerIteratorObject* di )
+PyObject* SPELLdtaContainerObject_NextKey(SPELLdtaContainerIteratorObject* di)
{
- PyObject *key;
- register Py_ssize_t i, mask;
- register PyDictEntry *ep;
+ PyObject *key, *value;
+ Py_ssize_t i;
+ int result;
+ DEBUG("[DTAPY] Next iterator key on " + PYCREPR(di));
- DEBUG("[DTAPY] Next iterator key on " + PYCREPR(di));
+ PyObject* d = (PyObject*) di->di_dict;
- PyDictObject* d = di->di_dict;
+ if (d == NULL)
+ return NULL;
+ assert(PyDict_Check(d));
- DEBUG("[DTAPY] Dictionary: " + PYCREPR(d));
+ i = di->di_pos;
+ if (i < 0)
+ goto fail;
- if (d == NULL) return NULL;
+ result = PyDict_Next(d, &di->di_pos, &key, &value);
- if (di->di_used != d->ma_used)
- {
- PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration");
- di->di_used = -1; /* Make this state sticky */
- LOG_ERROR("Dictionary changed size during iteration!!!");
- return NULL;
- }
-
- i = di->di_pos;
- if (i < 0) goto fail;
- ep = d->ma_table;
- mask = d->ma_mask;
- while (i <= mask && ep[i].me_value == NULL) i++;
- di->di_pos = i+1;
- if (i > mask) goto fail;
- di->len--;
- key = ep[i].me_key;
- if (key == NULL) goto fail;
- Py_INCREF(key);
- return key;
-fail:
- DEBUG("[DTAPY] No key found to iterate on");
- di->di_dict = NULL;
- PyErr_Clear();
- return NULL;
+ if (!result)
+ goto fail;
+
+ di->len--;
+
+ Py_INCREF(key);
+ return key;
+fail: DEBUG("[DTAPY] No key found to iterate on");
+ di->di_dict = NULL;
+ PyErr_Clear();
+ return NULL;
}
//============================================================================
diff --git a/lib/SPELL_DTA/src/SPELLdtaModule.C b/lib/SPELL_DTA/src/SPELLdtaModule.C
index 1da117e..db7a5d2 100644
--- a/lib/SPELL_DTA/src/SPELLdtaModule.C
+++ b/lib/SPELL_DTA/src/SPELLdtaModule.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of DTA module
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -54,7 +54,7 @@ static PyMethodDef SPELLdtaContainerObject_Methods[] =
{"get", SPELLdtaContainerObject_Get, METH_VARARGS, "Get a value"},
{"has_key", SPELLdtaContainerObject_HasKey, METH_VARARGS, "Check if the key exists"},
{"keys", SPELLdtaContainerObject_Keys, METH_NOARGS, "Obtain the keys"},
- {"values", SPELLdtaContainerObject_Keys, METH_NOARGS, "Obtain the values"},
+ {"values", SPELLdtaContainerObject_Values, METH_NOARGS, "Obtain the values"},
{"enableNotifications", SPELLdtaContainerObject_EnableNotifications, METH_NOARGS, "Enable value notifications"},
{"disableNotifications", SPELLdtaContainerObject_DisableNotifications, METH_NOARGS, "Disable value notifications"},
{NULL, NULL, 0, NULL} /* Sentinel */
@@ -91,8 +91,7 @@ static PyMappingMethods SPELLdtaContainerObject_MappingMethods =
//============================================================================
static PyTypeObject SPELLdtaContainerObject_Type =
{
- PyObject_HEAD_INIT(NULL) /* basic object head */
- 0, /* var objects */
+ PyVarObject_HEAD_INIT(NULL,0) /* basic object head */
"spell.lib.adapter.data.DataContainer", /* type name */
sizeof(SPELLdtaContainerObject), /* type size */
0, /* item size */
@@ -145,8 +144,7 @@ static PyTypeObject SPELLdtaContainerObject_Type =
//============================================================================
static PyTypeObject SPELLdtaVariableObject_Type =
{
- PyObject_HEAD_INIT(NULL) /* basic object head */
- 0, /* var objects */
+ PyVarObject_HEAD_INIT(NULL,0) /* basic object head */
"spell.lib.adapter.data.Var", /* type name */
sizeof(SPELLdtaVariableObject), /* type size */
0, /* item size */
@@ -197,8 +195,8 @@ static PyTypeObject SPELLdtaVariableObject_Type =
//////////////////////////////////////////////////////////////////////////////
// PYTHON MODULE INITIALIZATION
//////////////////////////////////////////////////////////////////////////////
-PyMODINIT_FUNC
-initlibSPELL_DTA(void)
+
+MOD_INIT(libSPELL_DTA)
{
// Will hold the Python module
PyObject* module;
@@ -210,7 +208,7 @@ initlibSPELL_DTA(void)
std::string err = "Unable to load type " + std::string(SPELLdtaContainerObject_Type.tp_name);
PyErr_SetString( PyExc_RuntimeError, err.c_str());
std::cerr << "ERROR: " << err << std::endl;
- return;
+ return MOD_ERROR_VAL;
}
// Allocate the new type for SPELL variable containers
@@ -220,15 +218,17 @@ initlibSPELL_DTA(void)
std::string err = "Unable to load type " + std::string(SPELLdtaVariableObject_Type.tp_name);
PyErr_SetString( PyExc_RuntimeError, err.c_str());
std::cerr << "ERROR: " << err << std::endl;
- return;
+ return MOD_ERROR_VAL;
}
// Initialize the module
- module = Py_InitModule3("libSPELL_DTA", NULL, "Module for SPELL data containers");
+ MOD_DEF(module,MOD_NAME(libSPELL_DTA),"Module for SPELL data containers",NULL);
Py_INCREF(&SPELLdtaContainerObject_Type);
PyModule_AddObject(module, "DataContainer", (PyObject *)&SPELLdtaContainerObject_Type);
Py_INCREF(&SPELLdtaVariableObject_Type);
PyModule_AddObject(module, "Var", (PyObject *)&SPELLdtaVariableObject_Type);
+
+ return MOD_SUCCESS_VAL(module);
}
diff --git a/lib/SPELL_DTA/src/SPELLdtaVariable.C b/lib/SPELL_DTA/src/SPELLdtaVariable.C
index 4b0e372..66f5f19 100644
--- a/lib/SPELL_DTA/src/SPELLdtaVariable.C
+++ b/lib/SPELL_DTA/src/SPELLdtaVariable.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Data variable implementation
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -955,10 +955,14 @@ bool SPELLdtaVariable::promptForValue( std::string& message )
for(unsigned int idx = 0; idx < m_expected.size(); idx++)
{
std::string option = "";
- if (m_type == LanguageConstants::STRING || m_type == LanguageConstants::DATETIME || m_type == LanguageConstants::RELTIME )
+ if (m_type == LanguageConstants::STRING)
{
option = "'" + m_expected[idx].str() + "'";
}
+ else if (m_type == LanguageConstants::DATETIME || m_type == LanguageConstants::RELTIME )
+ {
+ option = m_expected[idx].str();
+ }
else
{
option = m_expected[idx].str();
diff --git a/lib/SPELL_DTA/src/SPELLdtaVariableObjectMethods.C b/lib/SPELL_DTA/src/SPELLdtaVariableObjectMethods.C
index ebbbb89..580343a 100644
--- a/lib/SPELL_DTA/src/SPELLdtaVariableObjectMethods.C
+++ b/lib/SPELL_DTA/src/SPELLdtaVariableObjectMethods.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of variable container
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -70,7 +70,7 @@ int SPELLdtaVariableObject_Init( SPELLdtaVariableObject* self, PyObject* args, P
void SPELLdtaVariableObject_Dealloc( SPELLdtaVariableObject* self )
{
delete self->var;
- self->ob_type->tp_free( (PyObject*) self );
+ Py_TYPE(self)->tp_free( (PyObject*) self );
}
//============================================================================
diff --git a/lib/SPELL_EXC/Makefile.am b/lib/SPELL_EXC/Makefile.am
index 9a4fab4..733d639 100644
--- a/lib/SPELL_EXC/Makefile.am
+++ b/lib/SPELL_EXC/Makefile.am
@@ -1,62 +1,98 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
include ${top_srcdir}/common.mk
-#libSPELL_EXC_la_CPPFLAGS = ${AM_CPPFLAGS} -DWITH_DEBUG
-
-lib_LTLIBRARIES= libSPELL_EXC.la
-libSPELL_EXC_la_LDFLAGS = -version-info 3:0:0
-libSPELL_EXC_la_SOURCES = \
- src/SPELLgoto.C \
- src/SPELLbreakpoint.C \
- src/SPELLbreakpointType.C \
- src/SPELLbytecode.C \
- src/SPELLastAnalyzer.C \
- src/SPELLexecutor.C \
- src/SPELLexecutorImpl.C \
- src/SPELLimportChecker.C \
- src/SPELLexecutorPython.C \
- src/SPELLcallstack.C \
- src/SPELLexecutorUtils.C \
- src/SPELLinterpreter.C \
- src/SPELLgotoPython.C \
- src/SPELLstepPython.C \
- src/SPELLscheduler.C \
- src/SPELLchildManager.C \
- src/SPELLframeManager.C \
- src/SPELLlnotab.C \
- src/SPELLcontroller.C \
- src/SPELLcodeTreeNode.C \
- src/SPELLcodeTreeLine.C \
- src/SPELLexecutorConfiguration.C \
- src/SPELLexecutionModel.C \
- src/SPELLexecutionTrace.C \
- src/SPELLvariableMonitor.C \
- src/SPELLvariableManager.C \
- src/SPELLcommandMailbox.C
-
-
+lib_LTLIBRARIES = libSPELL_EXC_v2.la libSPELL_EXC_v3.la
+
+libSPELL_EXC_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+
+libSPELL_EXC_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_EXC_v2_la_SOURCES = src/SPELLgoto.C \
+ src/SPELLbreakpoint.C \
+ src/SPELLbreakpointType.C \
+ src/SPELLbytecode.C \
+ src/SPELLastAnalyzer.C \
+ src/SPELLexecutor.C \
+ src/SPELLexecutorImpl.C \
+ src/SPELLserviceImpl.C \
+ src/SPELLimportChecker.C \
+ src/SPELLexecutorPython.C \
+ src/SPELLcallstack.C \
+ src/SPELLexecutorUtils.C \
+ src/SPELLinterpreter.C \
+ src/SPELLserviceInterpreter.C \
+ src/SPELLgotoPython.C \
+ src/SPELLstepPython.C \
+ src/SPELLscheduler.C \
+ src/SPELLchildManager.C \
+ src/SPELLframeManager.C \
+ src/SPELLlnotab.C \
+ src/SPELLcontroller.C \
+ src/SPELLcodeTreeNode.C \
+ src/SPELLcodeTreeLine.C \
+ src/SPELLexecutorConfiguration.C \
+ src/SPELLexecutionModel.C \
+ src/SPELLexecutionTrace.C \
+ src/SPELLvariableMonitor.C \
+ src/SPELLvariableManager.C \
+ src/SPELLresourceMonitor.C \
+ src/SPELLresourceManager.C \
+ src/SPELLcommandMailbox.C
+
+
+libSPELL_EXC_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS}
+
+libSPELL_EXC_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_EXC_v3_la_SOURCES = src/SPELLgoto.C \
+ src/SPELLbreakpoint.C \
+ src/SPELLbreakpointType.C \
+ src/SPELLbytecode.C \
+ src/SPELLastAnalyzer.C \
+ src/SPELLexecutor.C \
+ src/SPELLexecutorImpl.C \
+ src/SPELLserviceImpl.C \
+ src/SPELLimportChecker.C \
+ src/SPELLexecutorPython.C \
+ src/SPELLcallstack.C \
+ src/SPELLexecutorUtils.C \
+ src/SPELLinterpreter.C \
+ src/SPELLserviceInterpreter.C \
+ src/SPELLgotoPython.C \
+ src/SPELLstepPython.C \
+ src/SPELLscheduler.C \
+ src/SPELLchildManager.C \
+ src/SPELLframeManager.C \
+ src/SPELLlnotab.C \
+ src/SPELLcontroller.C \
+ src/SPELLcodeTreeNode.C \
+ src/SPELLcodeTreeLine.C \
+ src/SPELLexecutorConfiguration.C \
+ src/SPELLexecutionModel.C \
+ src/SPELLexecutionTrace.C \
+ src/SPELLvariableMonitor.C \
+ src/SPELLvariableManager.C \
+ src/SPELLresourceMonitor.C \
+ src/SPELLresourceManager.C \
+ src/SPELLcommandMailbox.C
+
\ No newline at end of file
diff --git a/lib/SPELL_EXC/src/SPELLastAnalyzer.C b/lib/SPELL_EXC/src/SPELLastAnalyzer.C
index 54dd55a..e00abbc 100644
--- a/lib/SPELL_EXC/src/SPELLastAnalyzer.C
+++ b/lib/SPELL_EXC/src/SPELLastAnalyzer.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the AST analyzer
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -43,6 +43,8 @@
//============================================================================
SPELLastAnalyzer::SPELLastAnalyzer()
{
+ m_lastLineType = NONE;
+ m_openLineNo = 0;
DEBUG("[ASTN] AST analyzer created");
};
diff --git a/lib/SPELL_EXC/src/SPELLbreakpoint.C b/lib/SPELL_EXC/src/SPELLbreakpoint.C
index 6521b82..6227245 100644
--- a/lib/SPELL_EXC/src/SPELLbreakpoint.C
+++ b/lib/SPELL_EXC/src/SPELLbreakpoint.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the breakpoint manager
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_EXC/src/SPELLbreakpointType.C b/lib/SPELL_EXC/src/SPELLbreakpointType.C
index d001050..2997ec8 100644
--- a/lib/SPELL_EXC/src/SPELLbreakpointType.C
+++ b/lib/SPELL_EXC/src/SPELLbreakpointType.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the breakpoint types
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_EXC/src/SPELLbytecode.C b/lib/SPELL_EXC/src/SPELLbytecode.C
index 11cb834..e4afc6c 100644
--- a/lib/SPELL_EXC/src/SPELLbytecode.C
+++ b/lib/SPELL_EXC/src/SPELLbytecode.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the bytecode analyzer
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -36,9 +36,20 @@
// Macros for accessing opcodes
+#if PY_MAJOR_VERSION >= 3
+#define INSTR_OFFSET() \
+ (sizeof(_Py_CODEUNIT) * (int)(next_instr - first_instr))
+#define NEXTOPARG() do { \
+ _Py_CODEUNIT word = *next_instr; \
+ opcode = _Py_OPCODE(word); \
+ oparg = _Py_OPARG(word); \
+ next_instr++; \
+ } while (0)
+#else
#define NEXTOP() (*next_instr++)
#define NEXTARG() (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
#define INSTR_OFFSET() ((int)(next_instr - first_instr))
+#endif
// Debugging macro
#define DUMP DEBUG("[" + ISTR(info->lineno) +\
":" + ISTR(info->offset) + "]: " + OPCODES[info->opcode] \
@@ -225,9 +236,13 @@ void SPELLbytecode::analyze()
{
assert( m_code != NULL );
// Pointer to initial instruction (used by macros)
- unsigned char* first_instr = (unsigned char*) PyString_AS_STRING(m_code->co_code);
+#if PY_MAJOR_VERSION >= 3
+ _Py_CODEUNIT* first_instr = (_Py_CODEUNIT*) PyBytes_AsString(m_code->co_code);
+#else
+ _Py_CODEUNIT* first_instr = (_Py_CODEUNIT*) PyString_AsString(m_code->co_code);
+#endif
// Pointer to current instruction (used by macros)
- register unsigned char* next_instr = first_instr;
+ register _Py_CODEUNIT* next_instr = first_instr;
// Opcode argument
unsigned int oparg;
// Stores the previous line
@@ -235,10 +250,9 @@ void SPELLbytecode::analyze()
// Stores the last opcode
unsigned int prevOpCode = 0;
// Opcode count in line
- unsigned short opcodeCount = 0;
+ unsigned int opcodeCount = 0;
// Will be true when there is no more bytecode to process
- bool finished = false;
unsigned int callDepth = 0;
// Try block structure
TryBlock tb;
@@ -250,8 +264,12 @@ void SPELLbytecode::analyze()
// Holds the bytecode offset for except and finally statements
unsigned int except_offset = 0;
unsigned int finally_offset = 0;
+ // Holds the current opcode
+#if PY_MAJOR_VERSION >= 3
+ unsigned int opcode;
+#endif
- while(not finished)
+ while(true)
{
// Create one BLine info structure per bytecode instruction
BLine info;
@@ -260,7 +278,20 @@ void SPELLbytecode::analyze()
// Get the corresponding script line
info.lineno = PyCode_Addr2Line(m_code, info.offset);
// Obtain the opcode
+
+#if PY_MAJOR_VERSION >= 3
+ NEXTOPARG();
+ info.opcode = opcode;
+
+#else
info.opcode = NEXTOP();
+#endif
+ // Track the end of the code
+ if (info.opcode == 0/*STOP_CODE*/)
+ {
+ m_lastAddr = info.offset;
+ break;
+ }
// Track the number of opcodes per line in the lnotab.
if ((prevLine>0) && (info.lineno != prevLine))
@@ -302,11 +333,11 @@ void SPELLbytecode::analyze()
// We will ignore this, for the moment
+#if PY_MAJOR_VERSION < 3
oparg = 0;
- // To decide wether store the bline information or not
- bool storeit = false;
- if (HAS_ARG(info.opcode)) oparg = NEXTARG();
+ if (HAS_ARG(info.opcode)) oparg = NEXTARG();
+#endif
//////////////////////////////////////////////////////////////////////////////////
// PHASE 2 - BUILD AND STORE NEXT BLINE INFORMATION
//////////////////////////////////////////////////////////////////////////////////
@@ -366,15 +397,12 @@ void SPELLbytecode::analyze()
//////////////////////////////////////////////////////////////////////////////////
switch(info.opcode)
{
- case RETURN_VALUE:
- m_lastAddr = info.offset;
- finished = true;
- break;
case SETUP_EXCEPT:
tb.try_lineno = info.lineno;
except_offset = info.offset + oparg + 3; // This is the real destination offset
break;
case SETUP_FINALLY:
+ tb.try_lineno = info.lineno;
finally_offset = info.offset + oparg + 3; // This is the 'finally' destination offset
break;
case END_FINALLY:
diff --git a/lib/SPELL_EXC/src/SPELLcallstack.C b/lib/SPELL_EXC/src/SPELLcallstack.C
index 3703a47..3daf9e7 100644
--- a/lib/SPELL_EXC/src/SPELLcallstack.C
+++ b/lib/SPELL_EXC/src/SPELLcallstack.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the callstack model
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -89,7 +89,7 @@ void SPELLcallstack::reset()
//=============================================================================
// METHOD : SPELLcallstack::getStack()
//=============================================================================
-const std::string& SPELLcallstack::getStack()
+const std::string SPELLcallstack::getStack()
{
SPELLmonitor mon(m_lock);
@@ -108,7 +108,7 @@ const std::string SPELLcallstack::getFullStack()
//=============================================================================
// METHOD : SPELLcallstack::getCodeName()
//=============================================================================
-const std::string& SPELLcallstack::getCodeName()
+const std::string SPELLcallstack::getCodeName()
{
SPELLmonitor mon(m_lock);
@@ -319,7 +319,8 @@ void SPELLcallstack::callbackEventReturn( PyFrameObject* frame, const std::strin
// When moving the view node, we shall notify the client.
// Do not remove the code on top. Just move the current node pointer.
- m_currentNode = m_currentNode->getParent()->getParentCode();
+ if (m_currentNode->getParent() != NULL)
+ m_currentNode = m_currentNode->getParent()->getParentCode();
// Store current line
m_currentLine = line;
diff --git a/lib/SPELL_EXC/src/SPELLchildManager.C b/lib/SPELL_EXC/src/SPELLchildManager.C
index f5c3882..d3d7e7b 100644
--- a/lib/SPELL_EXC/src/SPELLchildManager.C
+++ b/lib/SPELL_EXC/src/SPELLchildManager.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the child procedure manager
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_EXC/src/SPELLcodeTreeLine.C b/lib/SPELL_EXC/src/SPELLcodeTreeLine.C
index feaa9a5..ed3e4fa 100644
--- a/lib/SPELL_EXC/src/SPELLcodeTreeLine.C
+++ b/lib/SPELL_EXC/src/SPELLcodeTreeLine.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the execution line model
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_EXC/src/SPELLcodeTreeNode.C b/lib/SPELL_EXC/src/SPELLcodeTreeNode.C
index e36a4e8..33dbd55 100644
--- a/lib/SPELL_EXC/src/SPELLcodeTreeNode.C
+++ b/lib/SPELL_EXC/src/SPELLcodeTreeNode.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the execution node model
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_EXC/src/SPELLcommandMailbox.C b/lib/SPELL_EXC/src/SPELLcommandMailbox.C
index 3572171..0048933 100644
--- a/lib/SPELL_EXC/src/SPELLcommandMailbox.C
+++ b/lib/SPELL_EXC/src/SPELLcommandMailbox.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the command mailbox
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_EXC/src/SPELLcontroller.C b/lib/SPELL_EXC/src/SPELLcontroller.C
index c605b89..058faf1 100644
--- a/lib/SPELL_EXC/src/SPELLcontroller.C
+++ b/lib/SPELL_EXC/src/SPELLcontroller.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the executor controller
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -34,6 +34,7 @@
#include "SPELL_WRP/SPELLconstants.H"
#include "SPELL_WRP/SPELLregistry.H"
#include "SPELL_WRP/SPELLdriverManager.H"
+#include "SPELL_WRP/SPELLpyHandle.H"
// Local includes ----------------------------------------------------------
#include "SPELL_EXC/SPELLexecutor.H"
#include "SPELL_EXC/SPELLcontroller.H"
@@ -112,6 +113,15 @@ void SPELLcontroller::command( const ExecutorCommand& cmd, const bool queueIt, c
executeCommand(cmd);
}
}
+void SPELLcontroller::refreshStatus() {
+ LOG_INFO("Procedure status: " + SPELLexecutorUtils::statusToString(m_status));
+ SPELLstatusInfo info(m_status);
+ info.condition = getCondition();
+ info.actionLabel = SPELLexecutor::instance().getUserAction().getLabel();
+ info.actionEnabled = SPELLexecutor::instance().getUserAction().isEnabled();
+
+ SPELLexecutor::instance().getCIF().notifyStatus( info );
+}
//=============================================================================
// METHOD : SPELLcontroller::setStatus
@@ -119,6 +129,19 @@ void SPELLcontroller::command( const ExecutorCommand& cmd, const bool queueIt, c
void SPELLcontroller::setStatus( const SPELLexecutorStatus& st )
{
DEBUG("[C] Attempt to set status " + SPELLexecutorUtils::statusToString(st));
+
+ // Do not allow a status change (this may be manually invoked) in a final status
+ switch(m_status)
+ {
+ case STATUS_FINISHED:
+ case STATUS_ERROR:
+ case STATUS_ABORTED:
+ DEBUG("[C] In final status status " + SPELLexecutorUtils::statusToString(m_status) + " do not change status now. Check code.");
+ return;
+ default:
+ break;
+ }
+
bool newStatus = (st != m_status);
if (newStatus) notifyBeforeStatusChange(m_status);
@@ -311,8 +334,6 @@ void SPELLcontroller::executeCommand( const ExecutorCommand& cmd )
startCommandProcessing();
- notifyCommandToCore( cmd.id );
-
if (cmd.id == CMD_ABORT)
{
doAbort();
@@ -390,10 +411,16 @@ void SPELLcontroller::executeCommand( const ExecutorCommand& cmd )
{
doRecover();
}
+ else if (cmd.id == CMD_RESOURCES)
+ {
+ SPELLexecutor::instance().getResourceManager().callResourceMonitorFromClient( cmd.arg );
+ }
else
{
LOG_ERROR("[C] UNRECOGNISED COMMAND: " + cmd.id);
}
+ notifyCommandToCore( cmd.id );
+
m_mailbox.commandProcessed();
// The command has finished, release the dispatcher
@@ -761,7 +788,11 @@ void SPELLcontroller::doSkip()
/** \todo Should try to go to upper frame instead of stepping.
// This is the issue that obligues us to put a return statement
// at the end of each function. */
- doStep(false);
+ //doStep(false);
+ // For now just send a warning
+ SPELLexecutor::instance().getCIF().warning("Cannot execute 'Skip' on this line. Use 'Step' or 'Goto line number' instead."
+ "(This may happen for 'return' and 'try' block).",
+ LanguageConstants::SCOPE_SYS );
}
}
}
@@ -1234,3 +1265,12 @@ void SPELLcontroller::notifyAfterDriverOperation()
(*it)->callbackAfterDriverOperation();
}
}
+
+
+//=============================================================================
+// METHOD : SPELLscheduler::raiseInformationEventToGCS()
+//=============================================================================
+void SPELLcontroller::raiseInformationEventToGCS( const std::string& message ) {
+ SPELLsafePythonOperations ops("SPELLcontroller::raiseInformationEventToGCS()");
+ raiseEvent(message);
+}
\ No newline at end of file
diff --git a/lib/SPELL_EXC/src/SPELLexecutionModel.C b/lib/SPELL_EXC/src/SPELLexecutionModel.C
index 07fdcaf..7c1c345 100644
--- a/lib/SPELL_EXC/src/SPELLexecutionModel.C
+++ b/lib/SPELL_EXC/src/SPELLexecutionModel.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the execution model
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_EXC/src/SPELLexecutionTrace.C b/lib/SPELL_EXC/src/SPELLexecutionTrace.C
index c184a45..1c36fb4 100644
--- a/lib/SPELL_EXC/src/SPELLexecutionTrace.C
+++ b/lib/SPELL_EXC/src/SPELLexecutionTrace.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the execution trace model
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_EXC/src/SPELLexecutor.C b/lib/SPELL_EXC/src/SPELLexecutor.C
index 92ff4d9..d345e34 100644
--- a/lib/SPELL_EXC/src/SPELLexecutor.C
+++ b/lib/SPELL_EXC/src/SPELLexecutor.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the executor singleton access
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_EXC/src/SPELLexecutorConfiguration.C b/lib/SPELL_EXC/src/SPELLexecutorConfiguration.C
index 0d165b0..58c14ff 100644
--- a/lib/SPELL_EXC/src/SPELLexecutorConfiguration.C
+++ b/lib/SPELL_EXC/src/SPELLexecutorConfiguration.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the executor configuration
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -70,7 +70,10 @@ SPELLexecutorConfig::SPELLexecutorConfig( const SPELLexecutorConfig& refConfig )
m_blocking = refConfig.isBlocking();
m_saveStateMode = refConfig.getSaveStateMode();
m_watchVariables = refConfig.isWatchEnabled();
+ m_resourcesDisplay = refConfig.isResourcesDisplayEnabled();
+ m_localResourceSupport = refConfig.isLocalResourcesSupported();
m_forceTcConfirm = refConfig.isForceTcConfirm();
+ m_forcePromptConfirm = refConfig.isForcePromptConfirm();
m_controlClient = refConfig.getControlClient();
m_controlHost = refConfig.getControlHost();
m_headless = refConfig.isHeadless();
@@ -97,7 +100,10 @@ SPELLexecutorConfig& SPELLexecutorConfig::operator=( SPELLexecutorConfig& refCon
m_blocking = refConfig.isBlocking();
m_saveStateMode = refConfig.getSaveStateMode();
m_watchVariables = refConfig.isWatchEnabled();
+ m_resourcesDisplay = refConfig.isResourcesDisplayEnabled();
+ m_localResourceSupport = refConfig.isLocalResourcesSupported();
m_forceTcConfirm = refConfig.isForceTcConfirm();
+ m_forcePromptConfirm = refConfig.isForcePromptConfirm();
m_controlClient = refConfig.getControlClient();
m_controlHost = refConfig.getControlHost();
m_headless = refConfig.isHeadless();
@@ -129,7 +135,10 @@ void SPELLexecutorConfig::reset()
m_runInto = true;
m_watchVariables = false;
+ m_resourcesDisplay = false;
+ m_localResourceSupport = false;
m_forceTcConfirm = false;
+ m_forcePromptConfirm = false;
m_controlClient = "";
m_controlHost = "";
m_contextName = "";
diff --git a/lib/SPELL_EXC/src/SPELLexecutorImpl.C b/lib/SPELL_EXC/src/SPELLexecutorImpl.C
index 3bf29fc..580ec4b 100644
--- a/lib/SPELL_EXC/src/SPELLexecutorImpl.C
+++ b/lib/SPELL_EXC/src/SPELLexecutorImpl.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the executor
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -29,6 +29,7 @@
// Local includes ----------------------------------------------------------
#include "SPELL_EXC/SPELLexecutor.H"
#include "SPELL_EXC/SPELLexecutorImpl.H"
+#include "SPELL_EXC/SPELLexecutorUtils.H"
// Project includes --------------------------------------------------------
#include "SPELL_PRD/SPELLprocedureManager.H"
#include "SPELL_SYN/SPELLmonitor.H"
@@ -54,8 +55,6 @@ static int static_dispatch( PyObject* obj, PyFrameObject* frame, int what, PyObj
return SPELLexecutor::instance().dispatch(obj, frame, what, args);
}
-static SPELLexecutorConfig EMPTY_CONFIGURATION;
-
//=============================================================================
// FUNCTION: convert dispatch data type to string
//=============================================================================
@@ -104,6 +103,7 @@ SPELLexecutorImpl::SPELLexecutorImpl()
m_controller = NULL;
m_childMgr = NULL;
m_varManager = NULL;
+ m_resourceManager = NULL;
m_userAction.reset();
m_gotoTarget = "";
@@ -129,6 +129,15 @@ SPELLexecutorImpl::~SPELLexecutorImpl()
//=============================================================================
// METHOD : SPELLexecutorImpl::initialize()
//=============================================================================
+
+void SPELLexecutorImpl::refreshStatus()
+{
+ if (m_controller != NULL)
+ {
+ m_controller->refreshStatus();
+ }
+}
+
void SPELLexecutorImpl::initialize( SPELLcif* cif,
SPELLcontrollerIF* controller,
SPELLschedulerIF* scheduler,
@@ -146,6 +155,7 @@ void SPELLexecutorImpl::initialize( SPELLcif* cif,
m_callstack = callstack;
m_frameManager = frame;
m_varManager = new SPELLvariableManager(*frame);
+ m_resourceManager = new SPELLresourceManager(*frame);
// The order is important here!
addDispatchListener(m_frameManager);
@@ -156,13 +166,13 @@ void SPELLexecutorImpl::initialize( SPELLcif* cif,
//=============================================================================
// METHOD : SPELLexecutorImpl::getConfiguration()
//=============================================================================
-SPELLexecutorConfig& SPELLexecutorImpl::getConfiguration() const
+SPELLexecutorConfig& SPELLexecutorImpl::getConfiguration()
{
if (m_cif != NULL)
{
return m_cif->getExecutorConfig();
}
- return EMPTY_CONFIGURATION;
+ return m_emptyConfig;
};
//=============================================================================
@@ -223,8 +233,11 @@ void SPELLexecutorImpl::prepare( const std::string& instanceId, const SPELLconte
LOG_INFO("[E] Blocking mode : " + BSTR( getConfiguration().isBlocking() ));
LOG_INFO("[E] Browsable lib : " + getConfiguration().getBrowsableLibStr() );
LOG_INFO("[E] TC Confirm : " + BSTR( getConfiguration().isForceTcConfirm() ));
+ LOG_INFO("[E] Prompt Confirm : " + BSTR( getConfiguration().isForcePromptConfirm() ));
LOG_INFO("[E] Save state mode : " + getConfiguration().getSaveStateMode() );
LOG_INFO("[E] Watch variables : " + BSTR(getConfiguration().isWatchEnabled()) );
+ LOG_INFO("[E] Resources Display: " + BSTR(getConfiguration().isResourcesDisplayEnabled()) );
+ LOG_INFO("[E] Local resources support: " + BSTR(getConfiguration().isLocalResourcesSupported()) );
LOG_INFO("[E] Input directory : " + m_inputDir );
LOG_INFO("[E] Output directory : " + m_outputDir );
LOG_INFO("[E] Run Into : " + BSTR(getConfiguration().isRunInto()));
@@ -306,7 +319,7 @@ void SPELLexecutorImpl::installCallingArguments()
// Initialize now the data container for Calling Arguments
Py_INCREF(argDict);
DEBUG("[E] Argument dictionary: " + PYREPR(argDict));
- PyObject* classObj = SPELLpythonHelper::instance().getObject("libSPELL_DTA", "DataContainer");
+ PyObject* classObj = SPELLpythonHelper::instance().getObject(MOD_NAME(libSPELL_DTA), "DataContainer");
PyObject* argTuple = PyTuple_New(1);
PyObject* argsName = STRPY("Calling Arguments");
PyTuple_SetItem(argTuple,0,argsName);
@@ -341,7 +354,7 @@ void SPELLexecutorImpl::installCallingArguments()
//=============================================================================
void SPELLexecutorImpl::installInternalVariables()
{
- PyObject* classObj = SPELLpythonHelper::instance().getObject("libSPELL_DTA", "DataContainer");
+ PyObject* classObj = SPELLpythonHelper::instance().getObject(MOD_NAME(libSPELL_DTA), "DataContainer");
PyObject* argTuple = PyTuple_New(1);
PyObject* argsName = STRPY("Internal Variables");
PyTuple_SetItem(argTuple,0,argsName);
@@ -403,22 +416,34 @@ void SPELLexecutorImpl::executeInternal( bool doReset )
m_controller->enableRunInto( getConfiguration().isRunInto() );
// The client will know that the executor is ready to go
- m_controller->setStatus(STATUS_LOADED);
+ // Take into account initialization errors
+ SPELLexecutorStatus status = m_controller->getStatus();
+ LOG_INFO("Initial status check: " + SPELLexecutorUtils::statusToString(status) );
+ SPELLexecutionResult result = EXECUTION_UNKNOWN;
+ if (status != STATUS_ERROR)
+ {
+ m_controller->setStatus(STATUS_LOADED);
- // If in automatic and backgorund mode, set the controller in play mode accordingly
- // IMPORTANT If in automatic and foreground mode, it is the GUI who sends the run command
- if ( getConfiguration().isHeadless() || (getConfiguration().isAutomatic() && (!getConfiguration().isVisible()) ) )
- {
- DEBUG("[E] Set autorun");
- m_controller->setAutoRun();
- }
+ // If in automatic and backgorund mode, set the controller in play mode accordingly
+ // IMPORTANT If in automatic and foreground mode, it is the GUI who sends the run command
+ if ( getConfiguration().isHeadless() || (getConfiguration().isAutomatic() && (!getConfiguration().isVisible()) ) )
+ {
+ DEBUG("[E] Set autorun");
+ m_controller->setAutoRun();
+ }
- DEBUG("[E] Launching execution");
- // Execute the procedure/script. This triggers the procedure
- // execution under dispatcher control.
- SPELLexecutionResult result = m_frameManager->execute();
+ DEBUG("[E] Launching execution");
+ // Execute the procedure/script. This triggers the procedure
+ // execution under dispatcher control.
+ result = m_frameManager->execute();
- DEBUG("[E] Execution done, checking result (" + ISTR(result) + ")");
+ DEBUG("[E] Execution done, checking result (" + ISTR(result) + ")");
+ }
+ else
+ {
+ LOG_ERROR("Initialization error");
+ result = EXECUTION_ERROR;
+ }
// Check execution result and proceed accordingly.
// Frame will be reset and environment unloaded if needed, depending on the case.
@@ -669,9 +694,6 @@ void SPELLexecutorImpl::loadExecutionEnvironment()
// Check for Python errors
SPELLpythonHelper::instance().checkError();
- // Load SCDB and GDB
- SPELLdatabaseManager::instance().loadBuiltinDatabases();
-
// Create proc dictionary object and install it
PyObject* procObj = PyDict_New();
PyObject* pname = SSTRPY(m_instanceId);
@@ -689,10 +711,48 @@ void SPELLexecutorImpl::loadExecutionEnvironment()
PyDict_SetItemString( procObj, DatabaseConstants::PARENT.c_str(), parentId);
SPELLpythonHelper::instance().install( procObj, DatabaseConstants::PROC );
+ SPELLpythonHelper::instance().checkError();
- SPELLpythonHelper::instance().importUserLibraries( m_libPath );
-
+ // Load SCDB and GDB
+ SPELLdatabaseManager::instance().loadBuiltinDatabases();
SPELLpythonHelper::instance().checkError();
+
+ bool success = true;
+ std::string importErrors = "";
+
+ if (m_libPath != "")
+ {
+ if (m_libPath.find(",") != std::string::npos)
+ {
+ std::vector items = SPELLutils::tokenize(m_libPath,",");
+ std::vector::const_iterator cit;
+ for(cit = items.begin(); cit != items.end(); cit++)
+ {
+ success = SPELLpythonHelper::instance().importUserLibraries( *cit, importErrors ) && success;
+ }
+ }
+ else
+ {
+ try
+ {
+ success = SPELLpythonHelper::instance().importUserLibraries( m_libPath, importErrors ) && success;
+ }
+ catch(SPELLcoreException& ex)
+ {
+ importErrors += "\n - Failed to import user libraries from '" + m_libPath + "': " + ex.what();
+ }
+ }
+ }
+ else
+ {
+ LOG_INFO("No user libraries defined");
+ }
+
+
+ if (!success)
+ {
+ LOG_ERROR("Errors detected in UserLib: " + importErrors);
+ }
// Tell the execution frame that the environment has been updated
m_frameManager->filterDictUpdated();
@@ -723,6 +783,11 @@ void SPELLexecutorImpl::loadDriver()
setForceTcConfirmInternal(true);
}
+ if (getConfiguration().isForcePromptConfirm())
+ {
+ setForcePromptConfirmInternal(true);
+ }
+
// Load the driver language specifics
SPELLcontextConfig& ctxConfig = SPELLconfiguration::instance().getContext( getConfiguration().getContextName() );
std::string driverName = ctxConfig.getDriverName();
@@ -1068,6 +1133,9 @@ int SPELLexecutorImpl::dispatch( PyObject* obj, PyFrameObject* frame, int what,
if(!m_controller->checkAborted())
{
m_frameManager->terminate();
+ if (what == PyTrace_EXCEPTION)
+ // We haven't raised an exception in case we trace an exception therefore return 0 (no error)
+ return 0;
return -1;
}
@@ -1198,6 +1266,18 @@ void SPELLexecutorImpl::setForceTcConfirm( const bool force )
}
}
+//=============================================================================
+// METHOD : SPELLexecutorImpl::setForceTcConfirm
+//=============================================================================
+void SPELLexecutorImpl::setForcePromptConfirm( const bool force )
+{
+ if (getConfiguration().isForcePromptConfirm() != force )
+ {
+ LOG_INFO("[EXEC] Set force Prompt confirmation to " + BSTR(force));
+ getConfiguration().setForcePromptConfirm(force);
+ setForcePromptConfirmInternal(force);
+ }
+}
//=============================================================================
// METHOD : SPELLexecutorImpl::command
//=============================================================================
@@ -1210,7 +1290,18 @@ void SPELLexecutorImpl::setForceTcConfirmInternal( bool force )
SPELLpythonHelper::instance().callMethod( tc, "forceTcConfirm", arg, NULL );
}
}
-
+//=============================================================================
+// METHOD : SPELLexecutorImpl::command
+//=============================================================================
+void SPELLexecutorImpl::setForcePromptConfirmInternal( bool force )
+{
+ PyObject* tc = SPELLregistry::instance().get("CIF");
+ if (tc != NULL)
+ {
+ PyObject* arg = force ? Py_True : Py_False;
+ SPELLpythonHelper::instance().callMethod( tc, "forcePromptConfirm", arg, NULL );
+ }
+}
//=============================================================================
// METHOD : SPELLexecutorImpl::command
//=============================================================================
@@ -1292,7 +1383,8 @@ void SPELLexecutorImpl::finish( const std::string& message )
//=============================================================================
void SPELLexecutorImpl::processLock()
{
- SPELLmonitor m(m_cmdLock);
+ // TODO: No reason to lock here. Remove once validated.
+ //SPELLmonitor m(m_cmdLock);
m_controller->executionLock();
}
@@ -1301,7 +1393,8 @@ void SPELLexecutorImpl::processLock()
//=============================================================================
void SPELLexecutorImpl::processUnlock()
{
- SPELLmonitor m(m_cmdLock);
+ // TODO: No reason to lock here. Remove once validated.
+ //SPELLmonitor m(m_cmdLock);
m_controller->executionUnlock();
}
@@ -1568,9 +1661,13 @@ void SPELLexecutorImpl::displayStage( const std::string& id, const std::string&
Py_INCREF(pyId);
Py_INCREF(pyDesc);
+ // Get the previous step value if any
+ PyObject* prev = PyDict_GetItemString(proc, DatabaseConstants::STEP.c_str());
+
+ // Set the new value
PyDict_SetItemString( proc, DatabaseConstants::STEP.c_str(), list);
- PyObject* prev = PyDict_GetItemString(proc, DatabaseConstants::STEP.c_str());
+ // If there was a previous value, set it as PREVIOUS
if (prev != NULL)
{
PyDict_SetItemString( proc, DatabaseConstants::PREV_STEP.c_str(), prev);
diff --git a/lib/SPELL_EXC/src/SPELLexecutorPython.C b/lib/SPELL_EXC/src/SPELLexecutorPython.C
index d243498..84e04c2 100644
--- a/lib/SPELL_EXC/src/SPELLexecutorPython.C
+++ b/lib/SPELL_EXC/src/SPELLexecutorPython.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the executor Python bindings
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -179,6 +179,17 @@ static PyObject* Executor_DisableUserAction( PyObject* self, PyObject* args );
// DESCRIPTION : set current step id and description
//============================================================================
static PyObject* Executor_SetStep( PyObject* self, PyObject* args );
+
+//============================================================================
+// FUNCTION : Executor_SetByStep
+//============================================================================
+static PyObject* Executor_SetByStep( PyObject* self, PyObject* args );
+
+//============================================================================
+// FUNCTION : Executor_SetExecutionDelay
+//============================================================================
+static PyObject* Executor_GetByStep( PyObject* self, PyObject* args );
+
//============================================================================
// FUNCTION : Executor_Notify
// DESCRIPTION : Notify arbitrary data
@@ -232,8 +243,10 @@ static PyMethodDef Executor_Methods[] =
{"dismissUserAction", Executor_DismissUserAction, METH_NOARGS, "Unset the user action function"},
{"enableUserAction", Executor_EnableUserAction, METH_NOARGS, "Enable the user action function"},
{"disableUserAction", Executor_DisableUserAction, METH_NOARGS, "Disable the user action function"},
- {"setStep" , Executor_SetStep, METH_VARARGS, "Set current step name"},
- {"setExecutionDelay", Executor_SetExecutionDelay, METH_VARARGS, "Set execution delay"},
+ {"setStep" , Executor_SetStep, METH_VARARGS, "Set current step name"},
+ {"setByStep" , Executor_SetByStep, METH_VARARGS, "Set the ByStep configuration"},
+ {"getByStep" , Executor_GetByStep, METH_NOARGS, "Get the ByStep configuration"},
+ {"setExecutionDelay", Executor_SetExecutionDelay, METH_VARARGS, "Set execution delay"},
{"notify", Executor_Notify, METH_VARARGS, "Notify items"},
{"getControllingHost", Executor_GetControllingHost, METH_NOARGS, "Get the controlling host"},
{NULL, NULL, 0, NULL} /* Sentinel */
@@ -244,8 +257,7 @@ static PyMethodDef Executor_Methods[] =
//============================================================================
static PyTypeObject Executor_Type =
{
- PyObject_HEAD_INIT(NULL)
- 0, //ob_size
+ PyVarObject_HEAD_INIT(NULL,0)
"executor.Executor", //tp_name
sizeof(PyExecutorObject), //tp_basicsize
0, //tp_itemsize
@@ -298,7 +310,7 @@ static int Executor_Init( PyExecutorObject* self, PyObject* args, PyObject* kwds
//============================================================================
static void Executor_Dealloc( PyExecutorObject* self )
{
- self->ob_type->tp_free( (PyObject*) self );
+ Py_TYPE(self)->tp_free( (PyObject*) self );
}
//============================================================================
@@ -725,7 +737,11 @@ static PyObject* Executor_SetUserAction( PyObject* self, PyObject* args )
DEBUG("[EXECPY] Set user action");
PyObject* funcObj = PyTuple_GetItem(args,0);
std::string label = PYSTR(PyTuple_GetItem(args, 1));
+#if PY_MAJOR_VERSION >= 3
+ std::string funcName = PYSTR( ((PyFunctionObject*)funcObj)->func_name );
+#else
std::string funcName = PYSTR( PyObject_GetAttrString( funcObj, "func_name" ) );
+#endif
PyObject* configObj = PyTuple_GetItem(args,2);
unsigned int severity = LanguageConstants::INFORMATION;
SPELLpyHandle pySev = SSTRPY(LanguageModifiers::Severity);
@@ -808,7 +824,7 @@ static PyObject* Executor_SetStep( PyObject* self, PyObject* args )
PyObject* idObj = PyTuple_GetItem(args,0);
PyObject* descObj = PyTuple_GetItem(args,1);
- SPELLexecutor::instance().displayStage( PYSSTR(idObj), PYSSTR(descObj) );
+ SPELLexecutor::instance().stageReached( PYSSTR(idObj), PYSSTR(descObj) );
Py_RETURN_NONE;
}
@@ -835,6 +851,34 @@ static PyObject* Executor_SetExecutionDelay( PyObject* self, PyObject* args )
Py_RETURN_NONE;
}
+//============================================================================
+// FUNCTION : Executor_SetByStep
+//============================================================================
+static PyObject* Executor_SetByStep( PyObject* self, PyObject* args )
+{
+ DEBUG("[EXECPY] Set ByStep configuration");
+
+ PyObject* byStep = PyTuple_GetItem(args,0);
+ SPELLexecutor::instance().setByStep(PyObject_IsTrue(byStep));
+
+ Py_RETURN_NONE;
+}
+
+//============================================================================
+// FUNCTION : Executor_SetExecutionDelay
+//============================================================================
+static PyObject* Executor_GetByStep( PyObject* self, PyObject* args )
+{
+ DEBUG("[EXECPY] Get ByStep configuration");
+
+ if (SPELLexecutor::instance().getConfiguration().isByStep()){
+ Py_RETURN_TRUE;
+ } else {
+ Py_RETURN_FALSE;
+ }
+
+}
+
//============================================================================
// FUNCTION : Executor_GetControllingHost
//============================================================================
diff --git a/lib/SPELL_EXC/src/SPELLexecutorUtils.C b/lib/SPELL_EXC/src/SPELLexecutorUtils.C
index 7d401df..0fc863b 100644
--- a/lib/SPELL_EXC/src/SPELLexecutorUtils.C
+++ b/lib/SPELL_EXC/src/SPELLexecutorUtils.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the executor utilities
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_EXC/src/SPELLframeManager.C b/lib/SPELL_EXC/src/SPELLframeManager.C
index c92a60a..a29c5e8 100644
--- a/lib/SPELL_EXC/src/SPELLframeManager.C
+++ b/lib/SPELL_EXC/src/SPELLframeManager.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the Python frame manager
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -46,6 +46,7 @@
//=============================================================================
SPELLframeManager::SPELLframeManager()
: SPELLdispatchListener(),
+ m_resourceMonitor(new SPELLresourceChangeListener()),
m_modelMap()
{
m_warmStart = NULL;
@@ -56,6 +57,8 @@ SPELLframeManager::SPELLframeManager()
m_model = NULL;
m_filename = "";
m_definitions = NULL;
+ m_inError = false;
+ m_terminated = false;
}
//=============================================================================
@@ -88,6 +91,7 @@ void SPELLframeManager::initialize( const std::string& scriptFile )
// Enable or disable monitoring according to configuration
SPELLvariableMonitor::s_enabled = SPELLexecutor::instance().getConfiguration().isWatchEnabled();
+ SPELLresourceMonitor::s_enabled = SPELLexecutor::instance().getConfiguration().isResourcesDisplayEnabled();
// Compile the script and create the Python frame
// to execute bytecode
@@ -242,8 +246,8 @@ void SPELLframeManager::createInitialFrame()
Py_XDECREF(m_currentFrame);
m_currentFrame = NULL;
}
-
- updateCurrentFrame( m_initialFrame, true );
+ m_currentFrame = m_initialFrame;
+ //updateCurrentFrame( m_initialFrame, true );
DEBUG("[EF] Initial frame ready");
}
@@ -305,7 +309,7 @@ void SPELLframeManager::terminate()
if (!m_terminated)
{
DEBUG("[EF] Terminating execution");
- SPELLpythonHelper::instance().acquireGIL();
+ SPELLsafePythonOperations ops("SPELLframeManager::terminate");
// Note: we substract 3 bytes since the last two instructions are always
// resembling a "return None" statement. We want the instruction previous
// to the last one here.
@@ -316,9 +320,16 @@ void SPELLframeManager::terminate()
int lasti = it->second->getLastAddress() -3 ;
int lineno = it->second->getLastLine();
DEBUG("[EF] Setting lasti " + ISTR(lasti) + " lineno " + ISTR(lineno) + " on " + PYCREPR(frame));
- SPELLpythonHelper::instance().setNewLine(frame,lineno,lasti);
- DEBUG("Frame stack top " + PSTR(frame->f_stacktop));
- DEBUG("Frame value stack " + PSTR(frame->f_valuestack));
+ try
+ {
+ SPELLpythonHelper::instance().setNewLine(frame,lineno,lasti);
+ DEBUG("Frame stack top " + PSTR(frame->f_stacktop));
+ DEBUG("Frame value stack " + PSTR(frame->f_valuestack));
+ }
+ catch(SPELLcoreException& ex)
+ {
+ LOG_ERROR("Unable to set lasti in frame " + PYCREPR(frame));
+ }
}
m_terminated = true;
DEBUG("[EF] Terminating execution finished");
@@ -338,6 +349,7 @@ const SPELLexecutionResult SPELLframeManager::execute()
while(frame!= NULL)
{
DEBUG("[EF] Running frame " + PYCREPR(frame));
+ SPELLpythonHelper::instance().checkError();
PyEval_EvalFrame( frame );
DEBUG("[EF] Frame finished " + PYCREPR(frame));
DEBUG("[EF] Next frame " + PYCREPR(frame));
@@ -543,7 +555,14 @@ const bool SPELLframeManager::goNextLine()
else
{
DEBUG("[F] Go next line " + ISTR(new_lineno) + " at " + ISTR(new_lasti));
- controllerContinue = setNewLine( new_lineno, new_lasti );
+ try
+ {
+ controllerContinue = setNewLine( new_lineno, new_lasti );
+ }
+ catch (SPELLcoreException& ex)
+ {
+ controllerContinue = false;
+ }
}
}
@@ -586,7 +605,24 @@ const bool SPELLframeManager::goLine( const int& new_lineno, bool report )
{
SPELLsafePythonOperations ops("SPELLframeManager::goLine()");
DEBUG("[F] Go-to line " + ISTR(new_lineno) + " on model " + PSTR(m_model));
+#if PY_MAJOR_VERSION >= 3
+ bool result = false;
+ try
+ {
+ result = setNewLine( new_lineno, 0 );
+ DEBUG("[F] Go new line " + ISTR(new_lineno));
+ if (report)
+ {
+ SPELLexecutor::instance().getCIF().write("Jump to line " + ISTR(new_lineno), LanguageConstants::SCOPE_SYS );
+ }
+ }
+ catch(SPELLcoreException& ex)
+ {
+ SPELLexecutor::instance().getCIF().warning("Unable to go to line " + ISTR(new_lineno) + ", " + ex.what(), LanguageConstants::SCOPE_SYS );
+ }
+ return result;
+#else
// We cannot jump in the middle of a block
if (m_ast.isInsideBlock(new_lineno))
{
@@ -610,7 +646,7 @@ const bool SPELLframeManager::goLine( const int& new_lineno, bool report )
}
// We cannot jump inside blocks
- bool inTry = getModel().isInTryBlock(new_lineno);
+ /*bool inTry = getModel().isInTryBlock(new_lineno);
bool inExc = getModel().isInExceptBlock(new_lineno);
bool inFin = getModel().isInFinallyBlock(new_lineno);
if (inTry | inExc | inFin )
@@ -621,7 +657,7 @@ const bool SPELLframeManager::goLine( const int& new_lineno, bool report )
SPELLexecutor::instance().getCIF().warning("Unable to go to line " + ISTR(new_lineno), LanguageConstants::SCOPE_SYS );
}
return false;
- }
+ }*/
int new_lasti = getModel().offset(new_lineno);
if ( new_lasti == -1 )
@@ -650,6 +686,7 @@ const bool SPELLframeManager::goLine( const int& new_lineno, bool report )
}
return result;
+#endif
}
//=============================================================================
@@ -690,6 +727,8 @@ void SPELLframeManager::runScript( const std::string& script )
SPELLpythonHelper::instance().checkError();
// See model update its information
getModel().update();
+ // Disable local resource analyze due to performance loss
+ //getResourceMonitor().analyze();
DEBUG("[EF] Executing script OUT");
}
catch (SPELLcoreException& ex)
@@ -769,8 +808,10 @@ void SPELLframeManager::callbackEventLine( PyFrameObject* frame, const std::stri
m_warmStart->notifyLine();
}
}
- // See model update its information (including variable monitor if enabled)
+ // See model update its information (including variable/resource monitor if enabled)
getModel().update();
+ // Disable local resource analyze due to performance loss
+ //getResourceMonitor().analyze();
DEBUG("[EF] Reset error mode");
m_inError = false;
@@ -964,12 +1005,13 @@ void SPELLframeManager::copyDatabase( const std::string& database, PyFrameObject
if (db == NULL)
{
// New reference
- db = SPELLpythonHelper::instance().getObject("__main__", database);
+ db = SPELLpythonHelper::instance().getObject(BUILTINS, database);
}
if (db)
{
DEBUG("[EF] Copy database now");
Py_INCREF(db);
+ Py_INCREF(db);
PyDict_SetItemString(toFrame->f_globals, database.c_str(), db);
PyDict_SetItemString(toFrame->f_locals, database.c_str(), db);
}
@@ -977,6 +1019,7 @@ void SPELLframeManager::copyDatabase( const std::string& database, PyFrameObject
{
LOG_ERROR("Unable to copy database reference: " + database + " on " + PYCREPR(toFrame));
}
+ SPELLpythonHelper::instance().checkError();
}
//=============================================================================
@@ -1086,6 +1129,8 @@ void SPELLframeManager::createFrameModel( int callLine, PyFrameObject* frame )
// Initialize the variable monitor
m_model->getVariableMonitor().initialize();
+ // Initialize the resource monitor
+ getResourceMonitor().initialize();
m_modelMap.insert( std::make_pair( code_id, m_model ));
diff --git a/lib/SPELL_EXC/src/SPELLgoto.C b/lib/SPELL_EXC/src/SPELLgoto.C
index 19ef47a..7c0fae9 100644
--- a/lib/SPELL_EXC/src/SPELLgoto.C
+++ b/lib/SPELL_EXC/src/SPELLgoto.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the goto mechanism
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -35,10 +35,21 @@
// Macros for accessing opcodes
+#if PY_MAJOR_VERSION >= 3
+#define INSTR_OFFSET() \
+ (sizeof(_Py_CODEUNIT) * (int)(next_instr - first_instr))
+#define NEXTOPARG() do { \
+ _Py_CODEUNIT word = *next_instr; \
+ opcode = _Py_OPCODE(word); \
+ oparg = _Py_OPARG(word); \
+ next_instr++; \
+ } while (0)
+
+#else
#define NEXTOP() (*next_instr++)
#define NEXTARG() (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
#define INSTR_OFFSET() ((int)(next_instr - first_instr))
-
+#endif
static const std::string STEP_CALL("Step");
static const std::string GOTO_CALL("Goto");
@@ -84,19 +95,25 @@ void SPELLgoto::analyze()
// Assume there is no INIT step
m_initLine = -1;
// Pointer to initial instruction (used by macros)
- unsigned char* first_instr = (unsigned char*) PyString_AS_STRING(m_code->co_code);
+#if PY_MAJOR_VERSION >= 3
+ _Py_CODEUNIT* first_instr = (_Py_CODEUNIT*) PyBytes_AsString(m_code->co_code);
+ // Size of the code to analyze
+ const unsigned int code_size = PyBytes_Size(m_code->co_code);
+#else
+ _Py_CODEUNIT* first_instr = (_Py_CODEUNIT*) PyString_AsString(m_code->co_code);
// Size of the code to analyze
const unsigned int code_size = PyString_Size(m_code->co_code);
+#endif
// Pointer to current instruction (used by macros)
- register unsigned char* next_instr = first_instr;
+ register _Py_CODEUNIT* next_instr = first_instr;
// Holds the current line
unsigned int lineno;
// Holds the current instruction offset
register unsigned int offset;
// Holds the current opcode
- register unsigned int opcode;
+ register int opcode;
// Opcode argument
- register unsigned int oparg;
+ register int oparg;
// Holds the last loaded name
std::string loaded_name,loaded_const = "";
@@ -105,22 +122,38 @@ void SPELLgoto::analyze()
// Hold the goto information
std::string step_id,step_title,goto_id = "";
register unsigned short const1 = 1;
-
+#if PY_MAJOR_VERSION >= 3
+ int extendedArg = 0;
+#endif
offset = INSTR_OFFSET();
while (offset < code_size)
{
+#if PY_MAJOR_VERSION >= 3
+ NEXTOPARG();
+#else
// Obtain the opcode
opcode = NEXTOP();
// Get the opcode argument
oparg = 0;
if (HAS_ARG(opcode)) oparg = NEXTARG();
-
+#endif
switch(opcode)
{
+#if PY_MAJOR_VERSION >= 3
+ case EXTENDED_ARG:
+ {
+ extendedArg = (extendedArg << 8) + oparg;
+ break;
+ }
+#endif
case LOAD_NAME:
case LOAD_GLOBAL:
{
+#if PY_MAJOR_VERSION >= 3
+ oparg = oparg + (extendedArg << 8);
+ extendedArg = 0;
+#endif
loaded_name = PYSTR(PyTuple_GetItem(m_code->co_names,oparg));
if (loaded_name == STEP_CALL)
{
@@ -138,6 +171,10 @@ void SPELLgoto::analyze()
}
case LOAD_CONST:
{
+#if PY_MAJOR_VERSION >= 3
+ oparg = oparg + (extendedArg << 8);
+ extendedArg = 0;
+#endif
PyObject* pyConst = PyTuple_GetItem(m_code->co_consts,oparg);
if (pyConst != Py_None)
{
@@ -162,7 +199,10 @@ void SPELLgoto::analyze()
}
case CALL_FUNCTION:
{
- if (loaded_name == STEP_CALL)
+#if PY_MAJOR_VERSION >= 3
+ extendedArg = 0;
+#endif
+ if (loaded_name == STEP_CALL)
{
// Get the corresponding script line
lineno = PyCode_Addr2Line(m_code, offset);
@@ -186,6 +226,13 @@ void SPELLgoto::analyze()
const1 = 1;
break;
}
+ default:
+ {
+#if PY_MAJOR_VERSION >= 3
+ extendedArg = 0;
+#endif
+ break;
+ }
}// End switch
// // Inform about errors, but ignore them at this analysis
diff --git a/lib/SPELL_EXC/src/SPELLgotoPython.C b/lib/SPELL_EXC/src/SPELLgotoPython.C
index 0ca7caf..eae7813 100644
--- a/lib/SPELL_EXC/src/SPELLgotoPython.C
+++ b/lib/SPELL_EXC/src/SPELLgotoPython.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the goto Python bindings
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -80,8 +80,7 @@ static PyMethodDef Goto_Methods[] =
//============================================================================
static PyTypeObject Goto_Type =
{
- PyObject_HEAD_INIT(NULL)
- 0, //ob_size
+ PyVarObject_HEAD_INIT(NULL,0)
"executor.Goto", //tp_name
sizeof(PyGotoObject), //tp_basicsize
0, //tp_itemsize
@@ -135,7 +134,7 @@ static int Goto_Init( PyGotoObject* self, PyObject* args, PyObject* kwds )
//============================================================================
static void Goto_Dealloc( PyGotoObject* self )
{
- self->ob_type->tp_free( (PyObject*) self );
+ Py_TYPE(self)->tp_free( (PyObject*) self );
}
//============================================================================
diff --git a/lib/SPELL_EXC/src/SPELLimportChecker.C b/lib/SPELL_EXC/src/SPELLimportChecker.C
index 04cdb52..7f8c5ee 100644
--- a/lib/SPELL_EXC/src/SPELLimportChecker.C
+++ b/lib/SPELL_EXC/src/SPELLimportChecker.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the import detector
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_EXC/src/SPELLinterpreter.C b/lib/SPELL_EXC/src/SPELLinterpreter.C
index 27d4d36..d7f5408 100644
--- a/lib/SPELL_EXC/src/SPELLinterpreter.C
+++ b/lib/SPELL_EXC/src/SPELLinterpreter.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the custom interpreter
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -161,6 +161,7 @@ void SPELLinterpreter::mainLoop()
// Create and connect all execution control objects
if (prepareObjects())
{
+ SPELLsafePythonOperations ops("Executor execute");
// Now try to initialize (compile) the execution frame.
if (prepareExecution())
{
@@ -346,7 +347,7 @@ const bool SPELLinterpreter::prepareObjects()
{
DEBUG(" Initializing Python interface");
SPELLpythonHelper::instance().initialize();
-
+ SPELLsafePythonOperations ops("Executor Init");
// Install log support asap
Log_Install();
@@ -377,6 +378,8 @@ const bool SPELLinterpreter::prepareObjects()
m_callstack = new SPELLcallstack();
// Create and initialize the execution frame
m_frameManager = new SPELLframeManager();
+
+ DEBUG(" Initializing executor");
// Setup the CIF now
try
@@ -391,10 +394,10 @@ const bool SPELLinterpreter::prepareObjects()
::exit(EIO);
}
- DEBUG(" Initializing executor");
// Initialize the executor with the objects
m_executor->initialize(m_cif, m_controller, m_scheduler, m_callstack, m_frameManager);
+
// Prepare and configure warm start mechanism now
DEBUG(" Preparing warm start");
prepareWarmStart( ctxConfig );
diff --git a/lib/SPELL_EXC/src/SPELLlnotab.C b/lib/SPELL_EXC/src/SPELLlnotab.C
index 18c6038..dec7e41 100644
--- a/lib/SPELL_EXC/src/SPELLlnotab.C
+++ b/lib/SPELL_EXC/src/SPELLlnotab.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the LNotab analyzer
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_EXC/src/SPELLresourceManager.C b/lib/SPELL_EXC/src/SPELLresourceManager.C
new file mode 100644
index 0000000..611f41a
--- /dev/null
+++ b/lib/SPELL_EXC/src/SPELLresourceManager.C
@@ -0,0 +1,190 @@
+// ################################################################################
+// FILE : SPELLresourceManager.C
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Implementation of the procedure resource manager
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// System includes ---------------------------------------------------------
+// Local includes ----------------------------------------------------------
+#include "SPELL_EXC/SPELLresourceManager.H"
+#include "SPELL_EXC/SPELLexecutor.H"
+#include "SPELL_EXC/SPELLexecutorUtils.H"
+#include "SPELL_EXC/SPELLcommand.H"
+// Project includes --------------------------------------------------------
+#include "SPELL_UTIL/SPELLlog.H"
+#include "SPELL_UTIL/SPELLpythonHelper.H"
+
+// GLOBALS ////////////////////////////////////////////////////////////////////
+
+//=============================================================================
+// CONSTRUCTOR : SPELLresourceManager::SPELLresourceManager()
+//=============================================================================
+SPELLresourceManager::SPELLresourceManager( SPELLframeManager& frame )
+: m_frameManager(frame),
+m_changeResourceQueue(5)
+{
+ DEBUG("[RMGR] Created");
+}
+
+//=============================================================================
+// DESTRUCTOR: SPELLresourceManager::~SPELLresourceManager()
+//=============================================================================
+SPELLresourceManager::~SPELLresourceManager()
+{
+ DEBUG("[RMGR] Destroyed");
+}
+
+//=============================================================================
+// METHOD : SPELLresourceManager::setEnabled()
+//=============================================================================
+void SPELLresourceManager::setEnabled( bool enabled )
+{
+ SPELLresourceMonitor::s_enabled = enabled;
+ LOG_INFO("[RMGR] Display of resources enabled: " + BSTR(enabled) );
+}
+
+//=============================================================================
+// METHOD : SPELLresourceManager::setEnabled()
+//=============================================================================
+bool SPELLresourceManager::isEnabled()
+{
+ return SPELLresourceMonitor::s_enabled;
+}
+
+//=============================================================================
+// METHOD : SPELLresourceManager::getResources()
+//=============================================================================
+void SPELLresourceManager::getResources()
+{
+ DEBUG("[RMGR] Retrieve all resources");
+
+ if(isStatusValid())
+ {
+ ExecutorCommand cmd;
+ cmd.id = CMD_RESOURCES;
+ cmd.arg = RESOURCE_MONITOR_GET_RESOURCES;
+
+ // Call through controller
+ SPELLexecutor::instance().command(cmd, false);
+ }
+ else
+ {
+ SPELLexecutorStatus st = SPELLexecutor::instance().getStatus();
+ std::string status = SPELLexecutorUtils::statusToString(st);
+ LOG_WARN("[RMGR] Status is not valid for resource analysis: " + status);
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLresourceManager::analyze()
+//=============================================================================
+void SPELLresourceManager::analyze()
+{
+ m_frameManager.getResourceMonitor().analyze();
+}
+
+
+//=============================================================================
+// METHOD : SPELLresourceManager::changeResource()
+//=============================================================================
+void SPELLresourceManager::changeResource( SPELLresourceInfo& resource )
+{
+ DEBUG("[RMGR] Change resource " + resource.resourceName);
+
+ if(isStatusValid())
+ {
+ try
+ {
+ ExecutorCommand cmd;
+ cmd.id = CMD_RESOURCES;
+ cmd.arg = RESOURCE_MONITOR_CHANGE_RESOURCE;
+
+ m_changeResourceQueue.push(resource);
+ // Call through controller
+ SPELLexecutor::instance().command(cmd, false);
+
+ LOG_INFO("[RMGR] Resource modification submitted: "
+ + resource.resourceName + ": globalValue = "
+ + resource.resourceGlobalValue
+ + ", localValue = " + resource.resourceLocalValue);
+ }
+ catch( SPELLcoreException& ex )
+ {
+ LOG_ERROR("[RMGR] Unable to assign resource value: " + ex.what());
+ }
+ }
+ else
+ {
+ SPELLexecutorStatus st = SPELLexecutor::instance().getStatus();
+ std::string status = SPELLexecutorUtils::statusToString(st);
+ LOG_WARN("[RMGR] Status is not valid for resource analysis: " + status);
+ }
+}
+
+void SPELLresourceManager::callResourceMonitorFromClient(std::string monitorTask)
+{
+ if (monitorTask == RESOURCE_MONITOR_CHANGE_RESOURCE)
+ {
+ SPELLresourceInfo resource = m_changeResourceQueue.pull();
+ m_frameManager.getResourceMonitor().changeResource(resource);
+ }
+ else if (monitorTask == RESOURCE_MONITOR_GET_RESOURCES)
+ {
+ m_frameManager.getResourceMonitor().getResources();
+ }
+ else
+ {
+ LOG_ERROR("[RMGR] Invalid monitorTask in resource manager");
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLresourceManager::isStatusValid()
+//=============================================================================
+bool SPELLresourceManager::isStatusValid()
+{
+ bool valid = false;
+ if (m_frameManager.isReady())
+ {
+ SPELLexecutorStatus st = SPELLexecutor::instance().getStatus();
+ switch(st)
+ {
+ case STATUS_PAUSED:
+ case STATUS_WAITING:
+ case STATUS_PROMPT:
+ case STATUS_FINISHED:
+ case STATUS_INTERRUPTED:
+ case STATUS_ABORTED:
+ valid = true;
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ LOG_WARN("[RMGR] Frame manager is not ready for resource analysis");
+ }
+ return valid;
+}
diff --git a/lib/SPELL_EXC/src/SPELLresourceMonitor.C b/lib/SPELL_EXC/src/SPELLresourceMonitor.C
new file mode 100644
index 0000000..b84ae05
--- /dev/null
+++ b/lib/SPELL_EXC/src/SPELLresourceMonitor.C
@@ -0,0 +1,474 @@
+// ################################################################################
+// FILE : SPELLresourceMonitor.C
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Implementation of the procedure resource monitor
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// System includes ---------------------------------------------------------
+// Local includes ----------------------------------------------------------
+#include "SPELL_EXC/SPELLresourceMonitor.H"
+#include "SPELL_EXC/SPELLexecutor.H"
+// Project includes --------------------------------------------------------
+#include "SPELL_UTIL/SPELLlog.H"
+#include "SPELL_UTIL/SPELLutils.H"
+#include "SPELL_WRP/SPELLconstants.H"
+#include "SPELL_UTIL/SPELLpythonMonitors.H"
+#include "SPELL_WRP/SPELLpyHandle.H"
+
+// GLOBALS ////////////////////////////////////////////////////////////////////
+#define EMPTY_STRING ""
+
+bool SPELLresourceMonitor::s_enabled = false;
+
+//=============================================================================
+// CONSTRUCTOR : SPELLresourceMonitor::SPELLresourceMonitor
+//=============================================================================
+SPELLresourceMonitor::SPELLresourceMonitor( SPELLresourceChangeListener* listener)
+: m_listener(listener)
+{
+ DEBUG("[RD] Created resource monitor");
+ m_initialized = false;
+}
+
+//=============================================================================
+// DESTRUCTOR : SPELLresourceMonitor::~SPELLresourceMonitor
+//=============================================================================
+SPELLresourceMonitor::~SPELLresourceMonitor()
+{
+ delete m_listener;
+ // Do not delete! borrowed reference
+ m_listener = NULL;
+ m_resources.clear();
+ DEBUG("[RD] Destroyed");
+}
+
+//=============================================================================
+// METHOD: SPELLresourceMonitor::retrieveResources()
+//=============================================================================
+void SPELLresourceMonitor::retrieveResources( ResourceMap &resultingMap, bool onlyLocal )
+{
+
+ resultingMap.clear();
+
+ SPELLsafePythonOperations ops("SPELLresourceMonitor::retrieveResources()");
+ // Retrieve the resources
+
+ for (long isLocal=0; isLocal<=1; ++isLocal)
+ {
+ if(isLocal)
+ {
+ if (!SPELLexecutor::instance().getConfiguration().isLocalResourcesSupported())
+ {
+ continue;
+ }
+ }
+ else
+ {
+ if (onlyLocal)
+ {
+ continue;
+ }
+ }
+
+ DEBUG("[RD] Get resources from procedure, with 'IsLocal' = " + BSTR(bool(isLocal)));
+
+ PyObject* pyIsLocal = PyBool_FromLong(isLocal);
+ PyObject* dict = SPELLpythonHelper::instance().callFunction("spell.utils.resources_utils", "getResourcesUtil", pyIsLocal, NULL);
+ /*PyObject* args = PyTuple_New(0);
+ PyObject* kwargs = PyDict_New();
+ PyDict_SetItemString(kwargs, "IsLocal", pyIsLocal);
+ PyObject* dict = SPELLpythonHelper::instance().callSpellFunction("GetResources", args, kwargs);
+ Py_XDECREF(args);
+ Py_XDECREF(kwargs);*/
+ SPELLpythonHelper::instance().checkError();
+ Py_XDECREF(pyIsLocal);
+
+ SPELLpyHandle itemList = PyDict_Keys(dict);
+ unsigned int numItems = PyList_Size(itemList.get());
+ for( unsigned int index = 0; index"
+ //if (value == "") value = EMPTY_STRING;
+
+ if (isLocal)
+ {
+ // override previously set value. If not set (when onlyLocal is true), other fields are
+ // initialized by the default ResourceInfo initializer (called from analyser)
+ resultingMap[resourceName].resourceLocalValue = value;
+ }
+ else
+ {
+ std::string gcsName;
+ std::map::iterator itNM = m_resourceNameMapping.find(resourceName);
+ if (itNM != m_resourceNameMapping.end())
+ {
+ gcsName = itNM->second;
+ }
+ else
+ {
+ gcsName = resourceName;
+ }
+
+ // get the accepted values list
+ std::map > >::iterator it = m_resourceAcceptedValues.find(resourceName);
+ // first set the local value to the empty, wil be updated in the second iteration
+ if (it != m_resourceAcceptedValues.end())
+ {
+ resultingMap.insert( std::make_pair(resourceName, SPELLresourceInfo(resourceName, type, value, "", it->second, gcsName)) );
+ }
+ else
+ {
+ resultingMap.insert( std::make_pair(resourceName, SPELLresourceInfo(resourceName, type, value, "", std::vector >(), gcsName)) );
+ }
+ }
+
+ Py_XDECREF(object);
+ }
+ }
+}
+
+//=============================================================================
+// METHOD: SPELLresourceMonitor::retrieveResourceValueRangeAndNameMap()
+//=============================================================================
+void SPELLresourceMonitor::retrieveResourceValueRangeAndNameMap()
+{
+ m_resourceAcceptedValues.clear();
+
+ SPELLsafePythonOperations ops("SPELLresourceMonitor::retrieveResourceValueRangeAndNameMap()");
+
+ // Retrieved accepted values lists or resources
+ PyObject* dict = SPELLpythonHelper::instance().callFunction("spell.utils.resources_utils","getResourceAcceptedValuesUtil",NULL);
+ SPELLpyHandle itemList = PyDict_Keys(dict);
+ unsigned int numItems = PyList_Size(itemList.get());
+ for( unsigned int index = 0; index > valueVector;
+ for(Py_ssize_t i = 0; i < PyList_Size(object); i++) {
+ PyObject *tuple = PyList_GetItem(object, i);
+ Py_XINCREF(tuple);
+ PyObject *value1 = PyTuple_GetItem(tuple, 0);
+ PyObject *value2 = PyTuple_GetItem(tuple, 1);
+ valueVector.push_back( std::make_pair( PYSSTR( value1 ), PYSSTR( value2 ) ) );
+ Py_XDECREF(tuple);
+ }
+ Py_XDECREF(object);
+
+ m_resourceAcceptedValues.insert( std::make_pair(resourceName, valueVector ));
+ }
+
+ m_resourceNameMapping.clear();
+
+ dict = SPELLpythonHelper::instance().callFunction("spell.utils.resources_utils","getResourceNameMapUtil",NULL);
+ itemList = PyDict_Keys(dict);
+ numItems = PyList_Size(itemList.get());
+ for( unsigned int index = 0; index allResources;
+
+ SPELLresourceMonitor::ResourceMap::const_iterator it;
+ for( it = m_resources.begin(); it != m_resources.end(); it++)
+ {
+ allResources.push_back(it->second);
+ }
+
+ m_listener->resourceList( allResources );
+}
+
+//=============================================================================
+// METHOD: SPELLresourceMonitor::changeResource()
+//=============================================================================
+void SPELLresourceMonitor::changeResource( SPELLresourceInfo& resource )
+{
+ SPELLsafePythonOperations ops("SPELLresourceMonitor::changeResource()");
+
+ DEBUG("[RD] Request changing resource " + resource.resourceName);
+
+ if (!m_initialized) initialize();
+
+ ResourceMap::iterator it = m_resources.find(resource.resourceName);
+
+ for (long isLocal=0; isLocal<=1; ++isLocal)
+ {
+ std::string *resourceVal;
+ if (isLocal)
+ {
+ resourceVal = &(resource.resourceLocalValue);
+ if (it != m_resources.end() && *resourceVal == it->second.resourceLocalValue)
+ continue;
+ }
+ else
+ {
+ resourceVal = &(resource.resourceGlobalValue);
+ if (it != m_resources.end() && *resourceVal == it->second.resourceGlobalValue)
+ continue;
+ }
+
+ // Evaluate the value for the resource
+ PyObject* value = NULL;
+ // If resourceValue is empty string, do not change value
+ if (*resourceVal == "")
+ {
+ continue; //value = STRPY("");
+ }
+ else
+ {
+ // Build assignment expression. We need to check first, if there
+ // are double quotes, convert them to single quotes
+ SPELLutils::replace(*resourceVal, "\"", "'");
+ DEBUG("[RD] Evaluating value expression: " + *resourceVal );
+ // Check value correctness and evaluate it
+ value = SSTRPY((*resourceVal)); //SPELLpythonHelper::instance().eval(*resourceVal, false);
+ }
+
+ *resourceVal = PYSSTR(value);
+
+ DEBUG("[RD] Setting " + resource.resourceName + " to " + PYREPR(value) + " 'IsLocal' is " + BSTR(bool(isLocal)));
+
+ // create args
+ PyObject* pyIsLocal = PyBool_FromLong(isLocal);
+ PyObject* pyName = SSTRPY(resource.resourceName);
+ PyObject* retVal = SPELLpythonHelper::instance().callFunction("spell.utils.resources_utils", "setResourceUtil", pyName, value, pyIsLocal, NULL);
+ /*PyObject* args = PyTuple_New(2);
+ PyTuple_SetItem(args, 0, pyName);
+ PyTuple_SetItem(args, 1, value);
+ PyObject* kwargs = PyDict_New();
+ PyDict_SetItemString(kwargs, "IsLocal", pyIsLocal);
+ // Call set resource
+ PyObject* retVal = SPELLpythonHelper::instance().callSpellFunction("SetResource", args, kwargs);
+ // release
+ Py_XDECREF(args);
+ Py_XDECREF(kwargs);*/
+ SPELLpythonHelper::instance().checkError();
+ Py_XDECREF(pyIsLocal);
+ Py_XDECREF(pyName);
+ Py_XDECREF(value);
+
+ if ((int) PyInt_AsLong(retVal) != 1)
+ {
+ DEBUG("[RD] Setting resource " + resource.resourceName + " to " + (*resourceVal) + " failed. 'IsLocal' is " + BSTR(bool(isLocal)));
+ // setting resource failed, do nothing
+ return;
+ }
+
+ DEBUG("[RD] Setting resource " + resource.resourceName + " to " + (*resourceVal) + " success. 'IsLocal' is " + BSTR(bool(isLocal)));
+ //if (*resourceVal == "") *resourceVal = EMPTY_STRING;
+ }
+
+ // Update the resource in the internal model and notify to listeners
+ if (it != m_resources.end() && (resource.resourceGlobalValue != "" || resource.resourceLocalValue != ""))
+ {
+ std::vector changed;
+ if (resource.resourceGlobalValue != "")
+ {
+ it->second.resourceGlobalValue = resource.resourceGlobalValue;
+ }
+ if (resource.resourceLocalValue != "")
+ {
+ it->second.resourceLocalValue = resource.resourceLocalValue;
+ }
+ LOG_INFO("[RD] resource changed by user: " + resource.resourceName +
+ ", current global value: " + it->second.resourceGlobalValue +
+ ", current local value " + it->second.resourceLocalValue );
+ changed.push_back(it->second);
+ m_listener->resourceChanged( changed );
+ }
+}
+
+//=============================================================================
+// METHOD: SPELLresourceMonitor::getResource()
+//=============================================================================
+void SPELLresourceMonitor::getResource( SPELLresourceInfo& resource )
+{
+ if (!m_initialized) initialize();
+ ResourceMap::iterator it = m_resources.find(resource.resourceName);
+ if (it != m_resources.end())
+ {
+ resource.resourceGlobalValue = it->second.resourceGlobalValue;
+ if (resource.resourceGlobalValue == "") resource.resourceGlobalValue = EMPTY_STRING;
+ resource.resourceLocalValue = it->second.resourceLocalValue;
+ if (resource.resourceLocalValue == "") resource.resourceLocalValue = EMPTY_STRING;
+ resource.resourceType = it->second.resourceType;
+ }
+ else
+ {
+ resource.resourceGlobalValue = "???";
+ resource.resourceLocalValue = "???";
+ resource.resourceType = "???";
+ }
+}
+
+//=============================================================================
+// METHOD: SPELLresourceMonitor::shouldDiscard()
+//=============================================================================
+bool SPELLresourceMonitor::shouldDiscard( const std::string& resourceName )
+{
+ return false;
+}
+
+//=============================================================================
+// METHOD: SPELLresourceMonitor::analyze()
+//=============================================================================
+void SPELLresourceMonitor::analyze()
+{
+ if (!SPELLresourceMonitor::s_enabled) return;
+
+ if (!m_initialized) initialize();
+
+ SPELLsafePythonOperations ops("SPELLresourceMonitor::analyze()");
+
+ DEBUG("[RD] Analyze changes");
+
+ std::vector changed;
+
+ ResourceMap tempResourceMap;
+
+ // Retrieve local resources
+ retrieveResources(tempResourceMap, true);
+
+ ResourceMap::iterator it, itKeep;
+ for(it = tempResourceMap.begin(); it != tempResourceMap.end(); ++it)
+ {
+ std::string resourceName = it->first;
+ //std::cout << resourceName << " -> " << shouldDiscard(resourceName,object) << std::endl;
+ if (shouldDiscard(resourceName)) continue;
+
+ itKeep = m_resources.find(resourceName);
+
+ // The resource is new
+ if (itKeep == m_resources.end())
+ {
+ LOG_INFO("[RD] Error: There should be no new global resource, but got '" + resourceName + "'");
+ }
+ // The resource exists, compare values
+ else
+ {
+ bool hasChanged = false;
+ if (itKeep->second.resourceLocalValue != it->second.resourceLocalValue)
+ {
+ LOG_INFO("[RD] Resource local value change: " + resourceName + ", current value: " + it->second.resourceLocalValue + ", previous: " + itKeep->second.resourceLocalValue );
+ itKeep->second.resourceLocalValue = it->second.resourceLocalValue;
+ hasChanged = true;
+ }
+ if (hasChanged)
+ {
+ changed.push_back(itKeep->second);
+ }
+ }
+ }
+
+ if ( changed.size()>0 )
+ {
+ m_listener->resourceChanged( changed );
+ }
+}
+
+//=============================================================================
+// METHOD: SPELLresourceChangeListener::resourceChanged()
+//=============================================================================
+void SPELLresourceChangeListener::resourceChanged( const std::vector& changed )
+{
+ if (SPELLresourceMonitor::s_enabled)
+ {
+ SPELLexecutor::instance().getCIF().notifyResourceChange( changed );
+ }
+}
+
+//=============================================================================
+// METHOD: SPELLresourceChangeListener::resourceList()
+//=============================================================================
+void SPELLresourceChangeListener::resourceList( const std::vector& resources )
+{
+ if (SPELLresourceMonitor::s_enabled)
+ {
+ SPELLexecutor::instance().getCIF().notifyResourceList( resources );
+ }
+}
diff --git a/lib/SPELL_EXC/src/SPELLscheduler.C b/lib/SPELL_EXC/src/SPELLscheduler.C
index 7977a76..f254d6e 100644
--- a/lib/SPELL_EXC/src/SPELLscheduler.C
+++ b/lib/SPELL_EXC/src/SPELLscheduler.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the executor scheduler
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -60,7 +60,9 @@ SPELLscheduler::SPELLscheduler( bool useSafeCalls )
m_result.reset();
m_silentCheck = false;
m_defaultPromptWarningDelay = 30;
-
+ m_abortTimer = false;
+ m_pyTM = NULL;
+ m_notificationPeriodIndex = 0;
DEBUG("[SCH] Scheduler created");
}
@@ -78,26 +80,34 @@ SPELLscheduler::~SPELLscheduler()
//=============================================================================
void SPELLscheduler::startWait( const SPELLscheduleCondition& condition )
{
- DEBUG("[SCH] Starting wait");
+ LOG_INFO("Starting wait");
+ // If there is a condition already ongoing, cancel it
+ if (m_condition.type != SPELLscheduleCondition::SCH_NONE)
+ {
+ {
+ SPELLmonitor m(m_checkLock);
+ finishWaitInternal(false, false);
+ }
+ // Wait for the timer to finish otherwise we might cause a deadlock when starting the next timer
+ if (m_timer != NULL)
+ {
+ m_timer->join();
+ }
+ }
- // If there is a condition already ongoing, cancel it
- if (m_condition.type != SPELLscheduleCondition::SCH_NONE)
- {
- finishWait(false,false);
- }
+ SPELLmonitor m(m_checkLock);
- // Store the condition data
m_condition = condition;
- DEBUG(" Condition type: " + ISTR(m_condition.type));
- DEBUG(" Target time : " + m_condition.targetTime.toString());
- DEBUG(" Expression : " + m_condition.expression);
- DEBUG(" Message : " + m_condition.message);
- DEBUG(" Period : " + m_condition.period.toString());
- DEBUG(" Timeout : " + m_condition.timeout.toString());
- DEBUG(" List : " + PYREPR(m_condition.getVerification()));
- DEBUG(" Configuration : " + PYREPR(m_condition.getConfig()));
- DEBUG(" Prompt user : " + BSTR(m_condition.promptUser));
+ LOG_INFO(" Condition type: " + ISTR(m_condition.type));
+ LOG_INFO(" Target time : " + m_condition.targetTime.toString());
+ LOG_INFO(" Expression : " + m_condition.expression);
+ LOG_INFO(" Message : " + m_condition.message);
+ LOG_INFO(" Period : " + m_condition.period.toString());
+ LOG_INFO(" Timeout : " + m_condition.timeout.toString());
+ LOG_INFO(" List : " + PYREPR(m_condition.getVerification()));
+ LOG_INFO(" Configuration : " + PYREPR(m_condition.getConfig()));
+ LOG_INFO(" Prompt user : " + BSTR(m_condition.promptUser));
// Reset filters
@@ -191,12 +201,12 @@ void SPELLscheduler::startWait( const SPELLscheduleCondition& condition )
//=============================================================================
void SPELLscheduler::startPrompt( const SPELLtime& timeout, bool headless )
{
- DEBUG("[SCH] Starting prompt (to: " + timeout.toString() + ")");
+ LOG_INFO("Starting prompt (to: " + timeout.toString() + ")");
// If there is a condition already ongoing, cancel it
if (m_condition.type != SPELLscheduleCondition::SCH_NONE)
{
- finishWait(false,false);
+ finishWaitInternal(false,false);
}
// Store the condition data
@@ -217,6 +227,7 @@ void SPELLscheduler::startPrompt( const SPELLtime& timeout, bool headless )
DEBUG("[SCH] Timeout given from the adapter");
m_condition.timeout = timeout;
}
+
DEBUG("[SCH] Prompt timeout: " + m_condition.timeout.toString());
// Reset filters
@@ -281,7 +292,7 @@ void SPELLscheduler::startTimer()
{
DEBUG("Using default period of 1 second");
SPELLtime defaultPeriod(1,0,true);
- m_timer = new SPELLtimer( 200, *this );
+ m_timer = new SPELLtimer( 200, *dynamic_cast(this) );
}
m_timer->start();
}
@@ -300,35 +311,52 @@ bool SPELLscheduler::timerCallback( unsigned long elapsed )
}
else
{
- SPELLsafePythonOperations ops("SPELLscheduler::timerCallback()");
- // Depending on the condition type, we perform one check or another
- switch(m_condition.type)
- {
- case SPELLscheduleCondition::SCH_TIME:
- case SPELLscheduleCondition::SCH_PROMPT:
- {
- abortCheck = checkTime();
- break;
- }
- case SPELLscheduleCondition::SCH_EXPRESSION:
- {
- abortCheck = checkExpression();
- break;
- }
- case SPELLscheduleCondition::SCH_CHILD:
- {
- abortCheck = checkChildProcedure();
- break;
- }
- case SPELLscheduleCondition::SCH_VERIFICATION:
- {
- abortCheck = checkVerification();
- break;
- }
- default:
- break;
- }
+ SPELLtime lockTime;
+ // We need the check Lock as well otherwise we might deadlock when executing timerCallback and startWait at the same time
+ do {
+ //SPELLmonitor m(m_checkLock);
+ bool locked = m_checkLock.trylock();
+ if (!locked) {
+ SPELLtime currentTime;
+ SPELLtime diff = currentTime - lockTime;
+ if (diff.getSeconds() > 5 || m_abortTimer) {
+ return false;
+ }
+ usleep(100000);
+ continue;
+ }
+
+ SPELLsafePythonOperations ops("SPELLscheduler::timerCallback()");
+ // Depending on the condition type, we perform one check or another
+ switch(m_condition.type)
+ {
+ case SPELLscheduleCondition::SCH_TIME:
+ case SPELLscheduleCondition::SCH_PROMPT:
+ {
+ abortCheck = checkTime();
+ break;
+ }
+ case SPELLscheduleCondition::SCH_EXPRESSION:
+ {
+ abortCheck = checkExpression();
+ break;
+ }
+ case SPELLscheduleCondition::SCH_CHILD:
+ {
+ abortCheck = checkChildProcedure();
+ break;
+ }
+ case SPELLscheduleCondition::SCH_VERIFICATION:
+ {
+ abortCheck = checkVerification();
+ break;
+ }
+ default:
+ break;
+ }
+ m_checkLock.unlock();
+ } while (false);
// Periodic notifications with message and interval. We shall not be
// aborting, there shall be a defined notification period, a message
// to show shall be available and the time since the last notification
@@ -339,6 +367,7 @@ bool SPELLscheduler::timerCallback( unsigned long elapsed )
(m_condition.message != "") &&
(currentTime - m_lastNotificationTime)>=m_notificationPeriod )
{
+ SPELLsafePythonOperations ops("SPELLscheduler::timerCallback()");
DEBUG("[SCH] Issuing user message");
SPELLexecutor::instance().getCIF().write(m_condition.message, LanguageConstants::SCOPE_PROC );
@@ -378,7 +407,9 @@ void SPELLscheduler::notifyTime( bool finished, bool success )
if (!finished)
{
SPELLtime currentTime;
- std::string remaining = (m_checkTargetTime - currentTime).toString();
+ auto diff = (m_checkTargetTime - currentTime);
+ diff.set(diff.getSeconds(),diff.getMilliseconds(),0);
+ std::string remaining = diff.toString();
ItemNotification item;
item.type = NOTIFY_TIME;
item.name = "COUNTDOWN";
@@ -814,7 +845,14 @@ bool SPELLscheduler::interruptWait()
//=============================================================================
void SPELLscheduler::finishWait( bool setStatus, bool keepLock )
{
- SPELLmonitor m(m_checkLock);
+ finishWaitInternal(setStatus,keepLock);
+}
+
+//=============================================================================
+// METHOD : SPELLscheduler::finishWait
+//=============================================================================
+void SPELLscheduler::finishWaitInternal( bool setStatus, bool keepLock )
+{
if (waiting())
{
DEBUG("[SCH] Finish wait status");
@@ -866,7 +904,12 @@ void SPELLscheduler::wait()
// This may block the execution for a long time, so we need to allow other Python threads
// to kick in
SPELLsafeThreadOperations ops("SPELLscheduler::wait()");
+ DEBUG("[SCH] Wait on event IN");
m_waitingEvent.wait();
+// if (m_timer != NULL){
+// m_timer->join();
+// }
+ DEBUG("[SCH] Wait on event OUT");
};
//=============================================================================
@@ -997,7 +1040,7 @@ bool SPELLscheduler::waitCondition( std::string condition )
else if (PyDict_Contains( pycond.get(), pyUntil.get() ))
{
std::string until_time = PYREPR(PyDict_GetItemString( pycond.get(), Until.c_str()));
- until_time = "TIME(" + until_time + ").abs()";
+ until_time = "long(TIME(" + until_time + ").abs())";
// New reference
SPELLpyHandle theTime = SPELLpythonHelper::instance().eval(until_time,false);
@@ -1094,4 +1137,17 @@ void SPELLscheduler::setPromptWarningDelay( unsigned int secs )
{
LOG_INFO("[SCH] Update prompt warning default delay to " + ISTR(secs) + " seconds");
m_defaultPromptWarningDelay = secs;
+ // Set Default timeout in case the current condition waits for a Prompt
+ if (m_condition.type == SPELLscheduleCondition::SCH_PROMPT)
+ {
+ m_condition.timeout.set(m_defaultPromptWarningDelay,0);
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLscheduler::raiseWarningEventToGCS()
+//=============================================================================
+void SPELLscheduler::raiseWarningEventToGCS( const std::string& message ) {
+ SPELLsafePythonOperations ops("SPELLscheduler::raiseWarningEventToGCS()");
+ raiseEvent(message);
}
diff --git a/lib/SPELL_EXC/src/SPELLserviceImpl.C b/lib/SPELL_EXC/src/SPELLserviceImpl.C
new file mode 100644
index 0000000..61db8b1
--- /dev/null
+++ b/lib/SPELL_EXC/src/SPELLserviceImpl.C
@@ -0,0 +1,1739 @@
+// ################################################################################
+// FILE : SPELLexecutorImpl.C
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Implementation of the executor
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// System includes ---------------------------------------------------------
+// Local includes ----------------------------------------------------------
+#include "SPELL_EXC/SPELLexecutor.H"
+#include "SPELL_EXC/SPELLserviceImpl.H"
+#include "SPELL_EXC/SPELLexecutorImpl.H"
+
+#include "SPELL_EXC/SPELLexecutorUtils.H"
+// Project includes --------------------------------------------------------
+#include "SPELL_PRD/SPELLprocedureManager.H"
+#include "SPELL_SYN/SPELLmonitor.H"
+#include "SPELL_CFG/SPELLconfiguration.H"
+#include "SPELL_DTA/SPELLdtaContainer.H"
+#include "SPELL_UTIL/SPELLlog.H"
+#include "SPELL_UTIL/SPELLpythonHelper.H"
+#include "SPELL_UTIL/SPELLpythonMonitors.H"
+#include "SPELL_WRP/SPELLdriverManager.H"
+#include "SPELL_WRP/SPELLdatabaseManager.H"
+#include "SPELL_WRP/SPELLpyHandle.H"
+#include "SPELL_WRP/SPELLregistry.H"
+#include "SPELL_WRP/SPELLconstants.H"
+#include "SPELL_CFG/SPELLbrowsableLibMode.H"
+
+using namespace PythonConstants;
+
+// GLOBALS ////////////////////////////////////////////////////////////////////
+
+// Bridge for C-API dispatching callback
+static int static_dispatch( PyObject* obj, PyFrameObject* frame, int what, PyObject* args )
+{
+ return SPELLexecutor::instance().dispatch(obj, frame, what, args);
+}
+
+std::string dispatchDataType( int what );
+
+//=============================================================================
+// CONSTRUCTOR : SPELLserviceImpl::SPELLserviceImpl
+//=============================================================================
+SPELLserviceImpl::SPELLserviceImpl()
+ : SPELLexecutorIF(),
+ m_importChecker()
+{
+ m_initialized = false;
+ m_initStepDone = false;
+ m_initLines.clear();
+ m_cif = NULL;
+ m_frameManager = NULL;
+ m_instanceId = "";
+ m_parentId = "";
+ m_childId = "";
+ m_servicePath = "";
+
+ m_scheduler = NULL;
+ m_callstack = NULL;
+ m_controller = NULL;
+ m_childMgr = NULL;
+ m_varManager = NULL;
+ m_resourceManager = NULL;
+
+ m_userAction.reset();
+ m_gotoTarget = "";
+
+ m_childMgr = new SPELLchildManager();
+
+ DEBUG("[E] SPELLexecutor created");
+}
+
+//=============================================================================
+// DESTRUCTOR : SPELLexecutorImpl::~SPELLexecutorImpl
+//=============================================================================
+SPELLserviceImpl::~SPELLserviceImpl()
+{
+ DEBUG("[E] SPELLservice destroyed");
+ if (m_childMgr)
+ {
+ delete m_childMgr;
+ }
+
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::initialize()
+//=============================================================================
+
+void SPELLserviceImpl::refreshStatus()
+{
+ if (m_controller != NULL)
+ {
+ m_controller->refreshStatus();
+ }
+}
+
+void SPELLserviceImpl::initialize( SPELLcif* cif,
+ SPELLcontrollerIF* controller,
+ SPELLschedulerIF* scheduler,
+ SPELLcallstackIF* callstack,
+ SPELLframeManager* frame )
+{
+ assert( cif != NULL );
+ assert( controller != NULL );
+ assert( scheduler != NULL );
+ assert( callstack != NULL );
+ assert( frame != NULL );
+ m_cif = cif;
+ m_controller = controller;
+ m_scheduler = scheduler;
+ m_callstack = callstack;
+ m_frameManager = frame;
+ m_varManager = new SPELLvariableManager(*frame);
+ m_resourceManager = new SPELLresourceManager(*frame);
+
+ // The order is important here!
+ addDispatchListener(m_frameManager);
+ addDispatchListener(m_callstack);
+ addDispatchListener(m_controller);
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::getConfiguration()
+//=============================================================================
+SPELLexecutorConfig& SPELLserviceImpl::getConfiguration()
+{
+ if (m_cif != NULL)
+ {
+ return m_cif->getExecutorConfig();
+ }
+ return m_emptyConfig;
+};
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::getStatus()
+//=============================================================================
+const SPELLexecutorStatus SPELLserviceImpl::getStatus() const
+{
+ if (m_controller != NULL)
+ {
+ return m_controller->getStatus();
+ }
+ return STATUS_UNKNOWN;
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::getInstanceId
+//=============================================================================
+const std::string SPELLserviceImpl::getInstanceId() const
+{
+ return m_instanceId;
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::prepare
+//=============================================================================
+void SPELLserviceImpl::prepare( const std::string& instanceId, const SPELLcontextConfig& ctxConfig )
+{
+ assert( m_cif != NULL );
+ assert( m_controller != NULL );
+ assert( m_scheduler != NULL );
+ assert( m_callstack != NULL );
+ assert( m_frameManager != NULL );
+
+ LOG_INFO("[E] Preparing service execution");
+
+ // Check for Python errors
+ SPELLpythonHelper::instance().checkError();
+
+ // See constants.H
+ // We do this on preparation stage because these values shall not be reset
+ // on procedure reload. The user may have changed them in the meantime.
+ if (!m_initialized)
+ {
+ m_instanceId = instanceId;
+
+ //Get from CTX Config
+ m_inputDir = SPELLutils::resolvePath( ctxConfig.getInputDirectory() );
+ m_outputDir = SPELLutils::resolvePath( ctxConfig.getOutputDirectory() );
+
+ // Report the current configuration
+ LOG_INFO("EXECUTOR CONFIGURATION (" + getInstanceId() + ")");
+ LOG_INFO("[E] Headless : " + BSTR(getConfiguration().isHeadless()) );
+ LOG_INFO("[E] Parent : " + getConfiguration().getParentProcId() );
+ LOG_INFO("[E] Arguments : " + getConfiguration().getArguments() );
+ LOG_INFO("[E] Condition : " + getConfiguration().getCondition() );
+ LOG_INFO("[E] Automatic mode : " + BSTR( getConfiguration().isAutomatic() ));
+ LOG_INFO("[E] Visible mode : " + BSTR( getConfiguration().isVisible() ));
+ LOG_INFO("[E] Blocking mode : " + BSTR( getConfiguration().isBlocking() ));
+ LOG_INFO("[E] Browsable lib : " + getConfiguration().getBrowsableLibStr() );
+ LOG_INFO("[E] TC Confirm : " + BSTR( getConfiguration().isForceTcConfirm() ));
+ LOG_INFO("[E] Prompt Confirm : " + BSTR( getConfiguration().isForcePromptConfirm() ));
+ LOG_INFO("[E] Save state mode : " + getConfiguration().getSaveStateMode() );
+ LOG_INFO("[E] Watch variables : " + BSTR(getConfiguration().isWatchEnabled()) );
+ LOG_INFO("[E] resources display: " + BSTR(getConfiguration().isResourcesDisplayEnabled()) );
+ LOG_INFO("[E] Local resource support: " + BSTR(getConfiguration().isLocalResourcesSupported()) );
+ LOG_INFO("[E] Input directory : " + m_inputDir );
+ LOG_INFO("[E] Output directory : " + m_outputDir );
+ LOG_INFO("[E] Run Into : " + BSTR(getConfiguration().isRunInto()));
+ LOG_INFO("[E] Exec Delay : " + ISTR(getConfiguration().getExecDelay()));
+ LOG_INFO("[E] Prompt Delay : " + ISTR(getConfiguration().getPromptWarningDelay()));
+ LOG_INFO("[E] By Step : " + BSTR(getConfiguration().isByStep()));
+ LOG_INFO("[E] Max Verbosity : " + ISTR(getConfiguration().getMaxVerbosity()));
+
+ m_scheduler->setPromptWarningDelay(getConfiguration().getPromptWarningDelay());
+
+ m_initialized = true;
+ }
+
+ // Check that no previous errors are there
+ SPELLpythonHelper::instance().checkError();
+
+ // Setup extra environment stuff
+ // 1. Procedure arguments and internal variables.
+ // If there are arguments available we need to evaluate
+ // them in the Python environment and to install them in the execution environment
+ // via the ARGS and IVARS global objects.
+ installCallingArguments();
+ installInternalVariables();
+
+ // 2. Process condition and open mode
+ // If there is a condition available, we set it to the controller. The controller
+ // will read and evaluate it and hold the execution until the condition is
+ // fullfilled.
+ if (getConfiguration().getCondition() != "")
+ {
+ m_controller->setCondition( getConfiguration().getCondition() );
+ }
+
+ // Reset any user action function previously set
+ m_userAction.reset();
+
+ // Configure the initial step over mode in the callstack
+ if (getConfiguration().isRunInto()==true)
+ {
+ m_callstack->stepOver( SO_ALWAYS_INTO );
+ }
+ else
+ {
+ m_callstack->stepOver( SO_ALWAYS_OVER );
+ }
+
+ LOG_INFO("[E] Executor prepared");
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::installCallingArguments
+//=============================================================================
+void SPELLserviceImpl::installCallingArguments()
+{
+ DEBUG("[E] Installing calling arguments");
+
+ PyObject* argDict = NULL;
+ if (getConfiguration().getArguments() != "")
+ {
+ try
+ {
+ // Evaluate the argument string. It is expected to be a Python dictionary.
+ // No error check is done for this.
+ argDict = SPELLpythonHelper::instance().eval(getConfiguration().getArguments(),false);
+ }
+ catch(SPELLcoreException& ex)
+ {
+ m_cif->error( "Unable to install arguments data holder: " + ex.what(), LanguageConstants::SCOPE_SYS );
+ argDict = PyDict_New();
+ }
+ }
+ else
+ {
+ // In case of no arguments given, we install an empty Python dictionary.
+ argDict = PyDict_New();
+ }
+
+
+ // Initialize now the data container for Calling Arguments
+ Py_INCREF(argDict);
+ DEBUG("[E] Argument dictionary: " + PYREPR(argDict));
+ PyObject* classObj = SPELLpythonHelper::instance().getObject(MOD_NAME(libSPELL_DTA), "DataContainer");
+ PyObject* argTuple = PyTuple_New(1);
+ PyObject* argsName = STRPY("Calling Arguments");
+ PyTuple_SetItem(argTuple,0,argsName);
+ Py_INCREF(argsName);
+ Py_INCREF(argTuple);
+ PyObject* args = SPELLpythonHelper::instance().newInstance(classObj, argTuple, NULL);
+
+ DEBUG("[E] Calling arguments instance: " + PYREPR(args) + " type: " + PYCREPR(PyObject_Type(args)));
+
+ // Now assign the passed arguments. Disable notifications for DTA
+ SPELLdtaContainer::setGlobalNotificationsEnabled(false);
+ SPELLpyHandle argKeys = PyDict_Keys(argDict);
+ unsigned int numKeys = PyList_Size(argKeys.get());
+ for(unsigned int idx = 0; idxreset();
+ }
+ DEBUG("[E] Reset status");
+ m_controller->reset();
+ m_importChecker.reset();
+ // Reset CIF closure lock always
+ m_cif->resetClose();
+
+ // Establish initial run-into value now (after reset)
+ m_controller->enableRunInto( getConfiguration().isRunInto() );
+
+ // The client will know that the executor is ready to go
+ // Take into account initialization errors
+ SPELLexecutorStatus status = m_controller->getStatus();
+ LOG_INFO("Initial status check: " + SPELLexecutorUtils::statusToString(status) );
+ SPELLexecutionResult result = EXECUTION_UNKNOWN;
+ if (status != STATUS_ERROR)
+ {
+ m_controller->setStatus(STATUS_LOADED);
+
+ DEBUG("[E] Set autorun");
+ m_controller->setAutoRun();
+
+ DEBUG("[E] Launching execution");
+ // Execute the procedure/script. This triggers the procedure
+ // execution under dispatcher control.
+ //result = m_frameManager->execute();
+
+ SPELLpyService& service = SPELLprocedureManager::instance().getService(m_instanceId);
+
+ service.start();
+
+ DEBUG("[E] Execution done, checking result (" + ISTR(result) + ")");
+ }
+ else
+ {
+ LOG_ERROR("Initialization error");
+ result = EXECUTION_ERROR;
+ }
+
+ // Check execution result and proceed accordingly.
+ // Frame will be reset and environment unloaded if needed, depending on the case.
+
+ switch(result)
+ {
+ case EXECUTION_ERROR:
+ {
+ DEBUG("[E] Result ERROR");
+ m_initStepDone = true;
+ continueExecuting = executorFinishedWithErrors();
+ if (continueExecuting)
+ {
+ // We will recover, so do not reset entities
+ resetEntities = false;
+ }
+ break;
+ }
+ case EXECUTION_SUCCESS:
+ case EXECUTION_TERMINATED:
+ {
+ DEBUG("[E] Result SUCCESS/TERMINATED");
+ m_initStepDone = false;
+ continueExecuting = executorFinishedRight();
+ break;
+ }
+ case EXECUTION_ABORTED:
+ {
+ DEBUG("[E] Result ABORTED");
+ m_initStepDone = false;
+ continueExecuting = executorAborted();
+ break;
+ }
+ default:
+ {
+ DEBUG("[E] Execution result unknown: " + ISTR(result));
+ m_initStepDone = false;
+ unloadDriver(true);
+ continueExecuting = false;
+ break;
+ }
+ }
+ }
+ while(continueExecuting);
+
+ // This may be redundant, but does not harm.
+ PyEval_SetTrace( NULL, NULL );
+
+ DEBUG("[E] Execution finished");
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::reloadOrClose
+//=============================================================================
+bool SPELLserviceImpl::reloadOrClose()
+{
+ DEBUG("[E] Waiting for CIF closure");
+ // Wait the close or reload command from the user
+ m_cif->waitClose();
+ // This tells us if user wants to reload, not close
+ if (m_controller->shouldReload())
+ {
+ DEBUG("[E] Clear asrun");
+ m_cif->clearAsRun();
+ DEBUG("[E] Reload driver");
+ // We are reloading, load again the execution environment and reset the frame
+ loadDriver();
+ DEBUG("[E] Reset frame");
+ m_frameManager->reset();
+ DEBUG("[E] Reload environment");
+ loadExecutionEnvironment();
+ return true;
+ }
+ else
+ {
+ // Completely unload execution environment if we are not reloading
+ unloadDriver(true);
+ return false;
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::executorAborted
+//=============================================================================
+bool SPELLserviceImpl::executorAborted()
+{
+ DEBUG("[E] Execution finished due to abort");
+ // Cleanup the runtime exception that lead to the abort of the interpretation
+ SPELLerror::instance().clearErrors();
+ // Set the status aborted here, not before. Otherwise, the GUI would be notified
+ // before the driver actually unloads, and this may take time.
+ getController().setStatus(STATUS_ABORTED);
+ // Procedure has aborted, so unload the driver and execution environment right away
+ unloadDriver(false);
+ // Wait until the user decides to close or to reload
+ return reloadOrClose();
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::executorFinishedRight
+//=============================================================================
+bool SPELLserviceImpl::executorFinishedRight()
+{
+ DEBUG("[E] Service Execution finished successfully");
+ // Cleanup the runtime exception that lead to the termination of the interpretation
+ SPELLerror::instance().clearErrors();
+
+ // Mark the procedure as finished
+ m_controller->setFinished();
+
+ // Procedure has finished, so unload the driver and execution environment right away
+ unloadDriver(false);
+ // This call may be misleading but the behavior at this point is the same as the aborted state
+ return reloadOrClose();
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::executorFinishedWithErrors
+//=============================================================================
+bool SPELLserviceImpl::executorFinishedWithErrors()
+{
+ DEBUG("[E] Service Execution finished with errors");
+ // Will return true if the error was recoverable AND
+ // the user chooses to recover.
+ AfterError errorHandlingResult = handleExecutionError();
+ bool continueExecuting = false;
+
+ // If the user does not want to (either closing or reloading)
+ switch(errorHandlingResult)
+ {
+ case CANCEL_RECOVER:
+ {
+ // This tells us if user wants to reload, not close
+ if(m_controller->shouldReload())
+ {
+ // If we are reloading, just dont unload the execution environment, reset the
+ // frame and start over
+ m_frameManager->reset();
+ continueExecuting = true;
+ }
+ else
+ {
+ // Unload the environment if we dont recover
+ unloadDriver(true);
+ }
+ // Else will close and not reload/recover
+ break;
+ }
+ case RECOVER_SUCCESS:
+ {
+ // To re-execute. But do not reset the frame and dont unload the environment.
+ continueExecuting = true;
+ break;
+ }
+ case RECOVER_FAILED:
+ case CANNOT_RECOVER:
+ {
+ // Unload the environment, could not recover it
+ unloadDriver(false);
+ // We will need to wait users choice
+ DEBUG("[E] Waiting for CIF closure (recovery failed)");
+ // Wait the close or reload command from the user
+ m_cif->resetClose();
+ m_cif->waitClose();
+ // This may be misleading, but the behavior at this point is the same as aborted
+ continueExecuting = reloadOrClose();
+ break;
+ }
+ default:
+ break;
+ }
+ return continueExecuting;
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::save
+//=============================================================================
+void SPELLserviceImpl::save()
+{
+ DEBUG("[E] Saving on demand");
+ try
+ {
+ // Restore the state from persistent file
+ m_frameManager->saveState();
+ }
+ catch(SPELLcoreException& ex)
+ {
+ std::string msg = "Save state failed: " + std::string(ex.what());
+ m_cif->notifyError( msg, ex.what(), true);
+ LOG_ERROR(msg);
+ }
+ DEBUG("[E] Saving on demand done");
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::recover
+//=============================================================================
+void SPELLserviceImpl::recover()
+{
+ DEBUG("[E] Recovering service execution");
+
+ try
+ {
+ // Load the SPELL driver
+ loadDriver();
+
+ // Load the builtin databases, etc.
+ loadExecutionEnvironment();
+
+ // Restore the state from persistent file
+ m_frameManager->restoreState();
+
+ // Re-create the internal callstack model
+ m_frameManager->replayStack( m_callstack );
+ }
+ catch(SPELLcoreException& ex)
+ {
+ std::string msg = "Recovery failed, could not restore state: " + std::string(ex.what());
+ m_cif->notifyError( msg, ex.what(), true);
+ LOG_ERROR(msg);
+ PyEval_SetTrace( NULL, NULL );
+ DEBUG("[E] Waiting for CIF closure");
+ m_cif->waitClose();
+ return;
+ }
+ DEBUG("[E] Execution recovery finished");
+ executeInternal(false);
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::finalize
+//=============================================================================
+void SPELLserviceImpl::finalize()
+{
+ DEBUG("[E] Finalizing, user request closure");
+ // Release the CIF lock, the controller received the close command
+ // so we can proceed
+ m_cif->canClose();
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::loadExecutionEnvironment
+//=============================================================================
+void SPELLserviceImpl::loadExecutionEnvironment()
+{
+ DEBUG("[E] Loading execution environment");
+
+ // Check for Python errors
+ SPELLpythonHelper::instance().checkError();
+
+ // Load SCDB and GDB
+ SPELLdatabaseManager::instance().loadBuiltinDatabases();
+
+ // Create proc dictionary object and install it
+ PyObject* procObj = PyDict_New();
+ PyObject* pname = SSTRPY(m_instanceId);
+ PyObject* arguments = SSTRPY(getConfiguration().getArguments());
+ PyObject* outputDataDir = SSTRPY( m_outputDir );
+ PyObject* inputDataDir = SSTRPY( m_inputDir );
+ PyObject* parentId = SSTRPY( getConfiguration().getParentProcId() );
+
+ PyDict_SetItemString( procObj, DatabaseConstants::NAME.c_str(), pname);
+ PyDict_SetItemString( procObj, DatabaseConstants::ARGS.c_str(), arguments);
+ PyDict_SetItemString( procObj, DatabaseConstants::STEP.c_str(), Py_None);
+ PyDict_SetItemString( procObj, DatabaseConstants::PREV_STEP.c_str(), Py_None);
+ PyDict_SetItemString( procObj, DatabaseConstants::OUTPUT_DATA.c_str(), outputDataDir);
+ PyDict_SetItemString( procObj, DatabaseConstants::INPUT_DATA.c_str(), inputDataDir);
+ PyDict_SetItemString( procObj, DatabaseConstants::PARENT.c_str(), parentId);
+
+ SPELLpythonHelper::instance().install( procObj, DatabaseConstants::PROC );
+ SPELLpythonHelper::instance().checkError();
+
+ bool success = true;
+ std::string importErrors = "";
+
+ if (m_libPath != "")
+ {
+ if (m_libPath.find(",") != std::string::npos)
+ {
+ std::vector items = SPELLutils::tokenize(m_libPath,",");
+ std::vector::const_iterator cit;
+ for(cit = items.begin(); cit != items.end(); cit++)
+ {
+ success = success && SPELLpythonHelper::instance().importUserLibraries( *cit, importErrors );
+ }
+ }
+ else
+ {
+ try
+ {
+ success = success && SPELLpythonHelper::instance().importUserLibraries( m_libPath, importErrors );
+ }
+ catch(SPELLcoreException& ex)
+ {
+ importErrors += "\n - Failed to import user libraries from '" + m_libPath + "': " + ex.what();
+ }
+ }
+ }
+ else
+ {
+ LOG_INFO("No user libraries defined");
+ }
+
+
+ if (!success)
+ {
+ THROW_EXCEPTION("Initialization failed", "\nErrors detected in UserLib: " + importErrors, SPELL_ERROR_EXECUTION);
+ }
+
+ // Tell the execution frame that the environment has been updated
+ m_frameManager->filterDictUpdated();
+
+ DEBUG("[E] Loading execution environment done");
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::loadDriver
+//=============================================================================
+void SPELLserviceImpl::loadDriver()
+{
+ DEBUG("#############################################################");
+ DEBUG("[E] Load driver - start");
+
+ // Check for Python errors
+ SPELLpythonHelper::instance().checkError();
+
+ SPELLnoCommandProcessing nc;
+
+ LOG_INFO("Loading driver on context " + getConfiguration().getContextName());
+ // Prepare and load the SPELL driver
+ SPELLdriverManager::instance().setup( getConfiguration().getContextName() );
+
+ // Enable TC confirmation if so said the config
+ if (getConfiguration().isForceTcConfirm())
+ {
+ setForceTcConfirmInternal(true);
+ }
+
+ if (getConfiguration().isForcePromptConfirm())
+ {
+ setForcePromptConfirmInternal(true);
+ }
+
+ // Load the driver language specifics
+ SPELLcontextConfig& ctxConfig = SPELLconfiguration::instance().getContext( getConfiguration().getContextName() );
+ std::string driverName = ctxConfig.getDriverName();
+ SPELLdriverConfig& drvConfig = SPELLconfiguration::instance().getDriver( driverName );
+
+ std::string path = drvConfig.getPath() + PATH_SEPARATOR + drvConfig.getIdentifier();
+
+ path = SPELLutils::resolvePath(path);
+
+ DEBUG("[E] Driver files loaded in " + path);
+
+ // Import modifiers
+ std::string package = "";
+ std::string moduleFile = path + PATH_SEPARATOR + "modifiers.py";
+ DEBUG("[E] Checking for module " + moduleFile);
+ if (SPELLutils::isFile( moduleFile ))
+ {
+ package = drvConfig.getIdentifier() + ".modifiers";
+ DEBUG("[E] Importing driver package " + package);
+ SPELLpythonHelper::instance().importAllFrom( package );
+ }
+
+ // Import constants
+ moduleFile = path + PATH_SEPARATOR + "constants.py";
+ DEBUG("[E] Checking for module " + moduleFile);
+ if (SPELLutils::isFile( moduleFile ))
+ {
+ package = drvConfig.getIdentifier() + ".constants";
+ DEBUG("[E] Importing driver package " + package);
+ SPELLpythonHelper::instance().importAllFrom( package );
+ }
+
+ // Import functions
+ moduleFile = path + PATH_SEPARATOR + "functions.py";
+ DEBUG("[E] Checking for module " + moduleFile);
+ if (SPELLutils::isFile( path + PATH_SEPARATOR + "functions.py" ))
+ {
+ package = drvConfig.getIdentifier() + ".functions";
+ DEBUG("[E] Importing driver package " + package);
+ SPELLpythonHelper::instance().importAllFrom( package );
+ }
+ SPELLpythonHelper::instance().checkError();
+
+ DEBUG("[E] Load driver - end");
+ DEBUG("#############################################################");
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::unloadDriver
+//=============================================================================
+void SPELLserviceImpl::unloadDriver( bool shutdown )
+{
+ try
+ {
+ DEBUG("[E] Unload driver - start");
+
+ SPELLnoCommandProcessing nc;
+
+ // Just cleanup driver if reload/recover will be done
+ SPELLdriverManager::instance().cleanup(shutdown);
+
+ DEBUG("[E] Unload driver - end");
+ }
+ catch(SPELLcoreException& ex)
+ {
+ throw ex;
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::handleExecutionError
+//=============================================================================
+const SPELLserviceImpl::AfterError SPELLserviceImpl::handleExecutionError()
+{
+ AfterError result = CANNOT_RECOVER;
+ SPELLcoreException* exc = SPELLerror::instance().getError();
+ bool canRestore = m_frameManager->haveWarmStart();
+ bool fatalError = exc->isFatal() || (!canRestore);
+ LOG_ERROR("[E] Execution failed: " + exc->what() + " can restore: " + BSTR(canRestore) + ", fatal: " + BSTR(exc->isFatal()));
+
+ // If the error is inside user library, we do not allow recovery
+ // to browsable lib ON to show where the error was.
+ std::string location = SPELLerror::instance().getErrorLocation();
+ DEBUG("[E] Error location is " + location);
+ if ((location != "")&& (m_libPath != ""))
+ {
+ if (location.find(m_libPath) == 0)
+ {
+ m_controller->setError( "Error happened in user library: " + exc->getError(), exc->getReason(), true );
+ return CANNOT_RECOVER;
+ }
+ }
+
+ DEBUG("[E] Notify error to controller");
+ // Otherwise notify the error normally
+ m_controller->setError( "Execution aborted: " + exc->getError(), exc->getReason(), fatalError );
+
+ // If the execution frame has warmstart information
+ if ( canRestore )
+ {
+ // Wait user request to reload or abort
+ LOG_INFO("[E] Waiting for recover command");
+ m_cif->waitClose();
+ // This will tell us if the user wants recovery or not
+ bool doRecover = m_controller->shouldRecover();
+ LOG_INFO("[E] Recovery flag: " + ( doRecover ? STR("enabled") : STR("disabled")));
+ DEBUG("Do recover flag: " + BSTR(doRecover));
+ if (doRecover)
+ {
+ LOG_INFO("[E] Recovering execution");
+ m_cif->warning("Recovering execution from failure", LanguageConstants::SCOPE_SYS );
+ try
+ {
+ try
+ {
+ // No commands processed in the meantime
+ SPELLnoCommandProcessing nc;
+ // Recover the state in the frame
+ m_frameManager->fixState();
+ // Set the callstack in recovery mode so that
+ // the next module call event is not processed, and
+ // therefore add a spurious element to the stack
+ m_callstack->setRecoveryMode();
+ }
+ catch(SPELLcoreException& ex)
+ {
+ throw ex;
+ }
+
+ // Now re-invoke execution
+ DEBUG("[E] Re-executing");
+ PyErr_Clear();
+ result = RECOVER_SUCCESS;
+ }
+ catch(SPELLcoreException& ex)
+ {
+ std::string msg = "[E] Recovery failed: " + ex.what();
+ LOG_ERROR(msg);
+ DEBUG(msg);
+ m_cif->notifyError("Recovery failed", ex.what(), true);
+ result = RECOVER_FAILED;
+ }
+ }
+ else
+ {
+ LOG_WARN("[E] Recovery cancelled by user");
+ m_cif->warning("Recovery cancelled, procedure will be aborted", LanguageConstants::SCOPE_SYS );
+ result = CANCEL_RECOVER;
+ }
+ }
+ else
+ {
+ LOG_ERROR("Recovery failed, warm start mechanism disabled");
+ m_cif->notifyError("Recovery failed", "Warm start mechanism disabled", true);
+ // result is already CANNOT_RECOVER
+ }
+ return result;
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::dispatch
+//=============================================================================
+int SPELLserviceImpl::dispatch( PyObject* obj, PyFrameObject* frame, int what, PyObject* args )
+{
+ //SPELLmonitor m(m_dspLock);
+
+ // Do not dispatch if the notified code is not a procedure
+ std::string file = PYSTR(frame->f_code->co_filename);
+
+ //DEBUG("[DISPATCH] Processing file '" + file + "'")
+ //DEBUG("[DISPATCH] Proc path: '" + m_procPath + "'")
+ //DEBUG("[DISPATCH] Lib path: '" + m_libPath + "'")
+
+ bool notProc = (file.find(m_servicePath) == std::string::npos);
+ bool notUserLib = true;
+ if (notProc)
+ {
+ notUserLib = (m_libPath == "") || (file.find(m_libPath) == std::string::npos);
+ if (notUserLib) return 0;
+ }
+
+ // Filter importing state
+ std::string name = PYSTR(frame->f_code->co_name);
+ // Do not dispatch if the interpreter is importing a file
+ if (m_importChecker.isImporting(what,file,frame->f_lineno,name)) return 0;
+
+ // Extract the rest of information
+ std::string path = PYSTR(frame->f_code->co_filename);
+
+ // Will provide procedure or user library id
+ std::string procId = this->m_instanceId;
+
+ int lineno = frame->f_lineno;
+ std::string etype = dispatchDataType(what);
+
+ //DEBUG("[DISPATCH] START Dispatch event in " + procId + ":" + ISTR(lineno));
+ //DEBUG(" (" + name + ") at " + PYCREPR(frame));
+ //DEBUG(" event type " + etype);
+// std::cerr << "################################################################################" << std::endl;
+// std::cerr << "[DISPATCH] Dispatch event in " + procId + ":" + ISTR(lineno) + " (" + name + ") at " + PYCREPR(frame) << std::endl;
+// std::cerr << "################################################################################" << std::endl;
+
+ // Notify the frame manager to update the frame. This way, the internal models are
+ // created/updated at the proper time following the procedure execution. This call
+ // must be done before any other call to the frame manager that makes use of the
+ // 'procedure execution model object', because it is first created at this point.
+ m_frameManager->updateCurrentFrame(frame, what );
+
+ // INIT step feature
+ // IMPORTANT for this first if, there is no frame model until the first CALL dispatch
+ // has been processed. So we cannot use getModel() until then. That is why we have
+ // first the check to be PyTrace_LINE.
+ if (!m_initStepDone &&
+ what == PyTrace_LINE &&
+ m_frameManager->isAtInitialFrame() &&
+ m_frameManager->getModel().hasInitStep())
+ {
+ getCIF().disableNotifications();
+
+ if (checkInitStep(lineno))
+ {
+ m_initLines.push_back(lineno);
+ return 0;
+ }
+ else
+ {
+ LOG_INFO("INIT step mode finished");
+ // Use the callstack to notify the executed lines during INIT step, all together,
+ // to the controlling client. We do not care about dispatch and control during
+ // init mode, but we want to mark the appropriate lines as executed.
+ std::list::const_iterator it;
+ for( it = m_initLines.begin(); it != m_initLines.end(); it++ )
+ {
+ getCallstack().callbackEventLine(frame, procId, (*it), name);
+ }
+ m_initLines.clear();
+
+ // Re-enable notifications once INIT step is reached
+ getCIF().enableNotifications();
+ }
+ }
+
+ // Browsable lib feature: if the flag is enabled, allow browsing inside the user library.
+ // this means that dispatch shall continue when notUserLib is false --> we make it true.
+ notUserLib = notUserLib | (getConfiguration().getBrowsableLib()==ON);
+
+ // By-step feature: if enabled, pause on each Step statement
+ // Note that checkByStep cannot be used on the very first CALL notification
+ // as the current SPELLexecutionModel is not created yet, therefore there would
+ // be a segmentation fault.
+ if ( (what == PyTrace_LINE) && getConfiguration().isByStep()) checkByStep(lineno);
+
+ // Breakpoint feature: pause on the breakpoints
+ checkBreakpoint(procId,lineno);
+
+ // Hold the dispatching mechanism if there are commmands to be processed,
+ // and until the command finishes
+ {
+ SPELLsafeThreadOperations ops("SPELLexecutorImpl::dispatch()");
+ m_controller->waitCommand();
+ }
+
+ // Repeat flag is used for certain cases of skip mechanism.
+ bool repeat = true;
+ // Will be false if the execution has been aborted (the controller knows this)
+ // if the execution has been aborted, dispatching wont be done in control objects below.
+ bool statusOk = true;
+ while(repeat)
+ {
+ // Check aborted state beforehand
+ statusOk = m_controller->checkAborted();
+ repeat = false;
+
+ // Here is the in-language goto mechanism implementation. Whenever the current line is
+ // a line with a programmed goto (there is a target line in the Goto model) the frame
+ // lineno will be changed accordingly.
+ if (m_gotoTarget != "")
+ {
+ try
+ {
+ repeat = repeat || m_frameManager->goLabel(m_gotoTarget, false, true);
+ lineno = frame->f_lineno;
+ m_gotoTarget = "";
+ }
+ catch(SPELLcoreException& ex)
+ {
+ m_gotoTarget = "";
+ abort(ex.what(),true);
+ statusOk = false;
+ }
+ }
+
+ // If not aborted and not in User library, perform the data dispatch to each control object
+ if (statusOk && notUserLib)
+ {
+ //DEBUG("[DISPATCH] Will do dispatch");
+ switch(what)
+ {
+ case PyTrace_EXCEPTION:
+ {
+ DEBUG("[DISPATCH] Exception " + procId + ":" + ISTR(lineno) );
+ DEBUG("[DISPATCH] Args: " + PYREPR(args) );
+ DEBUG("[DISPATCH] Going to error state");
+
+ notifyErrorEvent( frame, procId, lineno, name );
+
+ if ( processException( args, lineno ) )
+ {
+ DEBUG("[DISPATCH] Exception is SPELL");
+ return 0;
+ }
+
+ DEBUG("[DISPATCH] Python exception");
+ statusOk = false;
+ break;
+ }
+ case PyTrace_LINE:
+ {
+ notifyLineEvent( frame, procId, lineno, name );
+ break;
+ }
+ case PyTrace_CALL:
+ {
+ // No Call/Return events for Services ar necessary
+ if (m_frameManager->isAtInitialFrame())
+ notifyCallEvent( frame, procId, lineno, name );
+ break;
+ }
+ case PyTrace_RETURN:
+ {
+ // No Call/Return events for Services ar necessary
+ if (m_frameManager->isAtInitialFrame())
+ notifyReturnEvent( frame, procId, lineno, name );
+ break;
+ }
+ default:
+ LOG_ERROR("[DISPATCH] Uncontrolled event " + procId + ":" + ISTR(lineno) );
+ break;
+ }
+ }
+ lineno = frame->f_lineno;
+ repeat = m_controller->shallRepeat();
+ }
+
+ // If we are terminating/aborting the execution, tell the frame to move to the end of
+ // the bytecode. This way we guarantee nothing will be executed.
+ if(!m_controller->checkAborted())
+ {
+ m_frameManager->terminate();
+ return -1;
+ }
+
+ return 0;
+// DEBUG("[DISPATCH] EXIT dispatch event in " + procId + ":" + ISTR(frame->f_lineno));
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::processException
+//=============================================================================
+bool SPELLserviceImpl::processException( PyObject* data, int lineno )
+{
+ // Check if it is a SPELL exception (syntax, driver, etc). If so,
+ // we want to KEEP the dispatching mechanism on because we still are
+ // executing a procedure normally.
+ // Handle name errors
+ PyObject* errValue = PyTuple_GetItem(data,1);
+ bool isSpell = SPELLpythonHelper::instance().isInstance( errValue, "SpellException", "spell.lib.exception" );
+
+ // If we are in a try block there will be no error report,
+ // but inform the user about the catched exception
+ if (m_frameManager->getModel().isInTryBlock( lineno ))
+ {
+ PyObject* errType = PyTuple_GetItem(data,0);
+ PyObject* errTb = PyTuple_GetItem(data,2);
+ SPELLcoreException* ex = SPELLerror::instance().errorToException( errType, errType, errValue, errTb );
+ if (isSpell)
+ {
+ m_cif->write( "SPELL exception: " + PYREPR(errValue), LanguageConstants::SCOPE_SYS);
+ }
+ else if (ex)
+ {
+ m_cif->write( ex->what(), LanguageConstants::SCOPE_SYS );
+ }
+ }
+
+ return isSpell;
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::setRunInto
+//=============================================================================
+void SPELLserviceImpl::setRunInto( const bool enabled )
+{
+ if (getConfiguration().isRunInto() != enabled)
+ {
+ LOG_INFO("[EXEC] Run into flag set to " + (enabled ? STR("ENABLED") : STR("DISABLED")));
+ getConfiguration().setRunInto(enabled);
+ m_controller->enableRunInto(enabled);
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::setByStep
+//=============================================================================
+void SPELLserviceImpl::setByStep( const bool enabled )
+{
+ if (getConfiguration().isByStep() != enabled)
+ {
+ LOG_INFO("[EXEC] By step flag set to " + (enabled ? STR("ENABLED") : STR("DISABLED")));
+ getConfiguration().setByStep(enabled);
+ /** \todo configure for dispatch */
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::setBrowsableLib
+//=============================================================================
+void SPELLserviceImpl::setBrowsableLib( const SPELLbrowsableLibMode& browsable )
+{
+ if (getConfiguration().getBrowsableLib() != browsable)
+ {
+ getConfiguration().setBrowsableLib(browsable);
+ LOG_INFO("[EXEC] Browsable lib flag set to " + browsableLibModeToString(browsable) );
+ /** \todo configure for dispatch */
+ }
+}
+
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::setBrowsableLib
+//=============================================================================
+void SPELLserviceImpl::setBrowsableLibStr( const std::string& browsableStr )
+{
+ if (getConfiguration().getBrowsableLibStr() != browsableStr)
+ {
+ getConfiguration().setBrowsableLibStr(browsableStr);
+ LOG_INFO("[EXEC] Browsable lib flag set to " + browsableStr);
+ /** \todo configure for dispatch */
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::setExecDelay
+//=============================================================================
+void SPELLserviceImpl::setExecDelay( const int delay )
+{
+ if (getConfiguration().getExecDelay() != delay)
+ {
+ LOG_INFO("[EXEC] Execution delay set to " + ISTR(delay) + " milliseconds");
+ getConfiguration().setExecDelay(delay);
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::setPromptWarningDelay
+//=============================================================================
+void SPELLserviceImpl::setPromptWarningDelay( const int delay )
+{
+ if (getConfiguration().getPromptWarningDelay() != delay)
+ {
+ LOG_INFO("[EXEC] Prompt warning delay set to " + ISTR(delay));
+ getConfiguration().setPromptWarningDelay(delay);
+ m_scheduler->setPromptWarningDelay(delay);
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::setForceTcConfirm
+//=============================================================================
+void SPELLserviceImpl::setForceTcConfirm( const bool force )
+{
+ if (getConfiguration().isForceTcConfirm() != force )
+ {
+ LOG_INFO("[EXEC] Set force TC confirmation to " + BSTR(force));
+ getConfiguration().setForceTcConfirm(force);
+ setForceTcConfirmInternal(force);
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::setForceTcConfirm
+//=============================================================================
+void SPELLserviceImpl::setForcePromptConfirm( const bool force )
+{
+ if (getConfiguration().isForcePromptConfirm() != force )
+ {
+ LOG_INFO("[EXEC] Set force Prompt confirmation to " + BSTR(force));
+ getConfiguration().setForcePromptConfirm(force);
+ setForcePromptConfirmInternal(force);
+ }
+}
+//=============================================================================
+// METHOD : SPELLexecutorImpl::command
+//=============================================================================
+void SPELLserviceImpl::setForceTcConfirmInternal( bool force )
+{
+ PyObject* tc = SPELLregistry::instance().get("TC");
+ if (tc != NULL)
+ {
+ PyObject* arg = force ? Py_True : Py_False;
+ SPELLpythonHelper::instance().callMethod( tc, "forceTcConfirm", arg, NULL );
+ }
+}
+//=============================================================================
+// METHOD : SPELLexecutorImpl::command
+//=============================================================================
+void SPELLserviceImpl::setForcePromptConfirmInternal( bool force )
+{
+ PyObject* tc = SPELLregistry::instance().get("CIF");
+ if (tc != NULL)
+ {
+ PyObject* arg = force ? Py_True : Py_False;
+ SPELLpythonHelper::instance().callMethod( tc, "forcePromptConfirm", arg, NULL );
+ }
+}
+//=============================================================================
+// METHOD : SPELLexecutorImpl::command
+//=============================================================================
+void SPELLserviceImpl::command( const ExecutorCommand& cmd, const bool high_priority )
+{
+ SPELLmonitor m(m_cmdLock);
+ DEBUG("[E] Issuing command " + cmd.id);
+ m_controller->command( cmd, (cmd.id != CMD_ABORT), high_priority );
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::abort
+//=============================================================================
+void SPELLserviceImpl::abort( const std::string& message, bool systemAborted )
+{
+ SPELLmonitor m(m_cmdLock);
+
+ // Send the finish message if any
+ if (message != "")
+ {
+ m_cif->warning(message, systemAborted ? LanguageConstants::SCOPE_SYS : LanguageConstants::SCOPE_PROC );
+ }
+
+ // Abort command is a special case which needs this method to process
+ // abort requests coming from the SPELL framework, not the user (in the
+ // former case abort shall be immediate, whereas in the latter the abort
+ // command shall wait till the language execution lock is released)
+ ExecutorCommand cmd_abort;
+ cmd_abort.id = CMD_ABORT;
+ m_controller->command( cmd_abort, false, true );
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::pause
+//=============================================================================
+void SPELLserviceImpl::pause()
+{
+ SPELLmonitor m(m_cmdLock);
+
+ // Pause command is a special case which needs this method to process
+ // pause requests coming from the SPELL framework, not the user.
+ ExecutorCommand cmd_pause;
+ cmd_pause.id = CMD_PAUSE;
+ m_controller->command( cmd_pause, false, true );
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::interrupt
+//=============================================================================
+void SPELLserviceImpl::interrupt()
+{
+ SPELLmonitor m(m_cmdLock);
+ ExecutorCommand cmd_int;
+ cmd_int.id = CMD_INTERRUPT;
+ m_controller->command( cmd_int, false, true );
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::finish
+//=============================================================================
+void SPELLserviceImpl::finish( const std::string& message )
+{
+ SPELLmonitor m(m_cmdLock);
+
+ // Send the finish message if any
+ if (message != "")
+ {
+ m_cif->warning(message, LanguageConstants::SCOPE_PROC );
+ }
+ // Finish command is a special case which needs this method to process
+ // finish requests coming from the SPELL framework, not the user.
+ ExecutorCommand cmd_finish;
+ cmd_finish.id = CMD_FINISH;
+ m_controller->command( cmd_finish, false, true );
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::processLock
+//=============================================================================
+void SPELLserviceImpl::processLock()
+{
+ // TODO: No reason to lock here. Remove once validated.
+ //SPELLmonitor m(m_cmdLock);
+ m_controller->executionLock();
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::processUnlock
+//=============================================================================
+void SPELLserviceImpl::processUnlock()
+{
+ // TODO: No reason to lock here. Remove once validated.
+ //SPELLmonitor m(m_cmdLock);
+ m_controller->executionUnlock();
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::canSkip
+//=============================================================================
+const bool SPELLserviceImpl::canSkip()
+{
+ // Allow skipping if in wait or interrupted state
+ SPELLexecutorStatus status = m_controller->getStatus();
+ if ((status == STATUS_WAITING)||(status == STATUS_INTERRUPTED)||(status == STATUS_PROMPT)) return true;
+ return m_frameManager->canSkip();
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::goNextLine
+//=============================================================================
+const bool SPELLserviceImpl::goNextLine()
+{
+ unsigned int currentLine = m_frameManager->getCurrentLine();
+ if (m_frameManager->getAST().isBlockStart(currentLine))
+ {
+ DEBUG("[E] Skipping entire code block");
+ unsigned int nextLine = m_frameManager->getAST().getBlockEnd(currentLine);
+ return goLine(nextLine);
+ }
+ else
+ {
+ DEBUG("[E] Skipping single line");
+ // When we skip the line, we dont want the callstack and trace model to register the current line
+ m_callstack->skipCurrentLine();
+ return m_frameManager->goNextLine();
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::goLabel
+//=============================================================================
+const bool SPELLserviceImpl::goLabel( const std::string& label, bool programmed )
+{
+ if (programmed)
+ {
+ m_gotoTarget = label;
+ return true;
+ }
+ else
+ {
+ m_gotoTarget = "";
+ // It is a manual goto: we want to report
+ bool result = m_frameManager->goLabel(label, true, false);
+ if (result)
+ {
+ // When we skip the line, we dont want the callstack and trace model to register the current line
+ m_callstack->skipCurrentLine();
+ }
+ else
+ {
+ m_cif->warning("Unable to go to label '" + label + "'", LanguageConstants::SCOPE_SYS );
+ }
+ return result;
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::goLine
+//=============================================================================
+const bool SPELLserviceImpl::goLine( const int new_lineno )
+{
+ // The frame manager will go to the given line only if possible, checks done inside
+ bool result = m_frameManager->goLine( new_lineno, true );
+ if (result)
+ {
+ // When we skip the line, we dont want the callstack and trace model to register the current line
+ m_callstack->skipCurrentLine();
+ }
+ return result;
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::setBreakpoint
+//=============================================================================
+const bool SPELLserviceImpl::setBreakpoint( const std::string& file,
+ const unsigned int line,
+ const SPELLbreakpointType type )
+{
+ return m_frameManager->getBreakpoints().setBreakpoint( file, line, type );
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::checkBreakpoint
+//=============================================================================
+void SPELLserviceImpl::checkBreakpoint( const std::string& file, const unsigned int line )
+{
+ if (m_controller->getStatus() == STATUS_RUNNING)
+ {
+ if (m_frameManager->getBreakpoints().checkBreakpoint(file,line))
+ {
+ DEBUG("[BYSTEP] Pausing procedure on breakpoint");
+ LOG_INFO("Breakpoint on line " + ISTR(line));
+ pause();
+ }
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::clearBreakpoints
+//=============================================================================
+void SPELLserviceImpl::clearBreakpoints()
+{
+ m_frameManager->getBreakpoints().clearBreakpoints();
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::checkByStep
+//=============================================================================
+const bool SPELLserviceImpl::checkByStep( const int& frameLine )
+{
+ // Only if we are not in background (headless)
+ if (getConfiguration().isHeadless()) return false;
+
+ if (m_frameManager->getModel().isLabel(frameLine))
+ {
+ DEBUG("[BYSTEP] Pausing procedure");
+ pause();
+ return true;
+ }
+ return false;
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::checkInitStep
+//=============================================================================
+const bool SPELLserviceImpl::checkInitStep( const int& frameLine )
+{
+ bool abortDispatching = false;
+ // Only if there is an INIT step in the code
+ if (m_frameManager->getModel().hasInitStep())
+ {
+ // Abort the dispatching unless the current line is the INIT line
+ abortDispatching = true;
+ if(m_frameManager->getModel().isInitStep( frameLine ))
+ {
+ LOG_INFO("Pausing on INIT step on line " + ISTR(frameLine));
+ m_initStepDone = true;
+ // Only if we are not in background (headless)
+ if (!getConfiguration().isHeadless()) pause();
+ // Continue dispatching so that the
+ // controller holds the execution in PAUSE
+ abortDispatching = false;
+ }
+ }
+ return abortDispatching;
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::runScript
+//=============================================================================
+const bool SPELLserviceImpl::runScript( const std::string& script )
+{
+ m_cif->setManualMode(true);
+ bool result = true;
+ try
+ {
+ m_frameManager->runScript( script );
+ }
+ catch(SPELLcoreException& ex)
+ {
+ result = false;
+ m_cif->warning("Failed to execute script: " + ex.what(), LanguageConstants::SCOPE_SYS );
+ }
+ m_cif->setManualMode(false);
+ return result;
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::executeUserAction()
+//=============================================================================
+void SPELLserviceImpl::executeUserAction()
+{
+ if (m_userAction.isEnabled())
+ {
+ LOG_INFO("Executing user action function '" + m_userAction.getAction() + "'");
+ try
+ {
+ SPELLpythonHelper::instance().checkError();
+ m_cif->warning("Running user action '" + m_userAction.getAction() + "'", LanguageConstants::SCOPE_SYS );
+ std::string actionScript = m_userAction.getAction() + "()";
+ m_frameManager->runScript( actionScript );
+ }
+ catch(SPELLcoreException& ex)
+ {
+ LOG_ERROR("Failed to execute user action: " + ex.what());
+ m_cif->error("Failed to execute user action: " + ex.what(), LanguageConstants::SCOPE_SYS );
+ }
+ }
+ else
+ {
+ LOG_WARN("Cannot execute user action, not enabled");
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::setUserAction()
+//=============================================================================
+void SPELLserviceImpl::setUserAction( const SPELLuserAction& action )
+{
+ m_userAction = action;
+ m_cif->notifyUserActionSet(action.getLabel(),action.getSeverity());
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::enableUserAction()
+//=============================================================================
+void SPELLserviceImpl::enableUserAction( bool enable )
+{
+ m_userAction.enable(enable);
+ m_cif->notifyUserActionEnable(enable);
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::dismissUserAction()
+//=============================================================================
+void SPELLserviceImpl::dismissUserAction()
+{
+ m_userAction.reset();
+ m_cif->notifyUserActionUnset();
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::stageReached
+//=============================================================================
+void SPELLserviceImpl::stageReached( const std::string& id, const std::string& title )
+{
+ displayStage(id,title);
+ // Notify the event to the excecution frame
+ m_frameManager->eventStage();
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::
+//=============================================================================
+void SPELLserviceImpl::displayStage( const std::string& id, const std::string& title )
+{
+ if (title != "")
+ {
+ m_cif->write("Step " + id + ": " + title, LanguageConstants::SCOPE_STEP );
+ }
+ else
+ {
+ m_cif->write("Step " + id, LanguageConstants::SCOPE_STEP );
+ }
+ // Change also in callstack
+ m_callstack->setStage(id,title);
+
+ // Update the data in the procedure
+ PyObject* proc = getVariableManager().getVariableRef(DatabaseConstants::PROC);
+ if (proc != NULL)
+ {
+ SPELLsafePythonOperations ops("SPELLexecutor::displayStage()");
+ PyObject* pyId = SSTRPY(id);
+ PyObject* pyDesc = SSTRPY(title);
+ PyObject* list = PyList_New(2);
+ PyList_SetItem(list,0,pyId);
+ PyList_SetItem(list,1,pyDesc);
+ Py_INCREF(pyId);
+ Py_INCREF(pyDesc);
+
+ // Get the previous step value if any
+ PyObject* prev = PyDict_GetItemString(proc, DatabaseConstants::STEP.c_str());
+
+ // Set the new value
+ PyDict_SetItemString( proc, DatabaseConstants::STEP.c_str(), list);
+
+ // If there was a previous value, set it as PREVIOUS
+ if (prev != NULL)
+ {
+ PyDict_SetItemString( proc, DatabaseConstants::PREV_STEP.c_str(), prev);
+ }
+ }
+
+ // prepares the message to be sent to GUI
+ m_cif->resetClose();
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::
+//=============================================================================
+void SPELLserviceImpl::addDispatchListener( SPELLdispatchListener* listener )
+{
+ if (std::find(m_listeners.begin(), m_listeners.end(), listener) == m_listeners.end())
+ {
+ DEBUG( "Added listener " + listener->getId() );
+ m_listeners.push_back(listener);
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::
+//=============================================================================
+void SPELLserviceImpl::removeDispatchListener( SPELLdispatchListener* listener )
+{
+ SPELLdispatchListeners::iterator it = std::find(m_listeners.begin(), m_listeners.end(), listener);
+ if (it != m_listeners.end())
+ {
+ DEBUG( "Removed listener " + listener->getId() );
+ m_listeners.erase(it);
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::
+//=============================================================================
+void SPELLserviceImpl::notifyLineEvent( PyFrameObject* frame, const std::string& file, const int line, const std::string& name )
+{
+ //DEBUG( "Notify listeners: line event");
+ SPELLdispatchListeners::iterator it;
+ for( it = m_listeners.begin(); it != m_listeners.end(); it++)
+ {
+ //DEBUG( " - notify dispatch listener " + (*it)->getId() );
+ (*it)->callbackEventLine( frame, file, line, name );
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::
+//=============================================================================
+void SPELLserviceImpl::notifyCallEvent( PyFrameObject* frame, const std::string& file, const int line, const std::string& name )
+{
+ //DEBUG( "Notify listeners: call event");
+ SPELLdispatchListeners::iterator it;
+ for( it = m_listeners.begin(); it != m_listeners.end(); it++)
+ {
+ //DEBUG( " - notify dispatch listener " + (*it)->getId() );
+ (*it)->callbackEventCall( frame, file, line, name );
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::
+//=============================================================================
+void SPELLserviceImpl::notifyReturnEvent( PyFrameObject* frame, const std::string& file, const int line, const std::string& name )
+{
+ //DEBUG( "Notify listeners: return event");
+ SPELLdispatchListeners::iterator it;
+ for( it = m_listeners.begin(); it != m_listeners.end(); it++)
+ {
+ //DEBUG( " - notify dispatch listener " + (*it)->getId() );
+ (*it)->callbackEventReturn( frame, file, line, name );
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLexecutorImpl::
+//=============================================================================
+void SPELLserviceImpl::notifyErrorEvent( PyFrameObject* frame, const std::string& file, const int line, const std::string& name )
+{
+ DEBUG( "Notify listeners: error event");
+ SPELLdispatchListeners::iterator it;
+ for( it = m_listeners.begin(); it != m_listeners.end(); it++)
+ {
+ DEBUG( " - notify dispatch listener " + (*it)->getId() );
+ (*it)->callbackEventError( frame, file, line, name );
+ }
+ DEBUG( "Notify listeners: error event done");
+}
diff --git a/lib/SPELL_EXC/src/SPELLserviceInterpreter.C b/lib/SPELL_EXC/src/SPELLserviceInterpreter.C
new file mode 100644
index 0000000..c099963
--- /dev/null
+++ b/lib/SPELL_EXC/src/SPELLserviceInterpreter.C
@@ -0,0 +1,532 @@
+// ################################################################################
+// FILE : SPELLinterpreter.C
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Implementation of the custom interpreter
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// System includes ---------------------------------------------------------
+// Local includes ----------------------------------------------------------
+#include "SPELL_EXC/SPELLserviceInterpreter.H"
+#include "SPELL_EXC/SPELLgoto.H"
+#include "SPELL_EXC/SPELLexecutor.H"
+#include "SPELL_EXC/SPELLexecutorStatus.H"
+#include "SPELL_EXC/SPELLcontroller.H"
+#include "SPELL_EXC/SPELLscheduler.H"
+#include "SPELL_EXC/SPELLcallstack.H"
+#include "SPELL_EXC/SPELLexecutorImpl.H"
+#include "SPELL_PRD/SPELLservicePython.H"
+// Project includes --------------------------------------------------------
+#include "SPELL_PRD/SPELLprocedureManager.H"
+#include "SPELL_UTIL/SPELLerror.H"
+#include "SPELL_UTIL/SPELLlog.H"
+#include "SPELL_UTIL/SPELLpythonHelper.H"
+#include "SPELL_UTIL/SPELLutils.H"
+#include "SPELL_CFG/SPELLconfiguration.H"
+#include "SPELL_WRP/SPELLregistry.H"
+#include "SPELL_WRP/SPELLdriverManager.H"
+#include "SPELL_WS/SPELLwsWarmStartImpl.H"
+#include "SPELL_WS/SPELLwsStartupInfo.H"
+#include "SPELL_CIF/SPELLcif.H"
+#include "SPELL_WRP/SPELLdatabaseManager.H"
+
+// GLOBALS /////////////////////////////////////////////////////////////////
+
+// Interpreter singleton instance
+static SPELLserviceInterpreter* s_instance = NULL;
+
+// Warmstart location name
+static const std::string WS_LOCATION = "ws";
+static const std::string ASRUN_LOCATION = "ar";
+
+//=============================================================================
+// CONSTRUCTOR: SPELLinterpreter::SPELLinterpreter
+//=============================================================================
+SPELLserviceInterpreter::SPELLserviceInterpreter()
+{
+ m_serviceImpl = NULL;
+ m_cif = NULL;
+ m_controller = NULL;
+ m_scheduler = NULL;
+ m_callstack = NULL;
+ m_frameManager = NULL;
+ m_warmStart = NULL;
+ m_servicePath = "";
+ m_service = "";
+}
+
+//=============================================================================
+// DESTRUCTOR: SPELLinterpreter::~SPELLinterpreter
+//=============================================================================
+SPELLserviceInterpreter::~SPELLserviceInterpreter()
+{
+ DEBUG("[*] Cleaning up");
+ if (m_warmStart != NULL)
+ {
+ DEBUG("[*] Cleaning warm start mechanism");
+ delete m_warmStart;
+ m_warmStart = NULL;
+ }
+ if (m_callstack != NULL)
+ {
+ delete m_callstack;
+ m_callstack = NULL;
+ }
+ if (m_controller != NULL)
+ {
+ delete m_controller;
+ m_controller = NULL;
+ }
+ if (m_scheduler != NULL)
+ {
+ delete m_scheduler;
+ m_scheduler = NULL;
+ }
+ if (m_serviceImpl != NULL)
+ {
+ delete m_serviceImpl;
+ m_serviceImpl = NULL;
+ }
+ SPELLpythonHelper::instance().finalize();
+ DEBUG("[*] End");
+}
+
+//=============================================================================
+// METHOD : SPELLinterpreter::instance
+//=============================================================================
+SPELLserviceInterpreter& SPELLserviceInterpreter::instance()
+{
+ if (s_instance == NULL)
+ {
+ s_instance = new SPELLserviceInterpreter();
+ }
+ return *s_instance;
+}
+
+//=============================================================================
+// METHOD : SPELLinterpreter::initialize
+//=============================================================================
+void SPELLserviceInterpreter::initialize( const SPELLinterpreterConfig& config, SPELLcif* cif )
+{
+ LOG_INFO("[*] Initializing interpreter");
+
+ m_cif = cif;
+ m_service = config.procId;
+ m_config = config;
+}
+
+//=============================================================================
+// METHOD : SPELLinterpreter::mainLoop
+//=============================================================================
+void SPELLserviceInterpreter::mainLoop()
+{
+ // Load the SPELL configuration (will fail with exception if there is an error)
+ SPELLconfiguration::instance().loadConfig(m_config.configFile);
+
+ // Configure the time format if defined in configuration
+ std::string format = SPELLconfiguration::instance().getCommonParameter("TdsTimeFormat");
+ if (format.length()!=0)
+ {
+ if (format.compare ("1") == 0)
+ {
+ SPELLutils::setTimeFormat(TIME_FORMAT_SLASH);
+ }
+ else if (format.compare("0")==0)
+ {
+ SPELLutils::setTimeFormat(TIME_FORMAT_DOT);
+ }
+ }
+
+ LOG_INFO("[***] Start main loop");
+
+ // Create and connect all execution control objects
+ if (prepareObjects())
+ {
+ SPELLsafePythonOperations ops("Service Init");
+ // Now try to initialize (compile) the execution frame.
+ if (prepareExecution())
+ {
+ // If we are in recovery mode:
+ if (m_config.recover)
+ {
+ recover();
+ }
+ else // Or we are in running mode
+ {
+ execute();
+ }
+ }
+
+ // After the execution cycle, wait for the user/server to autorize closure
+ DEBUG("[***] Main loop waiting for CIF");
+ m_cif->waitClose();
+
+ // Once all is finished, stop controller
+ DEBUG("[***] Stopping command controller");
+ m_controller->stop();
+
+ DEBUG("[***] Cleaning CIF");
+ m_cif->cleanup(false);
+ }
+
+ // Cleanup all warm start files
+ if (m_warmStart)
+ {
+ m_warmStart->cleanup();
+ }
+
+ LOG_INFO("[***] End main loop");
+}
+
+//=============================================================================
+// METHOD : SPELLinterpreter::prepareWarmStart
+//=============================================================================
+void SPELLserviceInterpreter::prepareWarmStart( const SPELLcontextConfig& ctxConfig )
+{
+ // Prepare warmstart file if applicable
+ if (m_config.warmstart)
+ {
+ char* home = getenv("SPELL_DATA");
+ if (home == NULL)
+ {
+ std::string msg = "Unable to setup persistent file, no SPELL_DATA environment variable defined";
+ LOG_ERROR(" " + msg);
+ m_cif->error(msg, LanguageConstants::SCOPE_SYS );
+ m_config.warmstart = false;
+ return;
+ }
+
+ // Get the location of WS files
+ std::string wsdir = ctxConfig.getLocationPath( WS_LOCATION );
+ std::string saveMode = ctxConfig.getExecutorParameter(ExecutorConstants::SaveStateMode);
+
+ // Prepare the WS configuration
+ SPELLwsStartupInfo startup;
+
+ if (saveMode == "DISABLED")
+ {
+ LOG_WARN("Warmstart disabled by configuration");
+ startup.persistentFile = "";
+ }
+ else
+ {
+ startup.persistentFile = STR(home) + PATH_SEPARATOR + wsdir + PATH_SEPARATOR;
+ // Check that the directory exists
+ if (!SPELLutils::pathExists(startup.persistentFile))
+ {
+ std::string msg = "Unable to setup persistent file, warm-start directory not found: " + startup.persistentFile;
+ LOG_ERROR(" " + msg);
+ m_cif->error(msg, LanguageConstants::SCOPE_SYS );
+ m_config.warmstart = false;
+ return;
+ }
+
+ // Character replacements for constructing the file ids
+ std::string theId = m_service;
+ SPELLutils::replace( theId, ".py", "" );
+ SPELLutils::replace( theId, "..", "" );
+ SPELLutils::replace( theId, "//", "/" );
+ SPELLutils::replace( theId, PATH_SEPARATOR, "__" );
+ startup.persistentFile += m_config.timeId + "_Executor_" + theId;
+ LOG_INFO("Warm start persistent file: " + startup.persistentFile);
+ }
+
+
+ LOG_INFO("Warm start files location: " + wsdir);
+ LOG_INFO("Warm start working mode: " + saveMode);
+ LOG_INFO("Warm start service file: " + m_service);
+
+
+ // Set the configured working mode
+ startup.workingMode = StringToWorkingMode(saveMode);
+
+ // Set the procedure file
+ startup.procedureFile = m_service;
+
+ // Set the recovery file if any
+ if (m_config.persis != "")
+ {
+ startup.recoveryFile = STR(home) + PATH_SEPARATOR + wsdir + PATH_SEPARATOR + m_config.persis;
+ startup.performRecovery = true;
+ }
+
+ try
+ {
+ // Create the warm start support
+ m_warmStart = new SPELLwsWarmStartImpl();
+ // Initialize it
+ m_warmStart->initialize( startup );
+ // Set the warm start support in the execution frame
+ m_frameManager->setWarmStart( m_warmStart );
+ }
+ catch(SPELLcoreException& ex)
+ {
+ if (m_warmStart != NULL) delete m_warmStart;
+ m_warmStart = NULL;
+ throw ex;
+ }
+ }
+ else
+ {
+ m_cif->warning("ATTENTION: no warmstart mechanism is being used", LanguageConstants::SCOPE_SYS );
+ LOG_WARN("[***] No warmstart mechanism will be used");
+ }
+}
+
+//=============================================================================
+// METHOD : SPELLinterpreter::prepareCIF
+//=============================================================================
+void SPELLserviceInterpreter::prepareCIF( const SPELLcontextConfig& ctxConfig )
+{
+ DEBUG(" Setup client interface");
+
+ // Create the configuration for the CIF
+ SPELLcifStartupInfo cifStartup;
+ cifStartup.procId = m_service;
+ cifStartup.procName = "service startups";
+ cifStartup.contextName = m_config.ctxName;
+ cifStartup.contextPort = m_config.ctxPort;
+ cifStartup.timeId = m_config.timeId;
+
+ m_cif->setup( cifStartup );
+}
+
+//=============================================================================
+// METHOD : SPELLinterpreter::prepareObjects
+//=============================================================================
+void SPELLserviceInterpreter::recoverCIF( const SPELLcontextConfig& ctxConfig )
+{
+ char* home = getenv("SPELL_DATA");
+ if (home == NULL)
+ {
+ std::string msg = "Unable to recover CIF asrun, no SPELL_DATA environment variable defined";
+ LOG_ERROR(" " + msg);
+ m_cif->error(msg, LanguageConstants::SCOPE_SYS );
+ return;
+ }
+
+ // Get the location of WS files
+ std::string ardir = ctxConfig.getLocationPath( ASRUN_LOCATION );
+
+ std::string originalAsRun = std::string(home) + PATH_SEPARATOR + ardir + PATH_SEPARATOR + m_config.persis + ".ASRUN";
+
+ m_cif->useAsRun( originalAsRun );
+}
+
+//=============================================================================
+// METHOD : SPELLinterpreter::prepareObjects
+//=============================================================================
+const bool SPELLserviceInterpreter::prepareObjects()
+{
+ LOG_INFO("[***] Preparing objects");
+ // Setup the client interface. The standalone one does
+ // just a few value initializations, the server one
+ // does the login in the context process
+ assert(m_cif != NULL);
+ bool result = true;
+ try
+ {
+ DEBUG(" Initializing Python interface");
+ SPELLpythonHelper::instance().initialize();
+ SPELLsafePythonOperations ops("Service Init");
+ // Install log support asap
+ Log_Install();
+ SpellService_Install();
+ DEBUG(" Loading execution framework functions");
+ // Setup the execution environment
+ SPELLpythonHelper::instance().loadFramework();
+
+ // Load the configuration on python side for the language and drivers
+ SPELLconfiguration::instance().loadPythonConfig(m_config.configFile);
+ // Get the context configuration
+ SPELLcontextConfig& ctxConfig = SPELLconfiguration::instance().getContext(m_config.ctxName);
+
+
+ // User library
+ m_libPath = SPELLprocedureManager::instance().getLibPath();
+
+ DEBUG(" Creating and linking");
+ // Create the executor instance
+ m_serviceImpl = new SPELLserviceImpl();
+ // Set the reference for the static accessor (Python layer and others)
+ SPELLexecutor::setInstance( m_serviceImpl );
+
+ m_controller = new SPELLcontroller( m_config.procId );
+ m_scheduler = new SPELLscheduler(false);
+ m_callstack = new SPELLcallstack();
+ // Create and initialize the execution frame
+ m_frameManager = new SPELLframeManager();
+
+ DEBUG(" Initializing Service");
+ // Initialize the executor with the objects
+ m_serviceImpl->initialize(m_cif, m_controller, m_scheduler, m_callstack, m_frameManager);
+
+ // Setup the CIF now
+ try
+ {
+ prepareCIF( ctxConfig );
+ }
+ catch(SPELLcoreException& ex)
+ {
+ // If we have no CIF there is no way to communicate anything. Bail out
+ LOG_ERROR("[FATAL] Failed to setup CIF: cannot start executor.");
+ LOG_ERROR("[FATAL] Error was: " + ex.what());
+ ::exit(EIO);
+ }
+
+
+ // Install the CIF object in the SPELL registry
+ DEBUG(" Installing client interface");
+ ClientIF_Install();
+
+ // Setup procedure manager
+ DEBUG(" Preparing procedure manager");
+ SPELLdriverManager::instance().setup(m_config.ctxName);
+ SPELLdatabaseManager::instance().loadBuiltinDatabases();
+ SPELLprocedureManager::instance().setup(m_config.ctxName);
+ SPELLpyService& service = SPELLprocedureManager::instance().getService(m_service);
+ m_servicePath = service.getBasePath();
+
+ // Prepare and configure warm start mechanism now
+ DEBUG(" Preparing warm start");
+ prepareWarmStart( ctxConfig );
+
+ // Let the executor prepare all the rest it needs for execution. Anything done here
+ // shall be independent from reloads/aborts, etc.
+ m_serviceImpl->prepare( m_service, ctxConfig );
+
+ DEBUG(" Starting controller");
+ m_controller->begin();
+
+ // If we are in recovery mode, recover also the original asrun file
+ if (m_config.persis != "")
+ {
+ recoverCIF( ctxConfig );
+ }
+
+ LOG_INFO("[***] Objects ready");
+ }
+ catch(SPELLcoreException& ex)
+ {
+ std::string msg = "[***] Failed to create objects: " + ex.what();
+ LOG_ERROR(msg);
+ // Notify error only if we have a way to do it, that is, no CIF failure.
+ if (m_controller)
+ {
+ m_controller->setError( "Failed to initialize: " + ex.getError(), ex.getReason(), true);
+ }
+ result = false;
+ }
+ return result;
+}
+
+//=============================================================================
+// METHOD : SPELLinterpreter::prepareExecution
+//=============================================================================
+const bool SPELLserviceInterpreter::prepareExecution()
+{
+ LOG_INFO("[***] Preparing execution");
+ try
+ {
+ DEBUG(" Installing executor binding");
+ Executor_Install();
+
+ DEBUG(" Installing goto bindings");
+ Goto_Install();
+ Step_Install();
+
+
+
+ if (m_config.script)
+ {
+ // In this case the proc path is just the script
+ //m_procPath = m_procedure;
+ LOG_INFO(" Compiling script");
+
+ }
+ else
+ {
+ LOG_INFO(" Compiling procedure");
+ // Compile and create initial execution frame
+ SPELLpyService& service = SPELLprocedureManager::instance().getService(m_service);
+ m_frameManager->initialize(service.getMainServiceFile());
+ }
+
+ // Set the procedures path
+ m_serviceImpl->setProcedurePath( m_servicePath );
+ // Set the user library path
+ m_serviceImpl->setLibraryPath( m_libPath );
+
+ LOG_INFO("Executor procedure path: " + m_servicePath);
+ LOG_INFO("Executor library path: " + m_libPath);
+
+ }
+ catch(SPELLcoreException& ex)
+ {
+ LOG_ERROR(" Catched error during preparation: " + ex.what());
+ m_controller->setError( "Error during preparation: " + ex.getError(), ex.getReason(), true);
+ return false;
+ }
+ LOG_INFO("[***] Execution ready");
+ return true;
+}
+
+//=============================================================================
+// METHOD : SPELLinterpreter::execute
+//=============================================================================
+void SPELLserviceInterpreter::execute()
+{
+ // Setup procedure manager
+ LOG_INFO("[*] Starting execution");
+
+ try
+ {
+ m_serviceImpl->execute();
+ }
+ catch(SPELLcoreException& ex)
+ {
+ LOG_ERROR("[FATAL] Error during execution: " + ex.what());
+ m_controller->setError( "Error during execution: " + ex.getError(), ex.getReason(), ex.isFatal());
+ }
+
+ LOG_INFO("[*] Execution finished");
+}
+
+//=============================================================================
+// METHOD : SPELLinterpreter::recover
+//=============================================================================
+void SPELLserviceInterpreter::recover()
+{
+ // Setup procedure manager
+ LOG_INFO("[*] Recovering execution from persistent file");
+ try
+ {
+ m_serviceImpl->recover();
+ }
+ catch(SPELLcoreException& ex)
+ {
+ LOG_ERROR("[FATAL] Error during recovery: " + ex.what());
+ /** \todo handle exception: send error */
+ }
+ LOG_INFO("[*] Execution finished");
+}
diff --git a/lib/SPELL_EXC/src/SPELLstepPython.C b/lib/SPELL_EXC/src/SPELLstepPython.C
index 5754b94..94655fc 100644
--- a/lib/SPELL_EXC/src/SPELLstepPython.C
+++ b/lib/SPELL_EXC/src/SPELLstepPython.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the Step Python bindings
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -80,8 +80,7 @@ static PyMethodDef Step_Methods[] =
//============================================================================
static PyTypeObject Step_Type =
{
- PyObject_HEAD_INIT(NULL)
- 0, //ob_size
+ PyVarObject_HEAD_INIT(NULL,0)
"executor.Step", //tp_name
sizeof(PyStepObject), //tp_basicsize
0, //tp_itemsize
@@ -135,7 +134,7 @@ static int Step_Init( PyStepObject* self, PyObject* args, PyObject* kwds )
//============================================================================
static void Step_Dealloc( PyStepObject* self )
{
- self->ob_type->tp_free( (PyObject*) self );
+ Py_TYPE(self)->tp_free( (PyObject*) self );
}
//============================================================================
diff --git a/lib/SPELL_EXC/src/SPELLvariableManager.C b/lib/SPELL_EXC/src/SPELLvariableManager.C
index 6888142..e16445b 100644
--- a/lib/SPELL_EXC/src/SPELLvariableManager.C
+++ b/lib/SPELL_EXC/src/SPELLvariableManager.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the procedure variable manager
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_EXC/src/SPELLvariableMonitor.C b/lib/SPELL_EXC/src/SPELLvariableMonitor.C
index c04e91e..bbbbcab 100644
--- a/lib/SPELL_EXC/src/SPELLvariableMonitor.C
+++ b/lib/SPELL_EXC/src/SPELLvariableMonitor.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the procedure variable monitor
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -92,12 +92,16 @@ void SPELLvariableMonitor::retrieveGlobalVariables()
std::string varName = PYSSTR(key);
PyObject* object = PyDict_GetItem( dict, key );
+ if (object == NULL) continue;
+
+ Py_XINCREF(object);
+
if (shouldDiscard(varName,object)) continue;
DEBUG("[VM] Processing " + varName);
std::string type = PYSSTR( PyObject_Type(object) );
- std::string value = PYREPR( object );
+ std::string value = PYCREPR( object );
DEBUG("[VM] Type : " + type);
DEBUG("[VM] Value : " + value);
@@ -107,6 +111,8 @@ void SPELLvariableMonitor::retrieveGlobalVariables()
if (value == "") value = EMPTY_STRING;
m_globalVariables.insert( std::make_pair(varName, SPELLvarInfo(varName, type, value, true)) );
+
+ Py_XDECREF(object);
}
}
@@ -150,7 +156,7 @@ void SPELLvariableMonitor::retrieveLocalVariables()
DEBUG("[VM] Processing " + varName);
std::string type = PYSSTR( PyObject_Type(object) );
DEBUG("[VM] Type : " + type);
- std::string value = PYREPR( object );
+ std::string value = PYCREPR( object );
DEBUG("[VM] Value : " + value);
DEBUG("[VM] Global : " + BSTR(false));
@@ -312,6 +318,12 @@ PyObject* SPELLvariableMonitor::getVariableRef( const std::string& name )
{
return PyDict_GetItemString(m_frame->f_globals, name.c_str());
}
+ PyObject* builtins = PyEval_GetBuiltins();
+ if (PyDict_Contains(builtins, pyName.get()))
+ {
+ return PyDict_GetItemString(builtins, name.c_str());
+ }
+
return NULL;
}
@@ -369,13 +381,15 @@ bool SPELLvariableMonitor::shouldDiscard( const std::string& varName, PyObject*
// Ignore internal flags
if (varName == "__USERLIB__") return true;
+ if (varName.substr(0,2) == "__" ) return true;
+
+
// Ignore callables and complex objects
if (SPELLpythonHelper::instance().isInstance(value, "Database", "spell.lib.adapter.databases.database")) return true;
if (PyCallable_Check(value)) return true;
if (PyFunction_Check(value)) return true;
if (PyClass_Check(value)) return true;
if (PyModule_Check(value)) return true;
- if (PyInstance_Check(value)) return true;
return false;
}
@@ -406,7 +420,7 @@ void SPELLvariableMonitor::analyze()
PyObject* key = PyList_GetItem( globalsItemList.get(), index );
PyObject* object = PyDict_GetItem( dict, key );
std::string varName = PYSTR(key);
-
+ //std::cout << varName << " -> " << shouldDiscard(varName,object) << std::endl;
if (shouldDiscard(varName,object)) continue;
it = m_globalVariables.find(varName);
diff --git a/lib/SPELL_IPC/Makefile.am b/lib/SPELL_IPC/Makefile.am
index 27b40f2..713afe3 100644
--- a/lib/SPELL_IPC/Makefile.am
+++ b/lib/SPELL_IPC/Makefile.am
@@ -1,47 +1,61 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
include ${top_srcdir}/common.mk
-lib_LTLIBRARIES= libSPELL_IPC.la
-CPPFLAGS += -Wno-pragmas
-libSPELL_IPC_la_LDFLAGS = -version-info 3:0:0
-libSPELL_IPC_la_SOURCES = \
- src/SPELLipcDataChunk.C \
- src/SPELLipcIncoming.C \
- src/SPELLipcMessage.C \
- src/SPELLipcServerInterface.C \
- src/SPELLipcServerInterfaceSingle.C \
- src/SPELLipcChannel.C \
- src/SPELLsocket.C \
- src/SPELLipcClientInterface.C \
- src/SPELLipcHelper.C \
- src/SPELLipcInput.C \
- src/SPELLipcMessageMailbox.C \
- src/SPELLipcOutput.C \
- src/SPELLipcTrash.C
-
-
+lib_LTLIBRARIES = libSPELL_IPC_v2.la libSPELL_IPC_v3.la
+
+libSPELL_IPC_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS} -Wno-pragmas
+
+libSPELL_IPC_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_IPC_v2_la_SOURCES = src/SPELLipcDataChunk.C \
+ src/SPELLipcIncoming.C \
+ src/SPELLipcMessage.C \
+ src/SPELLipcServerInterface.C \
+ src/SPELLipcServerInterfaceSingle.C \
+ src/SPELLipcChannel.C \
+ src/SPELLsocket.C \
+ src/SPELLipcClientInterface.C \
+ src/SPELLipcHelper.C \
+ src/SPELLipcInput.C \
+ src/SPELLipcMessageMailbox.C \
+ src/SPELLipcOutput.C \
+ src/SPELLipcTrash.C
+
+libSPELL_IPC_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS} -Wno-pragmas
+
+libSPELL_IPC_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_IPC_v3_la_SOURCES = src/SPELLipcDataChunk.C \
+ src/SPELLipcIncoming.C \
+ src/SPELLipcMessage.C \
+ src/SPELLipcServerInterface.C \
+ src/SPELLipcServerInterfaceSingle.C \
+ src/SPELLipcChannel.C \
+ src/SPELLsocket.C \
+ src/SPELLipcClientInterface.C \
+ src/SPELLipcHelper.C \
+ src/SPELLipcInput.C \
+ src/SPELLipcMessageMailbox.C \
+ src/SPELLipcOutput.C \
+ src/SPELLipcTrash.C
+
\ No newline at end of file
diff --git a/lib/SPELL_IPC/src/SPELLipcChannel.C b/lib/SPELL_IPC/src/SPELLipcChannel.C
index 29efc98..2e72709 100644
--- a/lib/SPELL_IPC/src/SPELLipcChannel.C
+++ b/lib/SPELL_IPC/src/SPELLipcChannel.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of a peer ipc channel
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -27,11 +27,13 @@
// FILES TO INCLUDE ////////////////////////////////////////////////////////
// Local includes ----------------------------------------------------------
#include "SPELL_IPC/SPELLipcChannel.H"
+#include "SPELL_IPC/SPELLipcError.H"
// Project includes --------------------------------------------------------
#include "SPELL_UTIL/SPELLlog.H"
#include "SPELL_UTIL/SPELLutils.H"
#include "SPELL_SYN/SPELLmonitor.H"
#include "SPELL_SYN/SPELLsyncError.H"
+#include "SPELL_IPC/SPELLipcError.H"
// System includes ---------------------------------------------------------
@@ -60,23 +62,25 @@ SPELLipcChannel::SPELLipcChannel( const std::string& name, SPELLsocket* socket,
SPELLipcChannel::~SPELLipcChannel()
{
DEBUG( NAME + "Destroying channel");
- if (m_socket)
- {
- delete m_socket;
- m_socket = NULL;
- }
if (m_output)
{
+ m_output->disconnect(false);
m_output->join();
delete m_output;
m_output = NULL;
}
if (m_input)
{
+ m_input->disconnect();
m_input->join();
delete m_input;
m_input = NULL;
}
+ if (m_socket)
+ {
+ delete m_socket;
+ m_socket = NULL;
+ }
DEBUG( NAME + "Channel destroyed");
}
@@ -89,6 +93,7 @@ void SPELLipcChannel::connect()
m_output = createOutput();
m_input = createInput();
m_input->start();
+ m_output->start();
setConnected(true);
DEBUG( NAME + "Connect done");
}
@@ -138,8 +143,17 @@ void SPELLipcChannel::disconnect()
{
DEBUG( NAME + "Disconnect");
m_connected = false;
- m_output->disconnect(true);
+ try
+ {
+ m_output->disconnect(true);
+ }
+ catch (SPELLipcError& ex)
+ {
+
+ }
+ m_input->setHandleEOC(false);
m_input->disconnect();
+ m_input->join();
m_socket->close();
DEBUG( NAME + "Disconnect finished");
}
@@ -217,11 +231,18 @@ void SPELLipcChannel::requestedEOC()
{
if (isConnected())
{
- setConnected(false);
- DEBUG( NAME + "Peer requested end of conversation");
- m_output->disconnect(false);
- m_socket->shutdown();
- DEBUG( NAME + "Disconnected, reporting interface");
- m_ifc.connectionClosed(m_key);
+ try
+ {
+ setConnected(false);
+ DEBUG( NAME + "Peer requested end of conversation");
+ m_output->disconnect(false);
+ m_socket->shutdown();
+ DEBUG( NAME + "Disconnected, reporting interface");
+ m_ifc.connectionClosed(m_key);
+ }
+ catch (SPELLipcError& ex)
+ {
+ // Ignore the IPC error if it happens when requeting EOC
+ }
}
}
diff --git a/lib/SPELL_IPC/src/SPELLipcClientInterface.C b/lib/SPELL_IPC/src/SPELLipcClientInterface.C
index e732e9e..8ac7e76 100644
--- a/lib/SPELL_IPC/src/SPELLipcClientInterface.C
+++ b/lib/SPELL_IPC/src/SPELLipcClientInterface.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the interface for clients
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -59,6 +59,7 @@ SPELLipcClientInterface::SPELLipcClientInterface( const std::string& name, const
{
m_channel = NULL;
m_listener = NULL;
+ m_socket = NULL;
m_trash.start();
m_timeoutIpcRetry = SPELLconfiguration::instance().commonOrDefault("RetryTimeout", IPC_REQUEST_RETRY_DEFAULT_DELAY_MSEC );
@@ -339,15 +340,16 @@ void SPELLipcClientInterface::incomingRequest( const SPELLipcMessage& msg )
SPELLmonitor m(m_lock);
- DEBUG(NAME + "Incoming request (" + msg.getSequenceStr() + ")");
+ DEBUG(NAME + "Incoming request (" + msg.getSequenceStr() + ") for ("+msg.get("User")+")");
try
{
DEBUG(NAME + "Creating request processor (" + msg.getSequenceStr() + ")");
- SPELLipcIncomingRequest* ireq = new SPELLipcIncomingRequest( msg.requestId(), m_ifcName, msg, m_channel->getWriter(), *m_listener );
+ SPELLipcIncomingRequest* ireq = new SPELLipcIncomingRequest( msg.requestId(), m_ifcName, msg, m_lock, &m_channel, *m_listener );
ireq->start();
- DEBUG(NAME + "Wait request processor to start (" + msg.getSequenceStr() + ")");
- ireq->waitStarted();
+ //DEBUG(NAME + "Wait request processor to start (" + msg.getSequenceStr() + ")");
+ // TODO: No reason to wait here. Remove once validated.
+ //ireq->waitStarted();
DEBUG(NAME + "Place in trash");
m_trash.place(ireq);
DEBUG(NAME + "Creating request processor DONE (" + msg.getSequenceStr() + ")");
@@ -365,7 +367,7 @@ void SPELLipcClientInterface::incomingRequest( const SPELLipcMessage& msg )
//=============================================================================
void SPELLipcClientInterface::incomingMessage( const SPELLipcMessage& msg )
{
- DEBUG(NAME + "IPC interface incoming message " + msg.getId());
+ DEBUG(NAME + "IPC interface incoming message " + msg.getId() + " for ("+msg.get("User")+")");
if (!m_connected) return;
if (m_listener == NULL) return;
@@ -374,11 +376,12 @@ void SPELLipcClientInterface::incomingMessage( const SPELLipcMessage& msg )
SPELLipcIncomingMessage* imsg = new SPELLipcIncomingMessage( msgId, m_ifcName, msg, *m_listener);
imsg->start();
- DEBUG(NAME + "Wait processor to start");
- imsg->waitStarted();
- DEBUG(NAME + "Place in trash");
+ //DEBUG(NAME + "Wait processor to start");
+ // TODO: No reason to wait here. Remove once validated.
+ //imsg->waitStarted();
+ //DEBUG(NAME + "Place in trash");
m_trash.place(imsg);
- DEBUG(NAME + "IPC interface incoming message OUT");
+ //DEBUG(NAME + "IPC interface incoming message OUT");
}
//=============================================================================
@@ -567,3 +570,10 @@ void SPELLipcClientInterface::removeListener()
m_listener = NULL;
}
+SPELLipcMessage SPELLipcClientInterface::getPingMessage()
+{
+ if (m_listener != NULL)
+ return m_listener->getPingMessage();
+ static SPELLipcMessage empty = SPELLipcMessage();
+ return empty;
+};
diff --git a/lib/SPELL_IPC/src/SPELLipcDataChunk.C b/lib/SPELL_IPC/src/SPELLipcDataChunk.C
index ee78224..1307e43 100644
--- a/lib/SPELL_IPC/src/SPELLipcDataChunk.C
+++ b/lib/SPELL_IPC/src/SPELLipcDataChunk.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the IPC data chunker
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_IPC/src/SPELLipcHelper.C b/lib/SPELL_IPC/src/SPELLipcHelper.C
index efc196d..fffd854 100644
--- a/lib/SPELL_IPC/src/SPELLipcHelper.C
+++ b/lib/SPELL_IPC/src/SPELLipcHelper.C
@@ -5,7 +5,7 @@
// DESCRIPTION: IPC utilities
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_IPC/src/SPELLipcIncoming.C b/lib/SPELL_IPC/src/SPELLipcIncoming.C
index d1fca4c..7cbfcf3 100644
--- a/lib/SPELL_IPC/src/SPELLipcIncoming.C
+++ b/lib/SPELL_IPC/src/SPELLipcIncoming.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the incoming message handler
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -49,10 +49,11 @@ SPELLipcIncomingBase::SPELLipcIncomingBase( const std::string& id, const std::st
m_processingFinishEvent(false),
m_processingStartEvent(false),
m_key(msg.getKey()),
- m_finished(false),
- m_started(false)
+ m_started(false),
+ m_finished(false)
+
{
- DEBUG( NAME + "Created");
+ //DEBUG( NAME + "Created");
DEBUG( NAME + "Using message " + m_message.getId());
m_processingFinishEvent.clear();
m_processingStartEvent.clear();
@@ -63,7 +64,7 @@ SPELLipcIncomingBase::SPELLipcIncomingBase( const std::string& id, const std::st
//=============================================================================
SPELLipcIncomingBase::~SPELLipcIncomingBase()
{
- DEBUG("Destroyed");
+ //DEBUG("Destroyed");
m_finished = true;
}
@@ -128,7 +129,6 @@ void SPELLipcIncomingBase::setFinished()
//=============================================================================
bool SPELLipcIncomingBase::isFinished()
{
- SPELLmonitor m(m_dataLock);
return m_finished;
}
@@ -164,16 +164,16 @@ int SPELLipcIncomingBase::getKey()
//=============================================================================
bool SPELLipcIncomingBase::wait( long timeoutMsec )
{
- DEBUG( NAME + "Wait finish " + getMessage().getSequenceStr());
+ //DEBUG( NAME + "Wait finish " + getMessage().getSequenceStr());
bool timedout = m_processingFinishEvent.wait( timeoutMsec );
if (timedout)
{
- DEBUG( NAME + "Finish timeout (" + ISTR(timeoutMsec) + ") " + getMessage().getSequenceStr());
- DEBUG( "MESSAGE " + getMessage().dataStr());
+ //DEBUG( NAME + "Finish timeout (" + ISTR(timeoutMsec) + ") " + getMessage().getSequenceStr());
+ //DEBUG( "MESSAGE " + getMessage().dataStr());
}
else
{
- DEBUG( NAME + "Wait finish done " + getMessage().getSequenceStr());
+ //DEBUG( NAME + "Wait finish done " + getMessage().getSequenceStr());
}
return timedout;
}
@@ -187,6 +187,7 @@ void SPELLipcIncomingBase::finish()
if (m_finished) return;
m_processingFinishEvent.set();
m_finished = true;
+ m_message.clear();
}
//=============================================================================
@@ -222,11 +223,11 @@ SPELLipcIncomingMessage::~SPELLipcIncomingMessage()
//=============================================================================
void SPELLipcIncomingMessage::run()
{
- DEBUG( NAME + "Incoming message starting");
+ //DEBUG( NAME + "Incoming message starting");
setStarted();
getListener().processMessage(getMessage());
finish();
- DEBUG( NAME + "Incoming message finished");
+ //DEBUG( NAME + "Incoming message finished");
}
//=============================================================================
@@ -235,11 +236,12 @@ void SPELLipcIncomingMessage::run()
SPELLipcIncomingRequest::SPELLipcIncomingRequest( const std::string& requestId,
const std::string& ifcName,
SPELLipcMessage msg,
- SPELLipcOutput& writer,
+ SPELLmutex& mutex,
+ SPELLipcChannel** channel,
SPELLipcInterfaceListener& listener)
: SPELLipcIncomingBase(requestId,ifcName,msg,listener),
- m_writer(writer)
+ m_channel(channel),m_mutex(mutex)
{
}
@@ -248,7 +250,7 @@ SPELLipcIncomingRequest::SPELLipcIncomingRequest( const std::string& requestId,
//=============================================================================
SPELLipcIncomingRequest::~SPELLipcIncomingRequest()
{
- DEBUG( NAME + "Incoming request destroyed");
+ //DEBUG( NAME + "Incoming request destroyed");
}
//=============================================================================
@@ -282,7 +284,12 @@ void SPELLipcIncomingRequest::run()
try
{
DEBUG( NAME + "Sending response (" + copy.getSequenceStr() + ")");
- m_writer.send(response);
+ {
+ SPELLmonitor m(m_mutex);
+ if (*m_channel != NULL){
+ (*m_channel)->getWriter().send(response);
+ }
+ }
DEBUG( NAME + "Response sent (" + copy.getSequenceStr() + ")");
}
catch(...)
diff --git a/lib/SPELL_IPC/src/SPELLipcInput.C b/lib/SPELL_IPC/src/SPELLipcInput.C
index 1018f00..8eacff9 100644
--- a/lib/SPELL_IPC/src/SPELLipcInput.C
+++ b/lib/SPELL_IPC/src/SPELLipcInput.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the data reader
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -38,7 +38,7 @@
// DEFINES /////////////////////////////////////////////////////////////////
#define NAME std::string("[ INPUT-KEY(") + ISTR(m_key) + ")-" + m_ifcName + " ] "
-#define SIZE sizeof(unsigned int)
+#define SIZE sizeof(uint32_t)
// store the diagnostics config
#pragma GCC diagnostic push
@@ -58,6 +58,9 @@ SPELLipcInput::SPELLipcInput( const std::string& name, SPELLsocket& skt, int pee
m_ifcName = name;
m_key = peerKey;
m_connected = true;
+ m_totalPacketLength = 0;
+ m_requestedEOC = false;
+ m_lastByte = 0;
DEBUG( NAME + "Created");
}
@@ -89,7 +92,10 @@ int SPELLipcInput::readPacketLength( int numRead )
m_totalPacketLength = length;
//DEBUG( NAME + " readPacketLength length: " + ISTR(m_totalPacketLength) + " " + SPELLutils::dumpString(tmp));
- assert(m_totalPacketLength < 9999000);
+ // Kill connection in case a client sends more then 1000MB in a single packet
+ if (m_totalPacketLength > 1000000000){
+ throw SPELLipcError( NAME + "Peer has sent bad data disconnecting!", 0);
+ }
// Remove the length bytes from buffer
for( unsigned int byte=0; byte<(numRead-SIZE); byte++)
@@ -126,6 +132,7 @@ int SPELLipcInput::readMoreBytes()
{
LOG_WARN( NAME + "WARNING: retrying read...");
retries++;
+ usleep(50000);
if (retries ==3) throw SPELLipcError(NAME + "Peer has disconnected (errno " + ISTR(errNo) + ")", errNo );
}
else break;
@@ -147,8 +154,8 @@ int SPELLipcInput::completeLength( int numRead )
{
int more = m_socket.receive( m_buffer+numRead, IPC_BUFFER_SIZE-numRead );
int errNo = errno;
- assert( more >= 0 );
- if (more == 0 && m_connected)
+ //assert( more >= 0 );
+ if (more <= 0 && m_connected)
{
DEBUG( NAME + "Read 0, peer has disconnected");
// When we receive zero it means that the peer has invoked
@@ -156,6 +163,7 @@ int SPELLipcInput::completeLength( int numRead )
// interface is in charge of that, we shall not touch the
// socket file descriptor here in SPELLipcInput. Just finish the
// loop.
+ // If more < 0 there was an during the receive call => disconect the client
throw SPELLipcError( NAME + "Peer has disconnected (errno " + ISTR(errNo) + ")", errNo);
}
return more;
@@ -344,7 +352,7 @@ void SPELLipcInput::run()
{
case IPC_ERROR_UNKNOWN_MSG_TYPE:
{
- LOG_ERROR( NAME + "Unable to process packet. " + ex.getError())
+ LOG_ERROR( NAME + "Unable to process packet. " + ex.getError());
DEBUG("Packet size: " + ISTR(m_packet.size()));
DEBUG("Packet expected length: " + ISTR(m_totalPacketLength));
DEBUG(SPELLutils::dumpString(m_packet));
@@ -407,7 +415,7 @@ void SPELLipcInput::disconnect()
//=============================================================================
void SPELLipcInput::dispatch()
{
- DEBUG( NAME + " Dispatch TRY IN");
+ //DEBUG( NAME + " Dispatch TRY IN");
if (!m_connected) return;
//DEBUG( NAME + "Dispatching: '" + m_packet + "'");
assert( m_packet.size() == m_totalPacketLength );
@@ -436,8 +444,9 @@ void SPELLipcInput::dispatch()
msg.fromData( dataForMsg );
msg.setCompressed(compression);
msg.setKey(m_key);
-
- DEBUG( NAME + "DISPATCH: " + msg.dataStr());
+ msg.setSender(msg.getSender());
+ msg.set("User",m_socket.getUser());
+ //DEBUG( NAME + "DISPATCH: " + msg.dataStr());
switch(msg.getType())
{
@@ -478,7 +487,7 @@ void SPELLipcInput::dispatch()
m_packet = "";
m_lastByte = NULL;
m_totalPacketLength = 0;
- DEBUG( NAME + "DISPATCH OUT");
+ //DEBUG( NAME + "DISPATCH OUT");
}
#pragma GCC diagnostic pop // restore diagnostics mode
diff --git a/lib/SPELL_IPC/src/SPELLipcMessage.C b/lib/SPELL_IPC/src/SPELLipcMessage.C
index 96a583d..a784232 100644
--- a/lib/SPELL_IPC/src/SPELLipcMessage.C
+++ b/lib/SPELL_IPC/src/SPELLipcMessage.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the IPC message
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -104,6 +104,7 @@ SPELLipcMessage::SPELLipcMessage( SPELLipcMessage* msg )
m_key = msg->m_key;
m_compressed = msg->m_compressed;
m_properties = msg->m_properties;
+ set("User", msg->get("User"));
}
//=============================================================================
@@ -195,7 +196,13 @@ std::string SPELLipcMessage::get( std::string key ) const
}
return it->second;
}
-
+void SPELLipcMessage::clear( )
+{
+ m_properties.clear();
+ m_id = "";
+ m_senderId = "";
+ m_receiverId = "";
+}
//=============================================================================
// METHOD: SPELLipcMessage:getRef
//=============================================================================
diff --git a/lib/SPELL_IPC/src/SPELLipcMessageMailbox.C b/lib/SPELL_IPC/src/SPELLipcMessageMailbox.C
index 6ae3c8b..955752e 100644
--- a/lib/SPELL_IPC/src/SPELLipcMessageMailbox.C
+++ b/lib/SPELL_IPC/src/SPELLipcMessageMailbox.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the message mailbox
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -108,22 +108,6 @@ void SPELLipcMessageMailbox::shutdown()
DEBUG(NAME + "Shutdown")
m_working = false;
}
- cancelAll();
-}
-
-//=============================================================================
-// METHOD: SPELLipcMessageMailbox::cancelAll()
-//=============================================================================
-void SPELLipcMessageMailbox::cancelAll()
-{
- SPELLipcMessageQueueMap::iterator mit;
- for( mit = m_queueMap.begin(); mit != m_queueMap.end(); mit++)
- {
- SPELLipcMessage* dummyResponse = new SPELLipcMessage("dummy");
- dummyResponse->setType( MSG_TYPE_RESPONSE );
- SPELLipcMessageQueue* queue = (*mit).second;
- queue->push(dummyResponse);
- }
}
//=============================================================================
diff --git a/lib/SPELL_IPC/src/SPELLipcOutput.C b/lib/SPELL_IPC/src/SPELLipcOutput.C
index 7b06f0d..5fb960e 100644
--- a/lib/SPELL_IPC/src/SPELLipcOutput.C
+++ b/lib/SPELL_IPC/src/SPELLipcOutput.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the data writer
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -33,15 +33,16 @@
#include "SPELL_SYN/SPELLmonitor.H"
#include "SPELL_UTIL/SPELLlog.H"
#include "SPELL_UTIL/SPELLcompression.H"
+#include "SPELL_EXC/SPELLexecutor.H"
// System includes ---------------------------------------------------------
// DEFINES /////////////////////////////////////////////////////////////////
#define NAME std::string("[ OUTPUT-KEY(") + ISTR(m_key) + ")-" + m_ifcName + " ] "
-#define SIZE sizeof(unsigned int)
+#define SIZE sizeof(uint32_t)
#define MINIMUM_SIZE_FOR_COMPRESSION 512
-#define PING_PERIOD_SEC 250
+#define PING_PERIOD_SEC 10
//=============================================================================
// FUNCTION: encodeLength
@@ -70,7 +71,7 @@ SPELLipcOutput::SPELLipcOutput( const std::string& name, SPELLsocket& skt, int m
m_channel(chan),
m_connected(true)
{
- DEBUG( NAME + "Created");
+ //DEBUG( NAME + "Created");
m_ping.setId("ping");
m_ping.setType(MSG_TYPE_PING);
}
@@ -80,7 +81,9 @@ SPELLipcOutput::SPELLipcOutput( const std::string& name, SPELLsocket& skt, int m
//=============================================================================
SPELLipcOutput::~SPELLipcOutput()
{
- DEBUG( NAME + "Destroyed");
+ //DEBUG( NAME + "Destroyed");
+ m_connected = false;
+ this->join();
}
//=============================================================================
@@ -88,20 +91,21 @@ SPELLipcOutput::~SPELLipcOutput()
//=============================================================================
void SPELLipcOutput::send( SPELLipcMessage& msg )
{
- msg.setKey( m_key );
- DEBUG( NAME + "SEND " + msg.dataStr() );
try
{
- std::string data = msg.data();
- bool doCompression = (msg.getCompressed() && (data.size()>= MINIMUM_SIZE_FOR_COMPRESSION));
+ SPELLmonitor m(m_lock);
+ msg.setKey(m_key);
+ //DEBUG(NAME + "SEND " + msg.dataStr());
+ std::string data = msg.data();
+ bool doCompression = (msg.getCompressed() && (data.size()>= MINIMUM_SIZE_FOR_COMPRESSION));
if (doCompression)
{
int origSize = data.size();
std::cerr << "Compressing message of length " << data.size() << " bytes (" << msg.getId() << ")" << std::endl;
- DEBUG("Raw data: " + SPELLutils::dumpString(data) + " size " + ISTR(data.length()) );
+ //DEBUG("Raw data: " + SPELLutils::dumpString(data) + " size " + ISTR(data.length()) );
SPELLcompression compressor(data);
data = compressor.compress();
- DEBUG("Compressed data: " + SPELLutils::dumpString(data) + " size " + ISTR(data.length()) );
+ //DEBUG("Compressed data: " + SPELLutils::dumpString(data) + " size " + ISTR(data.length()) );
double ratio = ((double) origSize - (double) data.size())/((double)origSize) * 100.0;
std::cerr << "Compressed to " << data.size() << " bytes (ratio " << std::setprecision(2) << ratio << "%)" << std::endl;
}
@@ -109,6 +113,8 @@ void SPELLipcOutput::send( SPELLipcMessage& msg )
data = (doCompression ? COMPRESSION_FLAG_TRUE_STR : COMPRESSION_FLAG_FALSE_STR) + data;
writeData( data );
+
+ //DEBUG( NAME + "SEND DONE" );
}
catch(SPELLipcError& err)
{
@@ -118,10 +124,11 @@ void SPELLipcOutput::send( SPELLipcMessage& msg )
LOG_ERROR( NAME + " Connection lost at output " + std::string(err.what()) );
LOG_ERROR( NAME + " Data being sent: " + msg.dataStr());
m_channel.outputFailed(errNo, err.getError());
+ throw;
}
else
{
- DEBUG( NAME + "Send failed, not connected: " + err.what() + ", errno=" + ISTR(errNo) );
+ //DEBUG( NAME + "Send failed, not connected: " + err.what() + ", errno=" + ISTR(errNo) );
}
}
catch(...)
@@ -135,10 +142,10 @@ void SPELLipcOutput::send( SPELLipcMessage& msg )
}
else
{
- DEBUG( NAME + "Send failed, not connected, errno=" + ISTR(errNo) );
+ //DEBUG( NAME + "Send failed, not connected, errno=" + ISTR(errNo) );
}
}
- DEBUG( NAME + "SEND DONE" );
+
}
//=============================================================================
@@ -147,8 +154,8 @@ void SPELLipcOutput::send( SPELLipcMessage& msg )
void SPELLipcOutput::disconnect( bool send_eoc )
{
if (!m_connected) return;
-
- DEBUG( NAME + "SPELLipcOutput disconnect");
+ SPELLmonitor m(m_lock);
+ //DEBUG( NAME + "SPELLipcOutput disconnect");
if (send_eoc)
{
@@ -157,9 +164,10 @@ void SPELLipcOutput::disconnect( bool send_eoc )
eoc.setType( MSG_TYPE_EOC );
eoc.setKey(m_key);
send(eoc);
- DEBUG( NAME + "EOC sent");
+ //DEBUG( NAME + "EOC sent");
}
m_connected = false;
+
}
//=============================================================================
@@ -167,13 +175,13 @@ void SPELLipcOutput::disconnect( bool send_eoc )
//=============================================================================
void SPELLipcOutput::writeData( std::string data )
{
- DEBUG( NAME + "Write data TRY-IN");
- SPELLmonitor m(m_lock);
- DEBUG( NAME + "Write data IN");
+ ////DEBUG( NAME + "Write data TRY-IN");
+
+ ////DEBUG( NAME + "Write data IN");
if (m_connected)
{
unsigned int sizeData = data.size();
- //DEBUG( NAME + "Packet length " + ISTR(sizeData));
+ ////DEBUG( NAME + "Packet length " + ISTR(sizeData));
int success = 0;
@@ -198,11 +206,11 @@ void SPELLipcOutput::writeData( std::string data )
numBytes = sizeData;
success = 0;
offset = 0;
- //DEBUG("writeData sending message: " + SPELLutils::dumpString(data));
+ ////DEBUG("writeData sending message: " + SPELLutils::dumpString(data));
while( numBytes > 0 )
{
success = m_socket.send(&data[offset],numBytes);
- if (success == -1 || errno != 0)
+ if (success == -1)
{
throw SPELLipcError( NAME + "Error while sending data, errno " + ISTR(errno) );
}
@@ -214,7 +222,7 @@ void SPELLipcOutput::writeData( std::string data )
m_lastSentTime.setCurrent();
}
- DEBUG( NAME + "Write data OUT");
+ ////DEBUG( NAME + "Write data OUT");
}
//=============================================================================
@@ -234,21 +242,22 @@ void SPELLipcOutput::run()
delta = currentTime - lastTime;
if (delta.getSeconds() > PING_PERIOD_SEC)
{
- std::cerr << "ping [" << NAME << "] " << currentTime.toString() << std::endl;
try
{
- send(m_ping);
+ SPELLipcMessage ping = this->m_channel.m_ifc.getPingMessage();
+ if (ping.isVoid()) {
+ send(m_ping);
+ } else {
+ send(ping);
+ }
}
catch(...)
{
- DEBUG( NAME + "Abort ping loop");
return;
}
}
- DEBUG( NAME + "1");
usleep(2000000); // 2 seconds
- DEBUG( NAME + "2");
}
- DEBUG( NAME + "Finish ping loop");
+ //DEBUG( NAME + "Finish ping loop");
}
diff --git a/lib/SPELL_IPC/src/SPELLipcServerInterface.C b/lib/SPELL_IPC/src/SPELLipcServerInterface.C
index 5c0d407..3a29092 100644
--- a/lib/SPELL_IPC/src/SPELLipcServerInterface.C
+++ b/lib/SPELL_IPC/src/SPELLipcServerInterface.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the interface for servers
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -27,6 +27,7 @@
// FILES TO INCLUDE ////////////////////////////////////////////////////////
// Local includes ----------------------------------------------------------
#include "SPELL_IPC/SPELLipcError.H"
+#include "SPELL_SYN/SPELLsyncError.H"
#include "SPELL_IPC/SPELLipcServerInterface.H"
#include "SPELL_IPC/SPELLipcHelper.H"
#include "SPELL_IPC/SPELLtimeoutValues.H"
@@ -56,7 +57,7 @@ SPELLipcServerInterface::SPELLipcServerInterface( const std::string& name, int k
m_serverPort = port;
m_clients.clear();
-
+ m_clientKeysToRemove.clear();
m_serverSocket = NULL;
m_ifcName = name;
@@ -125,6 +126,19 @@ void SPELLipcServerInterface::run()
bool disconnected = false;
SPELLsocket* clientSocket = m_serverSocket->acceptClient( &disconnected );
+ if (clientSocket == NULL && !m_clientKeysToRemove.empty())
+ {
+ SPELLmonitor m(m_clientCleanupLock);
+ SPELLmonitor m2(m_clientLock);
+
+ std::vector::const_iterator it = m_clientKeysToRemove.begin();
+ while(it != m_clientKeysToRemove.end())
+ {
+ removeClientInternal(*it);
+ ++it;
+ }
+ m_clientKeysToRemove.clear();
+ }
if ((!disconnected)&&clientSocket != NULL)
{
LOG_INFO(NAME + "Accepted new client connection");
@@ -159,6 +173,10 @@ void SPELLipcServerInterface::run()
{
LOG_ERROR("Failed to accept client: " + err.what());
}
+ catch(SPELLsyncError& err)
+ {
+ LOG_ERROR("Failed to accept client: " + err.what());
+ }
}
if (disconnected) return;
@@ -213,7 +231,8 @@ bool SPELLipcServerInterface::hasClient( int key )
DEBUG(NAME + "Has client TRY-IN");
SPELLmonitor m(m_clientLock);
DEBUG(NAME + "Has client OUT");
- return ( m_clients.find(key) != m_clients.end() );
+ SPELLipcChannelMap::iterator client = m_clients.find(key);
+ return ( client != m_clients.end() && client->second != NULL );
}
//=============================================================================
@@ -223,12 +242,11 @@ void SPELLipcServerInterface::addClient( int key, SPELLsocket* skt )
{
DEBUG( NAME + "add Client TRY-IN");
- SPELLmonitor m(m_clientLock);
-
SPELLipcChannel* channel = new SPELLipcChannel( std::string(m_ifcName), skt, key, *this );
channel->connect();
- m_clients.insert( std::make_pair( key, channel ));
+ SPELLmonitor m(m_clientLock);
+ m_clients[key] = channel;
LOG_INFO(NAME + "Added client " + ISTR(key));
m_clientConnectionEvent.set();
}
@@ -237,6 +255,13 @@ void SPELLipcServerInterface::addClient( int key, SPELLsocket* skt )
// METHOD: SPELLipcServerInterface:removeClient
//=============================================================================
void SPELLipcServerInterface::removeClient( int key )
+{
+ SPELLmonitor m(m_clientCleanupLock);
+ m_clientKeysToRemove.push_back(key);
+}
+
+
+void SPELLipcServerInterface::removeClientInternal( int key )
{
if (!hasClient(key))
{
@@ -244,12 +269,22 @@ void SPELLipcServerInterface::removeClient( int key )
}
DEBUG( NAME + "Remove client TRY-IN" );
- SPELLmonitor m(m_clientLock);
-
SPELLipcChannelMap::iterator cit = m_clients.find(key);
- cit->second->disconnect();
- delete cit->second;
- m_clients.erase(cit);
+ if (cit->second != NULL)
+ {
+ cit->second->disconnect();
+
+ m_clientLock.unlock();
+ m_clientCleanupLock.unlock();
+ delete cit->second;
+ m_clientCleanupLock.lock();
+ m_clientLock.lock();
+
+ // FIXME: Clearing clients may invalidate references in other threads
+ // resulting in a crash. This ought to be fixed with the new IPC layer.
+ //m_clients.erase(cit);
+ m_clients[cit->first] = NULL;
+ }
std::vector::iterator kit = std::find(m_usedClientKeys.begin(), m_usedClientKeys.end(), key);
if (kit != m_usedClientKeys.end())
{
@@ -270,12 +305,20 @@ void SPELLipcServerInterface::removeAllClients()
for( cit = m_clients.begin(); cit != m_clients.end(); cit++)
{
DEBUG(NAME + "Removing client " + ISTR(cit->first));
- cit->second->disconnect();
- delete cit->second;
+ if (cit->second != NULL)
+ {
+ cit->second->disconnect();
+ delete cit->second;
+ m_clients[cit->first] = NULL;
+ }
+
DEBUG(NAME + "Removing client " + ISTR(cit->first) + " done" );
}
m_usedClientKeys.clear();
- m_clients.clear();
+ m_clientKeysToRemove.clear();
+ // FIXME: Clearing clients may invalidate references in other threads
+ // resulting in a crash. This ought to be fixed with the new IPC layer.
+ //m_clients.clear();
DEBUG( NAME + "Remove all clients OUT");
}
@@ -339,7 +382,7 @@ void SPELLipcServerInterface::connectionLost( int peerKey, int errNo, const std:
cit = m_clients.find(peerKey);
}
}
- if (cit != m_clients.end())
+ if (cit != m_clients.end() && cit->second != NULL)
{
LOG_INFO(NAME + "#### Peer " + ISTR(peerKey) + " reconnected!");
}
@@ -376,8 +419,9 @@ void SPELLipcServerInterface::sendMessage( int peerKey, SPELLipcMessage& msg )
{
// Must set the appropriate key to the message beforehand. The key info is used
// to identify requests and their responses
+ SPELLmonitor m(m_clientLock);
msg.setKey(peerKey);
- getChannel(peerKey).getWriter().send(msg);
+ (*getChannel(peerKey))->getWriter().send(msg);
}
catch(SPELLipcError& err)
{
@@ -397,9 +441,10 @@ SPELLipcMessage SPELLipcServerInterface::sendRequest( int peerKey, SPELLipcMessa
DEBUG(NAME + "Get writer for peer " + ISTR(peerKey));
// Must set the appropriate key to the message beforehand. The key info is used
// to identify requests and their responses
+ SPELLmonitor m(m_clientLock);
msg.setKey(peerKey);
DEBUG(NAME + "Sending now request to peer " + ISTR(peerKey));
- resp = performRequest( getChannel(peerKey), msg, timeoutMsec );
+ resp = performRequest( **getChannel(peerKey), msg, timeoutMsec );
}
catch( SPELLipcError& err )
{
@@ -418,16 +463,16 @@ SPELLipcMessage SPELLipcServerInterface::sendRequest( int peerKey, SPELLipcMessa
//=============================================================================
// METHOD: SPELLipcServerInterface:getChannel
//=============================================================================
-SPELLipcChannel& SPELLipcServerInterface::getChannel( int peerKey )
+SPELLipcChannel** SPELLipcServerInterface::getChannel( int peerKey )
{
- DEBUG( NAME + "Get channel TRY-IN" );
+ //DEBUG( NAME + "Get channel TRY-IN" );
SPELLmonitor m(m_clientLock);
SPELLipcChannelMap::iterator cit = m_clients.find(peerKey);
- if (cit != m_clients.end())
+ if (cit != m_clients.end() && cit->second != NULL)
{
- DEBUG( NAME + "Get channel OUT" );
- return *cit->second;
+ //DEBUG( NAME + "Get channel OUT" );
+ return &m_clients[peerKey];
}
DEBUG( NAME + "Get channel FAIL" );
throw SPELLipcError("Cannot get writer, no such key: " + ISTR(peerKey));
@@ -514,11 +559,11 @@ void SPELLipcServerInterface::cancelOutgoingRequests( int peerKey )
DEBUG(NAME + "Cancel outgoing requests for peer " + ISTR(peerKey));
// Obtain the channel corresponding to the client
- SPELLipcChannel& channel = getChannel(peerKey);
+ SPELLipcChannel* channel = *getChannel(peerKey);
// Iterate over the list of ongoing requests, and cancel the requests in the mailbox
std::vector::iterator it;
- std::vector requestList = channel.getOngoingRequests();
+ std::vector requestList = channel->getOngoingRequests();
for( it = requestList.begin(); it != requestList.end(); it++)
{
DEBUG(NAME + " - cancel " + *it);
@@ -543,7 +588,7 @@ void SPELLipcServerInterface::cancelIncomingRequests( int peerKey )
//=============================================================================
void SPELLipcServerInterface::incomingRequest( const SPELLipcMessage& msg )
{
- DEBUG(NAME + "IPC interface incoming request TRY IN (" + msg.getSequenceStr() + ")");
+ //DEBUG(NAME + "IPC interface incoming request TRY IN (" + msg.getSequenceStr() + ")");
{
SPELLmonitor m(m_ipcLock);
@@ -559,23 +604,24 @@ void SPELLipcServerInterface::incomingRequest( const SPELLipcMessage& msg )
}
}
- DEBUG(NAME + "IPC interface incoming request IN (" + msg.getSequenceStr() + ")");
+ //DEBUG(NAME + "IPC interface incoming request IN (" + msg.getSequenceStr() + ")");
try
{
- DEBUG(NAME + "Creating request processor (" + msg.getSequenceStr() + ")");
- SPELLipcIncomingRequest* ireq = new SPELLipcIncomingRequest( msg.requestId(), m_ifcName, msg, getChannel(msg.getKey()).getWriter(), *m_listener );
+ //DEBUG(NAME + "Creating request processor (" + msg.getSequenceStr() + ")");
+ SPELLipcIncomingRequest* ireq = new SPELLipcIncomingRequest( msg.requestId(), m_ifcName, msg,m_clientLock, getChannel(msg.getKey()), *m_listener );
ireq->start();
- DEBUG(NAME + "Wait request processor to start (" + msg.getSequenceStr() + ")");
- ireq->waitStarted();
+ //DEBUG(NAME + "Wait request processor to start (" + msg.getSequenceStr() + ")");
+ // TODO: No reason to wait here. Remove once validated.
+ //ireq->waitStarted();
{
- DEBUG(NAME + "Place in trash");
+ //DEBUG(NAME + "Place in trash");
SPELLmonitor m(m_ipcLock);
m_trash.place(ireq);
- DEBUG(NAME + "Place in trash DONE");
+ //DEBUG(NAME + "Place in trash DONE");
}
- DEBUG(NAME + "Creating request processor DONE (" + msg.getSequenceStr() + ")");
+ //DEBUG(NAME + "Creating request processor DONE (" + msg.getSequenceStr() + ")");
}
catch(SPELLipcError& err)
{
@@ -597,19 +643,20 @@ void SPELLipcServerInterface::incomingMessage( const SPELLipcMessage& msg )
if (m_listener == NULL) return;
}
- DEBUG(NAME + "Creating message processor");
+ //DEBUG(NAME + "Creating message processor");
SPELLipcIncomingMessage* imsg = new SPELLipcIncomingMessage( msg.requestId(), m_ifcName, msg, *m_listener);
imsg->start();
- DEBUG(NAME + "Wait processor to start");
- imsg->waitStarted();
+ //DEBUG(NAME + "Wait processor to start");
+ // TODO: No reason to wait here. Remove once validated.
+ //imsg->waitStarted();
{
- DEBUG(NAME + "Place in trash");
+ //DEBUG(NAME + "Place in trash");
SPELLmonitor m(m_ipcLock);
m_trash.place(imsg);
- DEBUG(NAME + "Place in trash DONE");
+ //DEBUG(NAME + "Place in trash DONE");
}
- DEBUG(NAME + "IPC interface incoming message OUT");
+ //DEBUG(NAME + "IPC interface incoming message OUT");
}
//=============================================================================
diff --git a/lib/SPELL_IPC/src/SPELLipcServerInterfaceSingle.C b/lib/SPELL_IPC/src/SPELLipcServerInterfaceSingle.C
index 980740c..a8e12c0 100644
--- a/lib/SPELL_IPC/src/SPELLipcServerInterfaceSingle.C
+++ b/lib/SPELL_IPC/src/SPELLipcServerInterfaceSingle.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the interface for single client servers
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -49,7 +49,8 @@ SPELLipcServerInterfaceSingle::SPELLipcServerInterfaceSingle( const std::string&
m_connected(false),
m_trash(name),
m_ipcSequence(0),
- m_mailbox(name)
+ m_mailbox(name),
+ m_removeClient(false)
{
m_serverKey = key;
m_serverPort = port;
@@ -73,6 +74,7 @@ SPELLipcServerInterfaceSingle::~SPELLipcServerInterfaceSingle()
{
DEBUG(NAME + "Destroying server interface");
DEBUG(NAME + "Server interface destroyed");
+ removeClientInternal();
}
//=============================================================================
@@ -116,12 +118,14 @@ void SPELLipcServerInterfaceSingle::run()
DEBUG(" - Entering select loop");
DEBUG(NAME + "Accepting connections");
-
while(isConnected())
{
bool disconnected = false;
SPELLsocket* clientSocket = m_serverSocket->acceptClient( &disconnected );
-
+ if (clientSocket == NULL && m_removeClient)
+ {
+ removeClientInternal();
+ }
if ( (!disconnected) && (clientSocket != NULL) && (isConnected()) )
{
LOG_INFO(NAME + "Accepted new client connection");
@@ -172,7 +176,7 @@ void SPELLipcServerInterfaceSingle::addClient( SPELLsocket* skt )
DEBUG( NAME + "add Client TRY-IN");
SPELLmonitor m(m_clientLock);
-
+ m_removeClient = false;
m_channel = new SPELLipcChannel( std::string(m_ifcName), skt, 1, *this );
m_channel->connect();
@@ -185,22 +189,27 @@ void SPELLipcServerInterfaceSingle::addClient( SPELLsocket* skt )
//=============================================================================
void SPELLipcServerInterfaceSingle::removeClient()
{
- DEBUG( NAME + "Remove client TRY-IN" );
- SPELLmonitor m(m_clientLock);
+ m_removeClient = true;
+}
+
+void SPELLipcServerInterfaceSingle::removeClientInternal()
+{
+ SPELLmonitor m(m_cleanupLock);
if (m_channel)
{
- m_channel->disconnect();
- delete m_channel;
- m_channel = NULL;
+ m_channel->disconnect();
+ delete m_channel;
+ m_channel = NULL;
+ m_removeClient = false;
}
- DEBUG( NAME + "Remove client OUT" );
-}
+}
//=============================================================================
// METHOD: SPELLipcServerInterfaceSingle:disconnect
//=============================================================================
void SPELLipcServerInterfaceSingle::disconnect()
{
+
DEBUG(NAME + "Server interface disconnect TRY-IN");
if (!isConnected()) return;
DEBUG(NAME + "Server interface disconnect ALL IN");
@@ -220,7 +229,7 @@ void SPELLipcServerInterfaceSingle::disconnect()
//DEBUG(NAME + "Shutdown thread pool");
//m_msgPool.shutdown();
DEBUG(NAME + "Removing clients");
- removeClient();
+ removeClientInternal();
LOG_INFO(NAME + "Wait to end...");
join();
LOG_INFO(NAME + "Server interface disconnected");
@@ -272,11 +281,14 @@ void SPELLipcServerInterfaceSingle::sendMessage( SPELLipcMessage& msg )
DEBUG(NAME + "Send message to peer");
try
{
- SPELLipcOutput& writer = m_channel->getWriter();
- // Must set the appropriate key to the message beforehand. The key info is used
- // to identify requests and their responses
- msg.setKey(1);
- writer.send(msg);
+ if (m_channel != NULL)
+ {
+ SPELLipcOutput& writer = m_channel->getWriter();
+ // Must set the appropriate key to the message beforehand. The key info is used
+ // to identify requests and their responses
+ msg.setKey(1);
+ writer.send(msg);
+ }
}
catch(SPELLipcError& err)
{
@@ -428,15 +440,16 @@ void SPELLipcServerInterfaceSingle::incomingRequest( const SPELLipcMessage& msg
}
}
- DEBUG(NAME + "IPC interface incoming request IN (" + msg.getSequenceStr() + ")");
+ DEBUG(NAME + "IPC interface incoming request IN (" + msg.getSequenceStr() + ") for ("+msg.get("User")+")");
try
{
DEBUG(NAME + "Creating request processor (" + msg.getSequenceStr() + ")");
- SPELLipcIncomingRequest* ireq = new SPELLipcIncomingRequest( msg.requestId(), m_ifcName, msg, m_channel->getWriter(), *m_listener );
+ SPELLipcIncomingRequest* ireq = new SPELLipcIncomingRequest( msg.requestId(), m_ifcName, msg, m_clientLock,&m_channel, *m_listener );
ireq->start();
DEBUG(NAME + "Wait request processor to start (" + msg.getSequenceStr() + ")");
- ireq->waitStarted();
+ // TODO: No reason to wait here. Remove once validated.
+ //ireq->waitStarted();
DEBUG(NAME + "Place in trash");
m_trash.place(ireq);
DEBUG(NAME + "Place in trash DONE");
@@ -456,9 +469,9 @@ void SPELLipcServerInterfaceSingle::incomingRequest( const SPELLipcMessage& msg
//=============================================================================
void SPELLipcServerInterfaceSingle::incomingMessage( const SPELLipcMessage& msg )
{
- DEBUG(NAME + "IPC interface incoming message TRY IN");
+ // DEBUG(NAME + "IPC interface incoming message TRY IN");
SPELLmonitor m(m_incomingLock);
- DEBUG(NAME + "IPC interface incoming message IN " + msg.getId());
+ // DEBUG(NAME + "IPC interface incoming message IN " + msg.getId());
{
SPELLmonitor m(m_ipcLock);
if (!isConnected()) return;
@@ -468,18 +481,29 @@ void SPELLipcServerInterfaceSingle::incomingMessage( const SPELLipcMessage& msg
DEBUG(NAME + "Creating message processor");
while(m_trash.size()>50)
{
- //LOG_WARN(NAME + "Waiting for free space in queue");
- usleep(2000);
+ m_trash.clearData();
+ if (m_trash.size()>50)
+ {
+ LOG_WARN(NAME + "Waiting for free space in queue");
+ usleep(50000);
+ }
+ }
+ SPELLipcInterfaceListener* listener = m_listener;
+ if (listener != NULL){
+ SPELLipcIncomingMessage* imsg = new SPELLipcIncomingMessage( msg.requestId(), m_ifcName, msg, *listener);
+ imsg->start();
+ //DEBUG(NAME + "Wait processor to start");
+ // TODO: No reason to wait here. Remove once validated.
+ //imsg->waitStarted();
+ // DEBUG(NAME + "Place in trash");
+ m_trash.place(imsg);
+ } else {
+ LOG_WARN("!! Request discarded: no listener: " + msg.getId());
}
- SPELLipcIncomingMessage* imsg = new SPELLipcIncomingMessage( msg.requestId(), m_ifcName, msg, *m_listener);
- imsg->start();
- DEBUG(NAME + "Wait processor to start");
- imsg->waitStarted();
- DEBUG(NAME + "Place in trash");
- m_trash.place(imsg);
- DEBUG(NAME + "Place in trash DONE");
-
- DEBUG(NAME + "IPC interface incoming message OUT");
+
+ // DEBUG(NAME + "Place in trash DONE");
+
+ // DEBUG(NAME + "IPC interface incoming message OUT");
}
//=============================================================================
diff --git a/lib/SPELL_IPC/src/SPELLipcTrash.C b/lib/SPELL_IPC/src/SPELLipcTrash.C
index 3b7ce91..8789ebf 100644
--- a/lib/SPELL_IPC/src/SPELLipcTrash.C
+++ b/lib/SPELL_IPC/src/SPELLipcTrash.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the request cleaner
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -137,7 +137,7 @@ void SPELLipcTrash::run()
while(isWorking())
{
if (haveData()) clearData();
- usleep(350000);
+ usleep(50000);
}
if (haveData()) clearData();
m_trashFinishEvent.set();
@@ -167,7 +167,7 @@ bool SPELLipcTrash::haveData()
//=============================================================================
unsigned int SPELLipcTrash::size()
{
- SPELLmonitor m(m_dataLock);
+ SPELLmonitor m(m_dataLock);
return m_messages.size();
}
@@ -181,22 +181,26 @@ void SPELLipcTrash::clearData()
for( it = m_messages.begin(); it != m_messages.end(); it++)
{
- DEBUG( NAME + "Waiting for " + (*it)->getSequence() );
+ //DEBUG( NAME + "Waiting for " + (*it)->getSequence() );
if ((*it)->isStarted())
{
- bool timedout = (*it)->wait(500); // milliseconds
+ bool timedout = (*it)->wait(25); // milliseconds
if (!timedout)
{
- DEBUG( NAME + "Joining " + (*it)->getSequence() );
- (*it)->join();
- DEBUG( NAME + "************ Deleting " + (*it)->getSequence() );
- delete (*it);
- it = m_messages.erase(it);
- DEBUG( NAME + "Deleted");
+ if (!*it) {
+ it = m_messages.erase(it);
+ } else {
+ //DEBUG( NAME + "Joining " + (*it)->getSequence() );
+ (*it)->join();
+ //DEBUG( NAME + "************ Deleting " + (*it)->getSequence() );
+ delete (*it);
+ it = m_messages.erase(it);
+ //DEBUG( NAME + "Deleted");
+ }
}
else
{
- DEBUG( NAME + "Did not delete " + (*it)->getSequence() );
+ //DEBUG( NAME + "Did not delete " + (*it)->getSequence() );
}
}
}
diff --git a/lib/SPELL_IPC/src/SPELLsocket.C b/lib/SPELL_IPC/src/SPELLsocket.C
index 29a651e..83f0f65 100644
--- a/lib/SPELL_IPC/src/SPELLsocket.C
+++ b/lib/SPELL_IPC/src/SPELLsocket.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the socket wrapper
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -38,14 +38,16 @@
#include
#include
#include
-
+#include
+#include
+#include
// DEFINES /////////////////////////////////////////////////////////////////
//=============================================================================
// CONSTRUCTOR: SPELLsocket::SPELLsocket
//=============================================================================
-SPELLsocket::SPELLsocket( int fd )
+SPELLsocket::SPELLsocket( int fd , std::string user, std::vector groups) : user(user), groups(groups)
{
m_socketFd = fd;
m_connected = true;
@@ -90,9 +92,13 @@ int SPELLsocket::send( const void* buffer, int size )
{
//DEBUGX(std::string tmp);
if (!m_connected) return 0;
- int numWritten = write(m_socketFd,buffer,size);
+ int numWritten = ::send(m_socketFd,buffer,size,MSG_NOSIGNAL);
//DEBUGX(tmp.assign((char*) buffer, ((char*)buffer) + numWritten));
- //DEBUG("SPELL SOCKET WROTE (" + ISTR(numWritten) + "):" + SPELLutils::dumpString(tmp));
+
+ if (errno > 0) {
+ //perror("send");
+ LOG_ERROR("[SKT] Socket " + ISTR(m_socketFd) + " encountered error: " + ISTR(errno) + " bytes written: " + ISTR(numWritten) + "/" + ISTR(size));
+ }
return numWritten;
}
@@ -139,6 +145,63 @@ void SPELLsocket::close()
::close(m_socketFd);
}
+std::string _exec(std::string cmd) {
+ char buffer[128];
+ std::string result = "";
+ FILE* pipe = popen(cmd.c_str(), "r");
+ if (!pipe)
+ return "";
+ try {
+ while (fgets(buffer, sizeof buffer, pipe) != NULL) {
+ result += buffer;
+ }
+ } catch (...) {
+ pclose(pipe);
+ throw;
+ }
+ pclose(pipe);
+ std::string::size_type i = 0;
+ while (i < result.length()) {
+ i = result.find('\n', i);
+ if (i == std::string::npos) {
+ break;
+ }
+ result.erase(i);
+ }
+ return result;
+
+}
+
+std::vector split(std::string& s, const std::string& delimiter) {
+ std::vector tokens;
+ size_t pos = 0;
+ std::string token;
+ while ((pos = s.find(delimiter)) != std::string::npos) {
+ token = s.substr(0, pos);
+ tokens.push_back(token);
+ s.erase(0, pos + delimiter.length());
+ }
+ tokens.push_back(s);
+
+ return tokens;
+}
+template
+std::string str(T begin, T end)
+{
+ std::stringstream ss;
+ bool first = true;
+ ss << "[";
+ for (; begin != end; begin++)
+ {
+ if (!first)
+ ss << ", ";
+ ss << *begin;
+ first = false;
+ }
+ ss << "]";
+ return ss.str();
+}
+
//=============================================================================
// METHOD: SPELLsocket::isConnected
//=============================================================================
@@ -169,10 +232,11 @@ SPELLsocket* SPELLsocket::acceptClient( bool* disconnected )
timeout.tv_usec = 0;
// Wait on the file descriptors
- int numfds = select( m_socketFd+1, &read_fds, NULL, NULL, &timeout);
+ int numfds = select( FD_SETSIZE, &read_fds, NULL, NULL, &timeout);
if( numfds == -1)
{
+ perror("select");
if (m_connected)
{
LOG_ERROR("Error on socket select: " + ISTR(errno));
@@ -196,8 +260,32 @@ SPELLsocket* SPELLsocket::acceptClient( bool* disconnected )
}
else
{
+
+ in_port_t port = ntohs(client_addr.sin_port);
+#ifdef WITH_KUBERNETES
+ DEBUG("Incoming Client from port: " + ISTR(port));
+ std::string user = _exec("cat ~spell/procs/users | grep "+ISTR(port)+" | awk -F= '{print $2}'");
+ int tries = 10;
+ while (user == "" && tries-- > 0){
+ user = _exec("cat ~spell/procs/users | grep "+ISTR(port)+" | awk -F= '{print $2}'");
+ if (user == "") {
+ usleep(500000);
+ }
+ }
+ std::string groupsStr = _exec("cat ~spell/procs/groups/" + user);
+ tries = 10;
+ while (groupsStr == "" && tries-- > 0){
+ groupsStr = _exec("cat ~spell/procs/groups/" + user);
+ if (groupsStr == "") {
+ usleep(500000);
+ }
+ }
+ groups = split(groupsStr, " ");
+
+ DEBUG("Incoming Client for user: " + user + " groups:" + str(groups.begin(), groups.end()));
+#endif
*disconnected = false;
- return new SPELLsocket( newfd );
+ return new SPELLsocket( newfd, user, groups);
}
}
@@ -236,9 +324,10 @@ SPELLsocket* SPELLsocket::connect( const std::string& server, const int& port )
DEBUG(" - Connecting to server at port " + ISTR(port));
if (::connect(socketFd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
{
+ // perror("connect");
throw SPELLipcError("Error on socket connect: errno " + ISTR(errno));
}
- return new SPELLsocket(socketFd);
+ return new SPELLsocket(socketFd, "spell",{});
}
//=============================================================================
@@ -246,64 +335,78 @@ SPELLsocket* SPELLsocket::connect( const std::string& server, const int& port )
//=============================================================================
SPELLsocket* SPELLsocket::listen( int* port )
{
+ int retries = 0;
+ while (retries < 3)
+ {
+ if (retries)
+ usleep(250);
+ ++retries;
- struct sockaddr_in serv_addr;
- bzero( (char*) &serv_addr, sizeof(serv_addr));
+ struct sockaddr_in serv_addr;
+ bzero( (char*) &serv_addr, sizeof(serv_addr));
- int socketFd;
- // Get the listener socket
- if((socketFd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- throw SPELLipcError("Error on socket creation, errno " +ISTR(errno) );
- }
+ int socketFd;
+ // Get the listener socket
+ if((socketFd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
+ {
+ if (retries < 3) continue;
+ throw SPELLipcError("Error on socket creation, errno " +ISTR(errno) );
+ }
- // Set reuse address
- int yes = 1;
- if(setsockopt(socketFd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
- {
- throw SPELLipcError("Error on socket configuration (reuse addr), errno " + ISTR(errno));
- }
+ // Set reuse address
+ int32_t yes = 1;
+ if(setsockopt(socketFd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int32_t)) == -1)
+ {
+ if (retries < 3) continue;
+ throw SPELLipcError("Error on socket configuration (reuse addr), errno " + ISTR(errno));
+ }
- // Set no linger
- struct linger linger;
- linger.l_onoff = 1; /*0 = off (l_linger ignored), nonzero = on */
- linger.l_linger =0; /*0 = discard data, nonzero = wait for data sent */
- if(setsockopt(socketFd, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)) == -1)
- {
- throw SPELLipcError("Error on socket configuration (linger), errno " + ISTR(errno));
- }
+ // Set no linger
+ struct linger linger;
+ linger.l_onoff = 1; /*0 = off (l_linger ignored), nonzero = on */
+ linger.l_linger =0; /*0 = discard data, nonzero = wait for data sent */
+ if(setsockopt(socketFd, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)) == -1)
+ {
+ if (retries < 3) continue;
+ throw SPELLipcError("Error on socket configuration (linger), errno " + ISTR(errno));
+ }
- // Set keep alive
- if(setsockopt(socketFd, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(int)) == -1)
- {
- throw SPELLipcError("Error on socket configuration (keep alive), errno " + ISTR(errno));
- }
+ // Set keep alive
+ if(setsockopt(socketFd, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(int32_t)) == -1)
+ {
+ if (retries < 3) continue;
+ throw SPELLipcError("Error on socket configuration (keep alive), errno " + ISTR(errno));
+ }
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- serv_addr.sin_port = htons(*port);
- memset(&(serv_addr.sin_zero), '\0', 8);
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ serv_addr.sin_port = htons(*port);
+ memset(&(serv_addr.sin_zero), '\0', 8);
- if (bind(socketFd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
- {
- throw SPELLipcError("Error on socket bind, errno " + ISTR(errno));
- }
+ if (bind(socketFd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
+ {
+ if (retries < 3) continue;
+ throw SPELLipcError("Error on socket bind, errno " + ISTR(errno));
+ }
- socklen_t address_len = sizeof serv_addr;
- // Get the actual port (chosen by OS if m_serverPort was zero for bind)
- if (getsockname( socketFd, (struct sockaddr*) &serv_addr, &address_len )<0)
- {
- std::cerr << errno << std::endl;
- throw SPELLipcError("Error getting socket address, errno " + ISTR(errno) );
- }
- *port = ntohs(serv_addr.sin_port);
- DEBUG("Listening on port " + ISTR(*port));
+ socklen_t address_len = sizeof serv_addr;
+ // Get the actual port (chosen by OS if m_serverPort was zero for bind)
+ if (getsockname( socketFd, (struct sockaddr*) &serv_addr, &address_len )<0)
+ {
+ if (retries < 3) continue;
+ throw SPELLipcError("Error getting socket address, errno " + ISTR(errno) );
+ }
+ *port = ntohs(serv_addr.sin_port);
+ DEBUG("Listening on port " + ISTR(*port));
- if (::listen(socketFd,5) == -1)
- {
- throw SPELLipcError("Error on listen, errno " + ISTR(errno));
+ if (::listen(socketFd,5) == -1)
+ {
+ if (retries < 3) continue;
+ throw SPELLipcError("Error on listen, errno " + ISTR(errno));
+ }
+ return new SPELLsocket( socketFd , "spell",{});
}
- return new SPELLsocket( socketFd );
+ throw SPELLipcError("Error on listen, errno " + ISTR(errno));
}
//=============================================================================
diff --git a/lib/SPELL_LST/Makefile.am b/lib/SPELL_LST/Makefile.am
index abab52e..09beeaf 100644
--- a/lib/SPELL_LST/Makefile.am
+++ b/lib/SPELL_LST/Makefile.am
@@ -1,34 +1,41 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
include ${top_srcdir}/common.mk
-lib_LTLIBRARIES= libSPELL_LST.la
-libSPELL_LST_la_LDFLAGS = -version-info 3:0:0
-libSPELL_LST_la_SOURCES = \
- src/SPELLlistenerContext.C \
- src/SPELLlistenerGui.C \
- src/SPELLlistener.C
-
+
+lib_LTLIBRARIES = libSPELL_LST_v2.la libSPELL_LST_v3.la
+
+libSPELL_LST_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+
+libSPELL_LST_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_LST_v2_la_SOURCES = src/SPELLlistenerContext.C \
+ src/SPELLlistenerGui.C \
+ src/SPELLlistener.C
+
+libSPELL_LST_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS}
+
+libSPELL_LST_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_LST_v3_la_SOURCES = src/SPELLlistenerContext.C \
+ src/SPELLlistenerGui.C \
+ src/SPELLlistener.C
+
\ No newline at end of file
diff --git a/lib/SPELL_LST/src/SPELLlistener.C b/lib/SPELL_LST/src/SPELLlistener.C
index dc78b7c..697784a 100644
--- a/lib/SPELL_LST/src/SPELLlistener.C
+++ b/lib/SPELL_LST/src/SPELLlistener.C
@@ -5,7 +5,7 @@
// DESCRIPTION:
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -70,7 +70,16 @@ void SPELLlistener::start( const std::string& configFile )
m_contextListener = new SPELLlistenerContext( configFile );
m_guiListener->startup(m_contextListener, NULL);
- m_contextListener->startup(m_guiListener, NULL);
+ m_contextListener->startup(m_guiListener, NULL);
+
+ std::vector ctxList =
+ SPELLconfiguration::instance().getAvailableContexts();
+
+ for (std::vector::iterator it = ctxList.begin();
+ it != ctxList.end(); it++)
+ {
+ m_contextListener->respawnContext((*it));
+ }
}
void SPELLlistener::stop()
diff --git a/lib/SPELL_LST/src/SPELLlistenerContext.C b/lib/SPELL_LST/src/SPELLlistenerContext.C
index b799db0..564bd7e 100644
--- a/lib/SPELL_LST/src/SPELLlistenerContext.C
+++ b/lib/SPELL_LST/src/SPELLlistenerContext.C
@@ -5,7 +5,7 @@
// DESCRIPTION:
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -56,7 +56,7 @@ SPELLlistenerContext::SPELLlistenerContext(const std::string& configFile)
m_gui = NULL;
m_peer = NULL;
-
+ m_ipc = NULL;
m_configFile = configFile;
m_port = STRI(SPELLconfiguration::instance().getListenerParameter("ContextListenerPort"));
m_contextStartupCmd = SPELLconfiguration::instance().getListenerParameter("ContextScript");
@@ -220,6 +220,7 @@ SPELLipcMessage SPELLlistenerContext::startContext( const SPELLipcMessage& msg )
//=============================================================================
SPELLipcMessage SPELLlistenerContext::destroyContext( const SPELLipcMessage& msg )
{
+ LOG_INFO("Destroying context");
std::string name;
name = msg.get(MessageField::FIELD_CTX_NAME);
@@ -234,11 +235,12 @@ SPELLipcMessage SPELLlistenerContext::destroyContext( const SPELLipcMessage& msg
SPELLprocessManager::instance().killProcess("CTX_" + name);
SPELLprocessManager::instance().waitProcess("CTX_" + name);
SPELLprocessManager::instance().clearProcess("CTX_" + name);
+ usleep(10000000);
+ respawnContext(name);
}
catch(SPELLcoreException& ex) {};
LOG_INFO("Destroyed context");
-
return SPELLipcHelper::createResponse(ContextMessages::RSP_DESTROY_CTX, msg);
}
@@ -312,7 +314,7 @@ SPELLipcMessage SPELLlistenerContext::stopContext( const SPELLipcMessage& msg )
notify.setSender("LST");
notify.setReceiver("GUI");
m_gui->displace(¬ify);
-
+ //respawnContext(ctxInfo->m_name);
}
catch(SPELLcoreException& ex) {};
}
@@ -412,14 +414,26 @@ void SPELLlistenerContext::fillContextInfo(const std::string ctxName, SPELLipcMe
std::string driverName;
SPELLcontextConfig* ctxConfig;
SPELLdriverConfig* drvConfig;
- ContextInfo* ctxInfo;
+ std::map::iterator ctxInfo;
- ctxInfo = &m_openContexts[ctxName];
- ctxConfig = ctxInfo->m_ctxConfig;
- drvConfig = ctxInfo->m_drvConfig;
+ ctxInfo = m_openContexts.find(ctxName);
+ if (ctxInfo == m_openContexts.end()){
+ msg.set(MessageField::FIELD_CTX_NAME, "Unknown");
+ msg.set(MessageField::FIELD_CTX_PORT, ISTR(0) );
+ msg.set(MessageField::FIELD_CTX_DRV, "Unknown");
+ msg.set(MessageField::FIELD_CTX_SC, "Unknown");
+ msg.set(MessageField::FIELD_CTX_FAM, "Unknown");
+ msg.set(MessageField::FIELD_CTX_GCS, "Unknown");
+ msg.set(MessageField::FIELD_CTX_DESC, "Unknown");
+ msg.set(MessageField::FIELD_CTX_STATUS, "ERROR");
+ msg.set(MessageField::FIELD_CTX_MAXPROC, "0" );
+ return;
+ }
+ ctxConfig = ctxInfo->second.m_ctxConfig;
+ drvConfig = ctxInfo->second.m_drvConfig;
msg.set(MessageField::FIELD_CTX_NAME, ctxName);
- msg.set( MessageField::FIELD_CTX_PORT, ISTR(ctxInfo->m_port) );
+ msg.set( MessageField::FIELD_CTX_PORT, ISTR(ctxInfo->second.m_port) );
if (ctxConfig != NULL)
{
@@ -428,7 +442,7 @@ void SPELLlistenerContext::fillContextInfo(const std::string ctxName, SPELLipcMe
msg.set(MessageField::FIELD_CTX_FAM, ctxConfig->getFamily());
msg.set(MessageField::FIELD_CTX_GCS, ctxConfig->getGCS());
msg.set(MessageField::FIELD_CTX_DESC, ctxConfig->getDescription());
- msg.set(MessageField::FIELD_CTX_STATUS, ctxInfo->m_status);
+ msg.set(MessageField::FIELD_CTX_STATUS, ctxInfo->second.m_status);
}
else
{
@@ -507,7 +521,7 @@ SPELLipcMessage SPELLlistenerContext::displace( const SPELLipcMessage& msg )
else if (msg.getId() == ContextMessages::REQ_DESTROY_CTX)
res = this->destroyContext(msg);
else
- LOG_ERROR("Unprocessed message: " + msg.getId())
+ LOG_ERROR("Unprocessed message: " + msg.getId());
DEBUG("Response IPC object: " + res.dataStr());
@@ -517,7 +531,7 @@ SPELLipcMessage SPELLlistenerContext::displace( const SPELLipcMessage& msg )
//=============================================================================
// METHOD: SPELLlistenerContext::processStarted
//=============================================================================
-void SPELLlistenerContext::processStarted( const std::string& identifier )
+void SPELLlistenerContext::processStarted( const std::string identifier )
{
LOG_INFO("Context process started: " + identifier);
}
@@ -525,7 +539,7 @@ void SPELLlistenerContext::processStarted( const std::string& identifier )
//=============================================================================
// METHOD: SPELLlistenerContext::processFinished
//=============================================================================
-void SPELLlistenerContext::processFinished( const std::string& identifier, const int& retValue )
+void SPELLlistenerContext::processFinished( const std::string identifier, const int& retValue )
{
LOG_INFO("Context process finished: " + identifier);
}
@@ -533,7 +547,7 @@ void SPELLlistenerContext::processFinished( const std::string& identifier, const
//=============================================================================
// METHOD: SPELLlistenerContext::processKilled
//=============================================================================
-void SPELLlistenerContext::processKilled( const std::string& identifier )
+void SPELLlistenerContext::processKilled( const std::string identifier )
{
ContextInfo* ctxInfo;
std::string ctxName = identifier.substr(4);
@@ -551,18 +565,25 @@ void SPELLlistenerContext::processKilled( const std::string& identifier )
notify.setReceiver("GUI");
m_gui->displace(¬ify);
DEBUG("Process killed processing done");
+ usleep(10000000);
+ respawnContext(ctxName);
}
//=============================================================================
// METHOD: SPELLlistenerContext::processFailed
//=============================================================================
-void SPELLlistenerContext::processFailed( const std::string& identifier )
+void SPELLlistenerContext::processFailed( const std::string identifier )
{
ContextInfo* ctxInfo;
LOG_ERROR("Context " + identifier + " failed");
ctxInfo = &m_openContexts[identifier.substr(4)];
ctxInfo->m_status = MessageValue::DATA_CTX_ERROR;
- m_ipc->disconnect();
+ try {
+ m_ipc->disconnectClient(ctxInfo->m_key);
+ } catch(SPELLcoreException& ex)
+ {
+
+ }
// Notify to other clients
SPELLipcMessage notify( ListenerMessages::MSG_CONTEXT_OP );
@@ -572,8 +593,11 @@ void SPELLlistenerContext::processFailed( const std::string& identifier )
notify.setSender("LST");
notify.setReceiver("GUI");
m_gui->displace(¬ify);
+ usleep(10000000);
+ respawnContext(ctxInfo->m_name);
}
+
//=============================================================================
// METHOD: SPELLlistenerContext::notifyClients
//=============================================================================
diff --git a/lib/SPELL_LST/src/SPELLlistenerGui.C b/lib/SPELL_LST/src/SPELLlistenerGui.C
index 44f5774..56b2ed2 100644
--- a/lib/SPELL_LST/src/SPELLlistenerGui.C
+++ b/lib/SPELL_LST/src/SPELLlistenerGui.C
@@ -5,7 +5,7 @@
// DESCRIPTION:
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -46,6 +46,9 @@ SPELLlistenerGui::SPELLlistenerGui(const std::string& configFile)
m_configFile = configFile;
m_port = STRI(SPELLconfiguration::instance().getListenerParameter("ListenerPort"));
m_peer = NULL;
+ m_ctx = NULL;
+ m_peer = NULL;
+ m_ipc = NULL;
}
//=============================================================================
diff --git a/lib/SPELL_PRC/Makefile.am b/lib/SPELL_PRC/Makefile.am
index a29aed2..3836e60 100644
--- a/lib/SPELL_PRC/Makefile.am
+++ b/lib/SPELL_PRC/Makefile.am
@@ -1,33 +1,38 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
include ${top_srcdir}/common.mk
-lib_LTLIBRARIES= libSPELL_PRC.la
-libSPELL_PRC_la_LDFLAGS = -version-info 3:0:0
-libSPELL_PRC_la_SOURCES = \
- src/SPELLprocess.C \
- src/SPELLprocessManager.C
-
+
+lib_LTLIBRARIES = libSPELL_PRC_v2.la libSPELL_PRC_v3.la
+
+libSPELL_PRC_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+
+libSPELL_PRC_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_PRC_v2_la_SOURCES = src/SPELLprocess.C \
+ src/SPELLprocessManager.C
+
+libSPELL_PRC_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS}
+
+libSPELL_PRC_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_PRC_v3_la_SOURCES = src/SPELLprocess.C \
+ src/SPELLprocessManager.C
\ No newline at end of file
diff --git a/lib/SPELL_PRC/src/SPELLprocess.C b/lib/SPELL_PRC/src/SPELLprocess.C
index 042ade7..674f4c1 100644
--- a/lib/SPELL_PRC/src/SPELLprocess.C
+++ b/lib/SPELL_PRC/src/SPELLprocess.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of process model
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -103,6 +103,7 @@ SPELLprocess::SPELLprocess( std::string identifier, int pid, SPELLprocessManager
SPELLprocess::~SPELLprocess()
{
DEBUG("[PRC] PROCESS " + m_identifier + " DESTROYED");
+ this->join();
}
//=============================================================================
@@ -117,6 +118,7 @@ void SPELLprocess::run()
m_statusCode = PSTATUS_INITIAL;
try
{
+ LOG_INFO("Starting process with command '" + m_command + "'");
m_processPID = popen( m_command );
}
catch(SPELLcoreException& ex)
@@ -223,7 +225,7 @@ void SPELLprocess::run()
m_statusCode = PSTATUS_RUNNING;
m_pManager->fireProcessStarted( m_identifier );
- bool repeat = false;
+ bool repeat = true;
do
{
if ( !SPELLutils::pathExists( "/proc/" + ISTR(m_processPID) + "/stat" ) )
@@ -243,7 +245,7 @@ void SPELLprocess::run()
}
else
{
- usleep(1000);
+ usleep(100000);
}
}
while(repeat);
@@ -303,7 +305,7 @@ pid_t SPELLprocess::popen( std::string command )
}
else if (pid == 0)
{
- if (execl("/bin/sh", "sh", "-c", command.c_str(), NULL) != 0)
+ if (execl("/bin/bash", "bash", "-c", command.c_str(), NULL) != 0)
{
std::cerr << "####################################################################" << std::endl;
std::cerr << "####################################################################" << std::endl;
diff --git a/lib/SPELL_PRC/src/SPELLprocessManager.C b/lib/SPELL_PRC/src/SPELLprocessManager.C
index 8a5e911..c68daa9 100644
--- a/lib/SPELL_PRC/src/SPELLprocessManager.C
+++ b/lib/SPELL_PRC/src/SPELLprocessManager.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of process manager
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -34,7 +34,7 @@
#include "SPELL_UTIL/SPELLbase.H"
#include "SPELL_UTIL/SPELLerror.H"
#include "SPELL_UTIL/SPELLlog.H"
-
+#include "SPELL_UTIL/SPELLutils.H"
// GLOBALS /////////////////////////////////////////////////////////////////
@@ -56,6 +56,7 @@ SPELLprocessManager::SPELLprocessManager()
//=============================================================================
SPELLprocessManager::~SPELLprocessManager()
{
+
m_processes.clear();
m_listeners.clear();
}
@@ -81,6 +82,9 @@ void SPELLprocessManager::startProcess( const std::string& identifier, const std
DEBUG("[PRCMGR] Starting process " + identifier);
SPELLprocess* process = new SPELLprocess(identifier,command,this);
process->start();
+ if (m_processes.count(identifier) > 0)
+ LOG_ERROR("[PRCMGR] ProcessId " + identifier + " already exists!!!");
+
m_processes.insert( std::make_pair( identifier, process ));
DEBUG("[PRCMGR] Starting process " + identifier + " done");
}
@@ -143,15 +147,32 @@ void SPELLprocessManager::killProcess( const std::string& identifier )
DEBUG("[PRCMGR] Kill process " + identifier + " done");
}
+bool SPELLprocessManager::checkProcessExist( const std::string& identifier )
+{
+ SPELLmonitor m(m_lock);
+ DEBUG("[PRCMGR] Checking process " + identifier);
+ SPELLprocessMap::iterator it = m_processes.find(identifier);
+ if (it == m_processes.end() )
+ {
+ return false;
+ }
+ return true;
+
+}
+
//=============================================================================
// METHOD : SPELLprocessManager::waitProcess()
//=============================================================================
int SPELLprocessManager::waitProcess( const std::string& identifier )
{
- SPELLprocessMap::iterator it = m_processes.find(identifier);
- if (it == m_processes.end() )
+ SPELLprocessMap::iterator it;
{
- THROW_EXCEPTION("Cannot wait process " + identifier, "Not found", SPELL_ERROR_PROCESS);
+ SPELLmonitor m(m_lock);
+ it = m_processes.find(identifier);
+ if (it == m_processes.end() )
+ {
+ THROW_EXCEPTION("Cannot wait process " + identifier, "Not found", SPELL_ERROR_PROCESS);
+ }
}
return it->second->wait();
}
@@ -161,6 +182,7 @@ int SPELLprocessManager::waitProcess( const std::string& identifier )
//=============================================================================
SPELLprocessStatus SPELLprocessManager::getProcessStatus( const std::string& identifier )
{
+ SPELLmonitor m(m_lock);
SPELLprocessMap::iterator it = m_processes.find(identifier);
if (it == m_processes.end() )
{
@@ -174,11 +196,14 @@ SPELLprocessStatus SPELLprocessManager::getProcessStatus( const std::string& ide
//=============================================================================
void SPELLprocessManager::clearProcess( const std::string& identifier )
{
+ SPELLmonitor m(m_lock);
DEBUG("[PRCMGR] Clear process " + identifier);
SPELLprocessMap::iterator pit = m_processes.find(identifier);
if (pit != m_processes.end())
{
+ m_lock.unlock();
pit->second->join();
+ m_lock.lock();
delete pit->second;
m_processes.erase(pit);
DEBUG("[PRCMGR] Clear process " + identifier + " done");
@@ -230,14 +255,14 @@ void SPELLprocessManager::removeListener( const std::string& identifier, SPELLpr
//=============================================================================
// METHOD : SPELLprocessManager::fireProcessStarted()
//=============================================================================
-void SPELLprocessManager::fireProcessStarted( const std::string& identifier )
+void SPELLprocessManager::fireProcessStarted( const std::string identifier )
{
- SPELLmonitor m(m_lock);
DEBUG("[PRCMGR] Firing process started: " + identifier);
- SPELLprocessListenersMap::iterator mit = m_listeners.find(identifier);
+ SPELLprocessListenersMap listeners = m_listeners;
+ SPELLprocessListenersMap::iterator mit = listeners.find(identifier);
if (mit != m_listeners.end())
{
- SPELLprocessListeners& list = mit->second;
+ SPELLprocessListeners list = mit->second;
SPELLprocessListeners::iterator it;
for( it = list.begin(); it != list.end(); it++)
{
@@ -253,14 +278,14 @@ void SPELLprocessManager::fireProcessStarted( const std::string& identifier )
//=============================================================================
// METHOD : SPELLprocessManager::fireProcessFinished()
//=============================================================================
-void SPELLprocessManager::fireProcessFinished( const std::string& identifier, int retValue )
+void SPELLprocessManager::fireProcessFinished( std::string identifier, int retValue )
{
- SPELLmonitor m(m_lock);
DEBUG("[PRCMGR] Firing process finished: " + identifier);
- SPELLprocessListenersMap::iterator mit = m_listeners.find(identifier);
+ SPELLprocessListenersMap listeners = m_listeners;
+ SPELLprocessListenersMap::iterator mit = listeners.find(identifier);
if (mit != m_listeners.end())
{
- SPELLprocessListeners& list = mit->second;
+ SPELLprocessListeners list = mit->second;
SPELLprocessListeners::iterator it;
for( it = list.begin(); it != list.end(); it++)
{
@@ -276,14 +301,14 @@ void SPELLprocessManager::fireProcessFinished( const std::string& identifier, in
//=============================================================================
// METHOD : SPELLprocessManager::fireProcessKilled()
//=============================================================================
-void SPELLprocessManager::fireProcessKilled( const std::string& identifier )
+void SPELLprocessManager::fireProcessKilled( std::string identifier )
{
- SPELLmonitor m(m_lock);
DEBUG("[PRCMGR] Firing process killed: " + identifier);
- SPELLprocessListenersMap::iterator mit = m_listeners.find(identifier);
+ SPELLprocessListenersMap listeners = m_listeners;
+ SPELLprocessListenersMap::iterator mit = listeners.find(identifier);
if (mit != m_listeners.end())
{
- SPELLprocessListeners& list = mit->second;
+ SPELLprocessListeners list = mit->second;
SPELLprocessListeners::iterator it;
for( it = list.begin(); it != list.end(); it++)
{
@@ -294,20 +319,19 @@ void SPELLprocessManager::fireProcessKilled( const std::string& identifier )
}
}
}
- DEBUG("[PRCMGR] Firing process killed done: " + identifier);
}
//=============================================================================
// METHOD : SPELLprocessManager::fireProcessFailed()
//=============================================================================
-void SPELLprocessManager::fireProcessFailed( const std::string& identifier )
+void SPELLprocessManager::fireProcessFailed( std::string identifier )
{
- SPELLmonitor m(m_lock);
DEBUG("[PRCMGR] Firing process failed: " + identifier);
- SPELLprocessListenersMap::iterator mit = m_listeners.find(identifier);
+ SPELLprocessListenersMap listeners = m_listeners;
+ SPELLprocessListenersMap::iterator mit = listeners.find(identifier);
if (mit != m_listeners.end())
{
- SPELLprocessListeners& list = mit->second;
+ SPELLprocessListeners list = mit->second;
SPELLprocessListeners::iterator it;
for( it = list.begin(); it != list.end(); it++)
{
diff --git a/lib/SPELL_PRD/Makefile.am b/lib/SPELL_PRD/Makefile.am
index cb47a17..66ee734 100644
--- a/lib/SPELL_PRD/Makefile.am
+++ b/lib/SPELL_PRD/Makefile.am
@@ -1,34 +1,47 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
include ${top_srcdir}/common.mk
-lib_LTLIBRARIES= libSPELL_PRD.la
-libSPELL_PRD_la_LDFLAGS = -version-info 2:1:0
-libSPELL_PRD_la_SOURCES = \
- src/SPELLprocedureManager.C \
- src/SPELLprocedure.C \
- src/SPELLlibrary.C
-
+
+lib_LTLIBRARIES = libSPELL_PRD_v2.la libSPELL_PRD_v3.la
+
+libSPELL_PRD_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+
+libSPELL_PRD_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_PRD_v2_la_SOURCES = src/SPELLprocedureManager.C \
+ src/SPELLprocedure.C \
+ src/SPELLlibrary.C \
+ src/SPELLpyService.C \
+ src/SPELLserviceRegisterPython.C \
+ src/SPELLserviceWatchdogPython.C
+
+libSPELL_PRD_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS}
+
+libSPELL_PRD_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_PRD_v3_la_SOURCES = src/SPELLprocedureManager.C \
+ src/SPELLprocedure.C \
+ src/SPELLlibrary.C \
+ src/SPELLpyService.C \
+ src/SPELLserviceRegisterPython.C \
+ src/SPELLserviceWatchdogPython.C
+
\ No newline at end of file
diff --git a/lib/SPELL_PRD/src/SPELLlibrary.C b/lib/SPELL_PRD/src/SPELLlibrary.C
index 3283c71..dd7cdaf 100644
--- a/lib/SPELL_PRD/src/SPELLlibrary.C
+++ b/lib/SPELL_PRD/src/SPELLlibrary.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of library model
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -48,9 +48,6 @@ SPELLlibrary::SPELLlibrary( const std::string& libPath, const std::string& filen
// The remove the lib base path, not the subfolders
m_libId = m_libId.substr( libPath.size()+1, m_libId.size()-libPath.size()-1 );
-
- // Parse the file to get properties and source code
- parseFile(filename);
}
//=============================================================================
@@ -59,28 +56,3 @@ SPELLlibrary::SPELLlibrary( const std::string& libPath, const std::string& filen
SPELLlibrary::~SPELLlibrary()
{
}
-
-//=============================================================================
-// METHOD : SPELLlibrary::parseFile
-//=============================================================================
-void SPELLlibrary::parseFile( const std::string& path )
-{
- // Will be composed during parsing
- m_source.clear();
-
- std::ifstream file;
- file.open( path.c_str() );
- if (!file.is_open())
- {
- THROW_EXCEPTION("Cannot parse file " + path, "Unable to open", SPELL_ERROR_FILESYSTEM);
- }
- // Stores the last key found
- std::string lastKey;
- while(!file.eof())
- {
- std::string line = "";
- std::getline(file,line);
- m_source.addSourceCodeLine(line);
- }
- file.close();
-}
diff --git a/lib/SPELL_PRD/src/SPELLprocedure.C b/lib/SPELL_PRD/src/SPELLprocedure.C
index 376e73d..81f87f1 100644
--- a/lib/SPELL_PRD/src/SPELLprocedure.C
+++ b/lib/SPELL_PRD/src/SPELLprocedure.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of procedure model
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -36,15 +36,16 @@
#include
#include
#include
-#include
#define KEY_NAME "NAME"
+#define KEY_PYTHON_VERSION "PYTHON VERSION"
#define KEY_FILE "FILE"
#define KEY_HISTORY "REVISION HISTORY"
#define KEY_SC1 "SPACECRAFT"
#define KEY_SC2 "SPACECRAFTS"
const std::string CHECK_SPACECRAFT = "CheckSpacecraft";
+const std::string OVERRIDE_SC = "OverrideContextSpacecraftName";
//=============================================================================
// CONSTRUCTOR : SPELLprocedure::SPELLprocedure()
@@ -69,9 +70,6 @@ SPELLprocedure::SPELLprocedure( const std::string& procPath, const std::string&
m_file = filename;
m_header = "";
- // Obtain the file checksum
- m_md5 = obtainChecksum(filename);
-
// Parse the file to get properties and source code
parseFile(filename);
}
@@ -89,6 +87,55 @@ SPELLprocedure::~SPELLprocedure()
//=============================================================================
std::string SPELLprocedure::getHeader()
{
+ if (!m_header.empty())
+ return m_header;
+
+ std::ifstream file;
+ file.open( m_file.c_str() );
+ if (!file.is_open())
+ {
+ THROW_EXCEPTION("Cannot parse file " + m_file, "Unable to open", SPELL_ERROR_FILESYSTEM);
+ }
+ // Will be true while in comment lines
+ bool isComment = false;
+ // Will be true while inside the header
+ bool inHeader = false;
+ // Will be true when finished parsing the header
+ bool headerDone = false;
+ // Will be true if parsing the history of changes
+ bool inHistory = false;
+ m_header = "";
+ // Stores the last key found
+ std::string lastKey;
+ while(!file.eof())
+ {
+ std::string line = "";
+ std::getline(file,line);
+
+ if ((line.size()>0)&&(!headerDone))
+ {
+ isComment = (line[0] == '#');
+ if (isComment && (!inHeader))
+ {
+ // If it is a header delimiter line we are entering the header
+ if (isLimitLine(line))
+ {
+ inHeader = true;
+ }
+ }
+ else if (isComment && inHeader)
+ {
+ m_header += line + "\n";
+ // If we are in header and another limit line comes, we have finished
+ if (isLimitLine(line))
+ {
+ headerDone = true;
+ break;
+ }
+ }
+ }
+ }
+ file.close();
return m_header;
}
@@ -129,7 +176,6 @@ void SPELLprocedure::parseFile( const std::string& path )
{
std::string line = "";
std::getline(file,line);
- m_source.addSourceCodeLine(line);
if ((line.size()>0)&&(!headerDone))
{
isComment = (line[0] == '#');
@@ -143,7 +189,6 @@ void SPELLprocedure::parseFile( const std::string& path )
}
else if (isComment && inHeader)
{
- m_header += line + "\n";
// If we are in header and another limit line comes, we have finished
if (isLimitLine(line))
{
@@ -224,43 +269,6 @@ void SPELLprocedure::parseFile( const std::string& path )
m_properties[KEY_FILE] = m_file;
}
-//=============================================================================
-// METHOD : SPELLprocedure::obtainChecksum()
-//=============================================================================
-std::string SPELLprocedure::obtainChecksum( const std::string& filename )
-{
- int fd = open(filename.c_str(), O_RDONLY);
- if (fd<0)
- {
- THROW_EXCEPTION("Cannot calculate MD5 for file " + filename, "Unable to open", SPELL_ERROR_FILESYSTEM);
- }
- struct stat statbuf;
- if(fstat(fd, &statbuf) < 0)
- {
- THROW_EXCEPTION("Cannot calculate MD5 for file " + filename, "Unable to stat file", SPELL_ERROR_FILESYSTEM);
- }
- int fileSize = statbuf.st_size;
- char* fileBuffer;
- unsigned char result[MD5_DIGEST_LENGTH];
-
- fileBuffer = (char*) mmap(0, fileSize, PROT_READ, MAP_SHARED, fd, 0);
- MD5((unsigned char*) fileBuffer, fileSize, result);
-
- // Print the MD5 sum as hex-digits.
- int i;
- char* hex = new char[2];
- std::string checksum = "";
- for(i=0; i SPELLprocedureSourceCode::getSourceCodeLines() {
+ if (!m_sourceLines.empty())
+ return m_sourceLines;
+
+ std::ifstream file;
+ file.open( m_filename.c_str() );
+ if (!file.is_open())
+ {
+ THROW_EXCEPTION("Cannot parse file " + m_filename, "Unable to open", SPELL_ERROR_FILESYSTEM);
+ }
+ // Stores the last key found
+ std::string lastKey;
+ std::string line = "";
+ while(!file.eof())
+ {
+ std::getline(file,line);
+ m_sourceLines.push_back(line);
+ }
+
+ return m_sourceLines;
+};
diff --git a/lib/SPELL_PRD/src/SPELLprocedureManager.C b/lib/SPELL_PRD/src/SPELLprocedureManager.C
index 326deb9..137ac73 100644
--- a/lib/SPELL_PRD/src/SPELLprocedureManager.C
+++ b/lib/SPELL_PRD/src/SPELLprocedureManager.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of procedure manager
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -33,7 +33,7 @@
#include "SPELL_UTIL/SPELLlog.H"
#include "SPELL_UTIL/SPELLpythonHelper.H"
#include "SPELL_SYN/SPELLmonitor.H"
-
+#include "SPELL_WRP/SPELLpyHandle.H"
static SPELLprocedureManager* s_instance = 0;
@@ -94,11 +94,16 @@ void SPELLprocedureManager::resolvePaths()
SPELLcontextConfig& ctx = SPELLconfiguration::instance().getContext(m_ctxName);
m_procPath = ctx.getProcPath();
m_libPath = ctx.getLibPath();
+ m_servicePath = ctx.getServicePath();
// Resolve the path
m_procPath = SPELLutils::resolvePath(m_procPath);
m_libPath = SPELLutils::resolvePath(m_libPath);
+ m_servicePath = SPELLutils::resolvePath(m_servicePath);
+
SPELLutils::trim(m_procPath, "\r\n");
SPELLutils::trim(m_libPath, "\r\n");
+ SPELLutils::trim(m_servicePath, "\r\n");
+
if (!SPELLutils::isDirectory(m_procPath))
{
LOG_ERROR("Procedure path not found or not a directory: '" + m_procPath + "'");
@@ -125,6 +130,24 @@ void SPELLprocedureManager::resolvePaths()
{
LOG_INFO("[PRCM] No user libraries defined");
}
+
+ if (m_servicePath != "" && m_servicePath != "None")
+ {
+ if (!SPELLutils::isDirectory(m_servicePath))
+ {
+ LOG_ERROR("Spell Service path not found or not a directory: '" + m_servicePath + "'");
+ m_servicePath = "";
+ }
+ else
+ {
+ LOG_INFO("[PRCM] Spell Service path: " + m_servicePath);
+ }
+ }
+ else
+ {
+ LOG_INFO("[PRCM] No Spell Services defined");
+ }
+
}
//=============================================================================
@@ -158,6 +181,17 @@ void SPELLprocedureManager::refresh()
LOG_INFO("Loading library files");
findLibraries( m_libPath );
}
+ if (m_servicePath != "" && m_servicePath != "None")
+ {
+ SPELLpythonHelper::instance().addToPath(m_libPath);
+ LOG_INFO("Loading Spell Services");
+ findServices( m_servicePath, sc );
+
+ ServiceModelMap::iterator serviceIt = m_serviceModels.begin();
+ for(;serviceIt != m_serviceModels.end();serviceIt++){
+ std::cout << "Service " << serviceIt->second->getName() << " was found" << std::endl;
+ }
+ }
}
//=============================================================================
@@ -223,7 +257,20 @@ const SPELLprocedureManager::ProcList SPELLprocedureManager::getProcList()
}
return list;
}
+//=============================================================================
+// METHOD : SPELLprocedureManager::getServiceList
+//=============================================================================
+const SPELLprocedureManager::ProcList SPELLprocedureManager::getServiceList()
+{
+ ProcList list;
+ ServiceModelMap::iterator it;
+ for( it = m_serviceModels.begin(); it != m_serviceModels.end(); it++)
+ {
+ list.push_back( it->first );
+ }
+ return list;
+}
//=============================================================================
// METHOD : SPELLprocedureManager::getProcName
//=============================================================================
@@ -235,6 +282,10 @@ const std::string SPELLprocedureManager::getProcName( const std::string& procId
ProcMap::iterator it = m_idToName.find(theProcId);
if (it == m_idToName.end())
{
+ if (m_serviceModels.find(theProcId) != m_serviceModels.end()){
+ return theProcId;
+ }
+
DEBUG("[PRCM] Did not find any name for: " + theProcId );
THROW_EXCEPTION("Cannot get name for procedure '" + theProcId + "'", "No such identifier", SPELL_ERROR_PROCEDURES);
}
@@ -242,6 +293,82 @@ const std::string SPELLprocedureManager::getProcName( const std::string& procId
return it->second;
}
+//=============================================================================
+// METHOD : SPELLprocedureManager::findProcedures
+//=============================================================================
+void SPELLprocedureManager::registerServiceHandler( PyObject* serviceImpl )
+{
+ SPELLpyService* serviceModel = new SPELLpyService(serviceImpl);
+
+ m_serviceModels[serviceModel->getName()] = serviceModel;
+}
+
+
+//=============================================================================
+// METHOD : SPELLprocedureManager::findProcedures
+//=============================================================================
+void SPELLprocedureManager::findServices( const std::string& basePath, const std::string& sc )
+{
+ if (!SPELLutils::isDirectory(basePath))
+ {
+ return;
+ }
+
+ std::list files = SPELLutils::getFilesInDir( basePath );
+ std::list::iterator it;
+ std::list::iterator end = files.end();
+
+ std::string procPath = m_servicePath;
+
+ // Add the current path to python path
+ if (SPELLpythonHelper::instance().isInitialized())
+ {
+ SPELLpythonHelper::instance().addToPath( basePath );
+ }
+
+ PyObject* result = SPELLpythonHelper::instance().callFunction("spell.utils.spell_service","SupportServices",NULL);
+ Py_IncRef(result);
+ SPELLpythonHelper::instance().checkError();
+ if (result == Py_False)
+ return;
+
+ for( it = files.begin(); it != end; it++ )
+ {
+ if ((*it) == "__init__.py") continue;
+
+ std::size_t idx = (*it).find_last_of(".py");
+ std::size_t idxb = (*it).find(".py~"); // Filter out backup files
+ std::size_t idxc = (*it).find(".pyc"); // Filter out compiled py files
+ if ((idx != std::string::npos && idx == ((*it).length() - 1))
+ && (idxb == std::string::npos) && (idxc == std::string::npos))
+ {
+ std::string serviceFile = basePath + PATH_SEPARATOR + (*it);
+ std::string serviceModuleName = it->substr(0, idx-2);
+ try
+ {
+ std::cout << "Loading Service " << serviceModuleName << std::endl;
+
+ SPELLpyHandle serviceModule = PyImport_ImportModule(serviceModuleName.c_str());
+ SPELLpythonHelper::instance().checkError();
+ }
+ catch (SPELLcoreException& e)
+ {
+
+ }
+
+ }
+ }
+
+ std::list subdirs = SPELLutils::getSubdirs( basePath );
+ // Procedure folder order will be ['Bus', 'Ground', 'Mission', 'Payload', 'Prod_SES', 'Regression', 'SAE', 'Validation']
+ subdirs.sort(SPELLutils::compareNocase);
+ end = subdirs.end();
+ for( it = subdirs.begin(); it != end; it++ )
+ {
+ findServices( basePath + PATH_SEPARATOR + (*it), sc );
+ }
+}
+
//=============================================================================
// METHOD : SPELLprocedureManager::findProcedures
//=============================================================================
@@ -265,7 +392,8 @@ void SPELLprocedureManager::findProcedures( const std::string& basePath, const s
std::size_t idx = (*it).find_last_of(".py");
std::size_t idxb = (*it).find(".py~"); // Filter out backup files
- if ((idx != std::string::npos && idx == ((*it).length() - 1) ) && ( idxb == std::string::npos ))
+ std::size_t idxc = (*it).find(".pyc"); // Filter out compiled py files
+ if ((idx != std::string::npos && idx == ((*it).length() - 1) ) && ( idxb == std::string::npos ) && ( idxc == std::string::npos ))
{
std::string procFile = basePath + PATH_SEPARATOR + (*it);
SPELLprocedure* proc = NULL;
@@ -301,6 +429,8 @@ void SPELLprocedureManager::findProcedures( const std::string& basePath, const s
}
std::list subdirs = SPELLutils::getSubdirs( basePath );
+ // Procedure folder order will be ['Bus', 'Ground', 'Mission', 'Payload', 'Prod_SES', 'Regression', 'SAE', 'Validation']
+ subdirs.sort(SPELLutils::compareNocase);
end = subdirs.end();
for( it = subdirs.begin(); it != end; it++ )
{
@@ -366,7 +496,14 @@ SPELLprocedureSourceCode SPELLprocedureManager::getSourceCode( const std::string
LibModels::iterator libit = m_libModels.find(procId);
if (libit == m_libModels.end())
{
- THROW_EXCEPTION("Cannot get source code for " + procId, "Procedure or library not found", SPELL_ERROR_PROCEDURES);
+ ServiceModelMap::iterator mit = m_serviceModels.find(theProcId);
+ if (mit == m_serviceModels.end())
+ {
+ THROW_EXCEPTION("Cannot get source code for " + procId, "Procedure or library not found", SPELL_ERROR_PROCEDURES);
+
+ }
+ SPELLpyService* service = mit->second;
+ return service->getSourceCode();
}
SPELLlibrary* lib = libit->second;
lib->refresh();
@@ -391,7 +528,16 @@ SPELLprocedure::PropertyKeys SPELLprocedureManager::getPropertyKeys( const std::
it = m_procModels.find(theProcId);
if (it == m_procModels.end())
{
- THROW_EXCEPTION("Cannot get properties for " + theProcId, "Procedure not found", SPELL_ERROR_PROCEDURES);
+ ServiceModelMap::iterator mit;
+ mit = m_serviceModels.find(theProcId);
+ if (mit == m_serviceModels.end())
+ {
+ THROW_EXCEPTION("Cannot get properties for " + theProcId, "Procedure not found", SPELL_ERROR_PROCEDURES);
+ }
+ // Services don't have properties for now
+ SPELLprocedure::PropertyKeys empty = SPELLprocedure::PropertyKeys();
+ empty.clear();
+ return empty;
}
SPELLprocedure* proc = (*it).second;
proc->refresh();
@@ -418,7 +564,7 @@ const std::string SPELLprocedureManager::getProperty( const std::string& procId,
//=============================================================================
// METHOD : SPELLprocedureManager::noInstanceId
//=============================================================================
-const std::string SPELLprocedureManager::noInstanceId( const std::string& procId )
+const std::string noInstanceId( const std::string& procId )
{
std::string noIId = procId;
std::size_t pos = procId.find_first_of("#");
@@ -429,6 +575,22 @@ const std::string SPELLprocedureManager::noInstanceId( const std::string& procId
return noIId;
}
+//=============================================================================
+// METHOD : SPELLprocedureManager::getProcedure
+//=============================================================================
+SPELLpyService& SPELLprocedureManager::getService( const std::string& serviceId )
+{
+ SPELLmonitor lock(m_lock);
+ std::string noIId = noInstanceId(serviceId);
+ ServiceModelMap::iterator it;
+ it = m_serviceModels.find(noIId);
+ if (it != m_serviceModels.end())
+ {
+ return *it->second;
+ }
+ THROW_EXCEPTION("Cannot obtain service model", "No such id: " + serviceId, SPELL_ERROR_PROCEDURES);
+}
+
//=============================================================================
// METHOD : SPELLprocedureManager::getProcedure
//=============================================================================
diff --git a/lib/SPELL_PRD/src/SPELLpyService.C b/lib/SPELL_PRD/src/SPELLpyService.C
new file mode 100644
index 0000000..1521e88
--- /dev/null
+++ b/lib/SPELL_PRD/src/SPELLpyService.C
@@ -0,0 +1,115 @@
+// ################################################################################
+// FILE : SPELLservice.C
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Implementation of spell service model
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// Local includes ----------------------------------------------------------
+#include "SPELL_CFG/SPELLconfiguration.H"
+#include "SPELL_UTIL/SPELLlog.H"
+#include "SPELL_UTIL/SPELLerror.H"
+#include "SPELL_WRP/SPELLpyHandle.H"
+#include "SPELL_UTIL/SPELLpythonHelper.H"
+#include "SPELL_UTIL/SPELLpythonMonitors.H"
+
+// System includes ---------------------------------------------------------
+#include
+#include
+#include
+#include
+#include "SPELL_PRD/SPELLpyService.H"
+#include "SPELL_PRD/SPELLserviceWatchdogPython.H"
+
+//=============================================================================
+// CONSTRUCTOR : SPELLpyService::SPELLpyService()
+//=============================================================================
+SPELLpyService::SPELLpyService(PyObject* serviceImpl) :
+m_source("")
+{
+ SPELLsafePythonOperations ops("SPELLpyService::SPELLpyService");
+ SPELLpyHandle pyServiceName = SPELLpythonHelper::instance().callMethod(
+ serviceImpl, "getName", NULL);
+ m_name = PyString_AsString(pyServiceName.get());
+ SPELLpyHandle basePath = SPELLpythonHelper::instance().callMethod(serviceImpl, "getBasePath", NULL);
+ m_basePath = PyString_AsString(basePath.get());
+ basePath = SPELLpythonHelper::instance().callMethod(serviceImpl, "getMainFile", NULL);
+ m_mainServiceFile = PyString_AsString(basePath.get());
+
+ m_service = serviceImpl;
+ Py_IncRef(serviceImpl);
+ std::cout << "Found Spell Service " << m_name << std::endl;
+ m_source = SPELLprocedureSourceCode(this->getMainServiceFile());
+}
+
+//=============================================================================
+// DESTRUCTOR : SPELLpyService::~SPELLpyService
+//=============================================================================
+SPELLpyService::~SPELLpyService()
+{
+ Py_DecRef(m_service);
+}
+
+bool SPELLpyService::useCommandOverride() const {
+ SPELLsafePythonOperations ops("useCommandOverride");
+ SPELLpyHandle userOverride = SPELLpythonHelper::instance().callMethod(m_service,"useCommandOverride",NULL);
+
+ SPELLpythonHelper::instance().checkError();
+
+ return userOverride.get() == Py_True;
+}
+
+std::string SPELLpyService::getCommandOverride(int startTimeout, int loginTimeout, std::string config, std::string contextName, int ipcPort, std::string instanceId,
+ std::string warmstartFile) const {
+ SPELLsafePythonOperations ops("getCommandOverride");
+
+ SPELLpyHandle newCommand = PyObject_CallMethod(m_service,(char*)"getCommandOverride", (char*)"(iississ)", startTimeout, loginTimeout, config.c_str(), contextName.c_str(), ipcPort, instanceId.c_str(), warmstartFile.c_str(),NULL);
+ SPELLpythonHelper::instance().checkError();
+ return PyString_AsString(newCommand.get());
+}
+
+void SPELLpyService::startWatchDog(void (*callback)(std::string&))
+{
+ SPELLsafePythonOperations ops("startWatchDog");
+ PyObject* callbackObj = SpellServiceWatchdog_Create(callback);
+ SPELLpyHandle newCommand = PyObject_CallMethod(m_service,(char*)"_startWatchDog", (char*)"(O)", callbackObj,NULL);
+ SPELLpythonHelper::instance().checkError();
+}
+
+void SPELLpyService::start()
+{
+ SPELLsafePythonOperations ops("start");
+
+ SPELLpyHandle newCommand = PyObject_CallMethod(m_service,(char*)"_start", (char*)"()",NULL);
+ SPELLpythonHelper::instance().checkError();
+}
+
+PyObject* SPELLpyService::getStartFunction() const
+{
+ SPELLsafePythonOperations ops("_getStartCode");
+
+ PyObject* funcCode = PyObject_CallMethod(m_service,(char*)"_getStartCode", (char*)"()",NULL);
+ SPELLpythonHelper::instance().checkError();
+
+ return PyMethod_Function(funcCode);
+}
diff --git a/lib/SPELL_PRD/src/SPELLserviceRegisterPython.C b/lib/SPELL_PRD/src/SPELLserviceRegisterPython.C
new file mode 100644
index 0000000..9d6345e
--- /dev/null
+++ b/lib/SPELL_PRD/src/SPELLserviceRegisterPython.C
@@ -0,0 +1,181 @@
+// ################################################################################
+// FILE : SPELLSpellServicePython.C
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Implementation of the goto Python bindings
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// Local includes ----------------------------------------------------------
+#include "SPELL_UTIL/SPELLbase.H"
+#include "SPELL_PRD/SPELLservicePython.H"
+#include "SPELL_UTIL/SPELLlog.H"
+#include "SPELL_UTIL/SPELLpythonHelper.H"
+#include "SPELL_PRD/SPELLprocedureManager.H"
+// System includes ---------------------------------------------------------
+#include "structmember.h"
+
+
+
+//============================================================================
+// FUNCTION : SpellService_Init
+// DESCRIPTION : Initialized of the SpellService python object
+//============================================================================
+static int SpellService_Init( PySpellServiceObject* self, PyObject* args, PyObject* kwds );
+//============================================================================
+// FUNCTION : SpellService_Dealloc
+// DESCRIPTION : Cleanup of the SpellService python object
+//============================================================================
+static void SpellService_Dealloc( PySpellServiceObject* self );
+//============================================================================
+// FUNCTION : SpellService_New
+// DESCRIPTION : Constructor of the SpellService python object
+//============================================================================
+static PyObject* SpellService_New( PyTypeObject* type, PyObject* args, PyObject* kwds );
+//============================================================================
+// FUNCTION : SpellService_Call
+// DESCRIPTION : Call a SpellService statement
+//============================================================================
+static PyObject* SpellService_Call( PyObject* self, PyObject* args, PyObject* kargs );
+
+
+
+//============================================================================
+// SpellService object member specification
+//============================================================================
+static PyMemberDef SpellService_Members[] =
+{
+ {NULL} /* Sentinel */
+};
+
+//============================================================================
+// SpellService object method specification
+//============================================================================
+static PyMethodDef SpellService_Methods[] =
+{
+ {NULL} /* Sentinel */
+};
+
+//============================================================================
+// Python representation of the SPELL SpellService object type
+//============================================================================
+static PyTypeObject SpellService_Type =
+{
+ PyVarObject_HEAD_INIT(NULL,0)
+ "context.RegisterSpellService", //tp_name
+ sizeof(PySpellServiceObject), //tp_basicsize
+ 0, //tp_itemsize
+ (destructor)SpellService_Dealloc, //tp_dealloc
+ 0, //tp_print
+ 0, //tp_getattr
+ 0, //tp_setattr
+ 0, //tp_compare
+ 0, //tp_repr
+ 0, //tp_as_number
+ 0, //tp_as_sequence
+ 0, //tp_as_mapping
+ 0, //tp_hash
+ SpellService_Call, //tp_call
+ 0, //tp_str
+ 0, //tp_getattro
+ 0, //tp_setattro
+ 0, //tp_as_buffer
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags
+ "RegisterSpellService mechanism", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ SpellService_Methods, // tp_methods
+ SpellService_Members, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ (initproc)SpellService_Init, // tp_init
+ 0, // tp_alloc
+ SpellService_New, // tp_new
+};
+
+
+//============================================================================
+// FUNCTION : SpellService_Init
+//============================================================================
+static int SpellService_Init( PySpellServiceObject* self, PyObject* args, PyObject* kwds )
+{
+ return 0;
+}
+
+//============================================================================
+// FUNCTION : SpellService_Dealloc
+//============================================================================
+static void SpellService_Dealloc( PySpellServiceObject* self )
+{
+ Py_TYPE(self)->tp_free( (PyObject*) self );
+}
+
+//============================================================================
+// FUNCTION : SpellService_New
+//============================================================================
+static PyObject* SpellService_New( PyTypeObject* type, PyObject* args, PyObject* kwds )
+{
+ //NOTE: Py_INCREF is already called!
+ PySpellServiceObject* self;
+ self = (PySpellServiceObject*) type->tp_alloc(type,0);
+ return (PyObject*)self;
+}
+
+//============================================================================
+// FUNCTION : SpellService_Call
+//============================================================================
+static PyObject* SpellService_Call( PyObject* self, PyObject* args, PyObject* kargs )
+{
+ PyObject* target = PyTuple_GetItem(args,0);
+ Py_IncRef(target);
+
+ SPELLprocedureManager::instance().registerServiceHandler(target);
+
+ return target;
+}
+
+//============================================================================
+// FUNCTION : SpellService_Install
+//============================================================================
+void SpellService_Install()
+{
+ LOG_INFO("Installing SpellService object");
+
+ if (PyType_Ready(&SpellService_Type) < 0 )
+ {
+ THROW_EXCEPTION("Cannot install SpellService", "Unable to register object type", SPELL_ERROR_PYTHON_API);
+ }
+
+ PyObject* SpellService = SpellService_New( &SpellService_Type, NULL, NULL );
+ Py_INCREF(SpellService);
+
+ SPELLpythonHelper::instance().install(SpellService,"RegisterSpellService");
+}
+
diff --git a/lib/SPELL_PRD/src/SPELLserviceWatchdogPython.C b/lib/SPELL_PRD/src/SPELLserviceWatchdogPython.C
new file mode 100644
index 0000000..7018933
--- /dev/null
+++ b/lib/SPELL_PRD/src/SPELLserviceWatchdogPython.C
@@ -0,0 +1,192 @@
+// ################################################################################
+// FILE : SPELLSpellServicePython.C
+// DATE : Mar 17, 2011
+// PROJECT : SPELL
+// DESCRIPTION: Implementation of the goto Python bindings
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+// FILES TO INCLUDE ////////////////////////////////////////////////////////
+// Local includes ----------------------------------------------------------
+#include "SPELL_UTIL/SPELLbase.H"
+#include "SPELL_PRD/SPELLserviceWatchdogPython.H"
+#include "SPELL_UTIL/SPELLlog.H"
+#include "SPELL_UTIL/SPELLpythonHelper.H"
+#include "SPELL_PRD/SPELLprocedureManager.H"
+// System includes ---------------------------------------------------------
+#include "structmember.h"
+
+
+
+//============================================================================
+// FUNCTION : SpellService_Init
+// DESCRIPTION : Initialized of the SpellService python object
+//============================================================================
+static int SpellServiceWatchdog_Init( PySpellServiceWatchdogObject* self, PyObject* args, PyObject* kwds );
+//============================================================================
+// FUNCTION : SpellService_Dealloc
+// DESCRIPTION : Cleanup of the SpellService python object
+//============================================================================
+static void SpellServiceWatchdog_Dealloc( PySpellServiceWatchdogObject* self );
+//============================================================================
+// FUNCTION : SpellService_New
+// DESCRIPTION : Constructor of the SpellService python object
+//============================================================================
+static PyObject* SpellServiceWatchdog_New( PyTypeObject* type, PyObject* args, PyObject* kwds );
+//============================================================================
+// FUNCTION : SpellService_Call
+// DESCRIPTION : Call a SpellService statement
+//============================================================================
+static PyObject* SpellServiceWatchdog_Call( PyObject* self, PyObject* args, PyObject* kargs );
+
+
+
+//============================================================================
+// SpellService object member specification
+//============================================================================
+static PyMemberDef SpellServiceWatchdog_Members[] =
+{
+ {"callback",T_OBJECT_EX,offsetof(PySpellServiceWatchdogObject,callback),0,"callback to C code"},
+ {NULL} /* Sentinel */
+};
+
+//============================================================================
+// SpellService object method specification
+//============================================================================
+static PyMethodDef SpellServiceWatchdog_Methods[] =
+{
+ {NULL} /* Sentinel */
+};
+
+//============================================================================
+// Python representation of the SPELL SpellService object type
+//============================================================================
+static PyTypeObject SpellServiceWatchdog_Type =
+{
+ PyVarObject_HEAD_INIT(NULL,0)
+ "context.WatchdogCallback", //tp_name
+ sizeof(PySpellServiceWatchdogObject), //tp_basicsize
+ 0, //tp_itemsize
+ (destructor)SpellServiceWatchdog_Dealloc, //tp_dealloc
+ 0, //tp_print
+ 0, //tp_getattr
+ 0, //tp_setattr
+ 0, //tp_compare
+ 0, //tp_repr
+ 0, //tp_as_number
+ 0, //tp_as_sequence
+ 0, //tp_as_mapping
+ 0, //tp_hash
+ SpellServiceWatchdog_Call, //tp_call
+ 0, //tp_str
+ 0, //tp_getattro
+ 0, //tp_setattro
+ 0, //tp_as_buffer
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, //tp_flags
+ "WatchdogCallback mechanism", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ SpellServiceWatchdog_Methods, // tp_methods
+ SpellServiceWatchdog_Members, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ (initproc)SpellServiceWatchdog_Init, // tp_init
+ 0, // tp_alloc
+ SpellServiceWatchdog_New, // tp_new
+};
+
+
+//============================================================================
+// FUNCTION : SpellService_Init
+//============================================================================
+static int SpellServiceWatchdog_Init( PySpellServiceWatchdogObject* self, PyObject* args, PyObject* kwds )
+{
+ return 0;
+}
+
+//============================================================================
+// FUNCTION : SpellService_Dealloc
+//============================================================================
+static void SpellServiceWatchdog_Dealloc( PySpellServiceWatchdogObject* self )
+{
+ Py_TYPE(self)->tp_free( (PyObject*) self );
+}
+
+//============================================================================
+// FUNCTION : SpellService_New
+//============================================================================
+static PyObject* SpellServiceWatchdog_New( PyTypeObject* type, PyObject* args, PyObject* kwds )
+{
+ //NOTE: Py_INCREF is already called!
+ PySpellServiceWatchdogObject* self;
+ self = (PySpellServiceWatchdogObject*) type->tp_alloc(type,0);
+ PyObject* callback = PyTuple_GetItem(args,0);
+ Py_INCREF(callback);
+ PyObject_SetAttrString((PyObject*)self, "callback",callback);
+
+ return (PyObject*)self;
+}
+
+//============================================================================
+// FUNCTION : SpellService_Call
+//============================================================================
+static PyObject* SpellServiceWatchdog_Call( PyObject* self, PyObject* args, PyObject* kargs )
+{
+ PyObject* target = PyTuple_GetItem(args,0);
+ Py_IncRef(target);
+
+ void (*callback)(std::string&);
+ PyObject* obj = PyObject_GetAttrString(self,"callback");
+ callback = (void (*)(std::string&))PyCapsule_GetPointer(obj, NULL);
+
+ std::string targetStr= PyString_AsString(target);
+ callback(targetStr);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+//============================================================================
+// FUNCTION : SpellService_Install
+//============================================================================
+PyObject* SpellServiceWatchdog_Create(void (*callback)(std::string&) )
+{
+ LOG_INFO("Installing SpellService object");
+
+ if (PyType_Ready(&SpellServiceWatchdog_Type) < 0 )
+ {
+ THROW_EXCEPTION("Cannot install SpellService", "Unable to register object type", SPELL_ERROR_PYTHON_API);
+ }
+ PyObject* callbackObj = PyCapsule_New((void*) callback,NULL,NULL);
+ PyObject* args = PyTuple_Pack(1,callbackObj,NULL);
+ PyObject* watchdog = SpellServiceWatchdog_New( &SpellServiceWatchdog_Type, args, NULL );
+ Py_INCREF(watchdog);
+
+ return watchdog;
+}
+
diff --git a/lib/SPELL_SDB/Makefile.am b/lib/SPELL_SDB/Makefile.am
index 1d58057..bdbd0a6 100644
--- a/lib/SPELL_SDB/Makefile.am
+++ b/lib/SPELL_SDB/Makefile.am
@@ -1,41 +1,46 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
include ${top_srcdir}/common.mk
-lib_LTLIBRARIES= libSPELL_SDB.la
+lib_LTLIBRARIES = libSPELL_SDB_v2.la libSPELL_SDB_v3.la
-libSPELL_SDB_la_CPPFLAGS = ${AM_CPPFLAGS} -DWITH_DEBUG
-libSPELL_SDB_la_LDFLAGS = -version-info 1:0:0
+libSPELL_SDB_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
-libSPELL_SDB_la_SOURCES = \
- src/SPELLpyDatabaseMethods.C \
- src/SPELLpyDatabaseModule.C \
- src/SPELLdatabase.C \
- src/SPELLdatabaseFile.C \
- src/SPELLdatabaseFileSPB.C \
- src/SPELLdatabaseFactory.C
-
+libSPELL_SDB_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_SDB_v2_la_SOURCES = src/SPELLpyDatabaseMethods.C \
+ src/SPELLpyDatabaseModule.C \
+ src/SPELLdatabase.C \
+ src/SPELLdatabaseFile.C \
+ src/SPELLdatabaseFileSPB.C \
+ src/SPELLdatabaseFactory.C
+
+libSPELL_SDB_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS}
+
+libSPELL_SDB_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_SDB_v3_la_SOURCES = src/SPELLpyDatabaseMethods.C \
+ src/SPELLpyDatabaseModule.C \
+ src/SPELLdatabase.C \
+ src/SPELLdatabaseFile.C \
+ src/SPELLdatabaseFileSPB.C \
+ src/SPELLdatabaseFactory.C
diff --git a/lib/SPELL_SDB/src/SPELLdatabase.C b/lib/SPELL_SDB/src/SPELLdatabase.C
index 28ca202..641784d 100644
--- a/lib/SPELL_SDB/src/SPELLdatabase.C
+++ b/lib/SPELL_SDB/src/SPELLdatabase.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of SPELL database
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_SDB/src/SPELLdatabaseFactory.C b/lib/SPELL_SDB/src/SPELLdatabaseFactory.C
index e7f1f61..f2118df 100644
--- a/lib/SPELL_SDB/src/SPELLdatabaseFactory.C
+++ b/lib/SPELL_SDB/src/SPELLdatabaseFactory.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of SPELL database factory
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_SDB/src/SPELLdatabaseFile.C b/lib/SPELL_SDB/src/SPELLdatabaseFile.C
index 072f6a7..5dda807 100644
--- a/lib/SPELL_SDB/src/SPELLdatabaseFile.C
+++ b/lib/SPELL_SDB/src/SPELLdatabaseFile.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of database based on local files
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_SDB/src/SPELLdatabaseFileSPB.C b/lib/SPELL_SDB/src/SPELLdatabaseFileSPB.C
index 8f7494c..243cc5d 100644
--- a/lib/SPELL_SDB/src/SPELLdatabaseFileSPB.C
+++ b/lib/SPELL_SDB/src/SPELLdatabaseFileSPB.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation based on local SPB files
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_SDB/src/SPELLpyDatabaseMethods.C b/lib/SPELL_SDB/src/SPELLpyDatabaseMethods.C
index f0844fe..2be34d0 100644
--- a/lib/SPELL_SDB/src/SPELLpyDatabaseMethods.C
+++ b/lib/SPELL_SDB/src/SPELLpyDatabaseMethods.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of database Python bindings
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -46,7 +46,7 @@ int SPELLpyDatabase_Init( PyDatabaseObject* self, PyObject* args, PyObject* kwds
std::string name = "";
std::string file = "";
std::string ext = "";
- std::string type = self->ob_type->tp_name;
+ std::string type = Py_TYPE(self)->tp_name;
if (PyTuple_Size(args)!=3)
{
THROW_SYNTAX_EXCEPTION_NR("Cannot initialize database", "Expected database name, file and default extension");
@@ -93,7 +93,7 @@ void SPELLpyDatabase_Dealloc( PyDatabaseObject* self )
{
delete self->__pdb;
self->__pdb = NULL;
- self->ob_type->tp_free( (PyObject*) self );
+ Py_TYPE(self)->tp_free( (PyObject*) self );
}
//============================================================================
@@ -614,8 +614,7 @@ static PyMethodDef dictiter_methods[] = {
PyTypeObject PyDatabaseIterator_Type =
{
- PyObject_HEAD_INIT(&PyType_Type)
- 0, /* ob_size */
+ PyVarObject_HEAD_INIT(&PyType_Type,0)
"database-keyiterator", /* tp_name */
sizeof(PyDatabaseIteratorObject), /* tp_basicsize */
0, /* tp_itemsize */
@@ -668,7 +667,7 @@ PyObject* SPELLpyDatabase_NewIterator( PyDatabaseObject* container )
//============================================================================
void SPELLpyDatabase_DeallocIterator( PyDatabaseIteratorObject* di )
{
- di->ob_type->tp_free( (PyObject*)di );
+ Py_TYPE(di)->tp_free( (PyObject*)di );
}
//============================================================================
@@ -676,34 +675,26 @@ void SPELLpyDatabase_DeallocIterator( PyDatabaseIteratorObject* di )
//============================================================================
PyObject* SPELLpyDatabase_NextKey( PyDatabaseIteratorObject* di )
{
- PyObject *key;
- register Py_ssize_t i, mask;
- register PyDictEntry *ep;
- PyDictObject* d = di->di_dict;
+ PyObject *key,*value;
+ Py_ssize_t i;
+ int result;
+ PyObject* d = (PyObject*)di->di_dict;
if (d == NULL) return NULL;
assert (PyDict_Check(d));
- if (di->di_used != d->ma_used)
- {
- PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration");
- di->di_used = -1; /* Make this state sticky */
- return NULL;
- }
-
i = di->di_pos;
if (i < 0) goto fail;
- ep = d->ma_table;
- mask = d->ma_mask;
- while (i <= mask && ep[i].me_value == NULL) i++;
- di->di_pos = i+1;
- if (i > mask) goto fail;
+
+ result = PyDict_Next(d, &di->di_pos, &key, &value);
+
+ if (!result) goto fail;
+
di->len--;
- key = ep[i].me_key;
+
Py_INCREF(key);
return key;
fail:
- Py_DECREF(d);
di->di_dict = NULL;
return NULL;
}
diff --git a/lib/SPELL_SDB/src/SPELLpyDatabaseModule.C b/lib/SPELL_SDB/src/SPELLpyDatabaseModule.C
index 37c8ee9..dd40883 100644
--- a/lib/SPELL_SDB/src/SPELLpyDatabaseModule.C
+++ b/lib/SPELL_SDB/src/SPELLpyDatabaseModule.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of Python database module
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -78,8 +78,8 @@ DATABASE_DEFINITION( SPELLpyDatabaseFileSPB_Type, "spell.adapter.databases.Datab
//////////////////////////////////////////////////////////////////////////////
// PYTHON MODULE INITIALIZATION
//////////////////////////////////////////////////////////////////////////////
-PyMODINIT_FUNC
-initlibSPELL_SDB(void)
+
+MOD_INIT(libSPELL_SDB)
{
// Will hold the Python module
PyObject* module;
@@ -90,10 +90,12 @@ initlibSPELL_SDB(void)
DATABASE_TYPE_READY(SPELLpyDatabaseFileSPB_Type);
// Initialize the module
- module = Py_InitModule3("libSPELL_SDB", NULL, "Module for SPELL databases");
+ MOD_DEF(module,MOD_NAME(libSPELL_SDB),"Module for SPELL databases",NULL)
// Add the classes to the module dictionary
DATABASE_TYPE_LOAD(module, SPELLpyDatabase_Type, "Database" );
DATABASE_TYPE_LOAD(module, SPELLpyDatabaseFile_Type, "DatabaseFile" );
DATABASE_TYPE_LOAD(module, SPELLpyDatabaseFileSPB_Type, "DatabaseFileSPB" );
+
+ return MOD_SUCCESS_VAL(module);
}
diff --git a/lib/SPELL_SYN/Makefile.am b/lib/SPELL_SYN/Makefile.am
index 8416b6c..0759e83 100644
--- a/lib/SPELL_SYN/Makefile.am
+++ b/lib/SPELL_SYN/Makefile.am
@@ -1,49 +1,53 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
include ${top_srcdir}/common.mk
-lib_LTLIBRARIES= libSPELL_SYN.la
-
-libSPELL_SYN_la_LDFLAGS = -version-info 1:0:0
-
-if PLATFORM_LINUX
- ADDITIONAL_SRC= src/SPELLmutexPOSIX.C \
- src/SPELLmutexFactoryPOSIX.C \
- src/SPELLconditionPOSIX.C \
- src/SPELLconditionFactoryPOSIX.C
-else
- ADDITIONAL_SRC=
-endif
-
-libSPELL_SYN_la_SOURCES = $(ADDITIONAL_SRC) \
- src/SPELLtimer.C \
- src/SPELLevent.C \
- src/SPELLthread.C \
- src/SPELLthreadWorker.C \
- src/SPELLthreadPool.C
-
-
+lib_LTLIBRARIES = libSPELL_SYN_v2.la libSPELL_SYN_v3.la
+
+libSPELL_SYN_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+
+libSPELL_SYN_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_SYN_v2_la_SOURCES = src/SPELLmutexPOSIX.C \
+ src/SPELLmutexFactoryPOSIX.C \
+ src/SPELLconditionPOSIX.C \
+ src/SPELLconditionFactoryPOSIX.C \
+ src/SPELLtimer.C \
+ src/SPELLevent.C \
+ src/SPELLthread.C \
+ src/SPELLthreadWorker.C \
+ src/SPELLthreadPool.C
+
+libSPELL_SYN_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS}
+
+libSPELL_SYN_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_SYN_v3_la_SOURCES = src/SPELLmutexPOSIX.C \
+ src/SPELLmutexFactoryPOSIX.C \
+ src/SPELLconditionPOSIX.C \
+ src/SPELLconditionFactoryPOSIX.C \
+ src/SPELLtimer.C \
+ src/SPELLevent.C \
+ src/SPELLthread.C \
+ src/SPELLthreadWorker.C \
+ src/SPELLthreadPool.C
+
\ No newline at end of file
diff --git a/lib/SPELL_SYN/src/SPELLconditionFactoryPOSIX.C b/lib/SPELL_SYN/src/SPELLconditionFactoryPOSIX.C
index fbdad75..a689e98 100644
--- a/lib/SPELL_SYN/src/SPELLconditionFactoryPOSIX.C
+++ b/lib/SPELL_SYN/src/SPELLconditionFactoryPOSIX.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of condition factory for POSIX
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_SYN/src/SPELLconditionPOSIX.C b/lib/SPELL_SYN/src/SPELLconditionPOSIX.C
index 34757f5..7fe518b 100644
--- a/lib/SPELL_SYN/src/SPELLconditionPOSIX.C
+++ b/lib/SPELL_SYN/src/SPELLconditionPOSIX.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of condition mechanism for POSIX
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -36,7 +36,21 @@
//=============================================================================
SPELLconditionPOSIX::SPELLconditionPOSIX()
{
- pthread_cond_init(&m_condition, NULL);
+ int result = pthread_cond_init(&m_condition, NULL);
+ if (result == EAGAIN){
+ LOG_ERROR("[SPELLconditionPOSIX.create] Error creating condition! The system lacked the necessary resources (other than memory) to initialise another condition variable.");
+ } else if (result == ENOMEM) {
+ LOG_ERROR("[SPELLconditionPOSIX.create] Error creating condition! Insufficient memory exists to initialise the condition variable.");
+ } else if (result == EBUSY) {
+ LOG_ERROR("[SPELLconditionPOSIX.create] Error creating condition! The implementation has detected an attempt to re-initialise the object referenced by cond, a previously initialised, but not yet destroyed, condition variable.");
+ } else if (result == EINVAL) {
+ LOG_ERROR("[SPELLconditionPOSIX.create] Error creating condition! The value specified by attr is invalid.");
+ }
+//#ifdef WITH_DEBUG
+// std::stringstream buf;
+// buf << "SPELLconditionPOSIX create " << &m_condition;
+// DEBUG( buf.str());
+//#endif
}
//=============================================================================
@@ -44,7 +58,12 @@ SPELLconditionPOSIX::SPELLconditionPOSIX()
//=============================================================================
SPELLconditionPOSIX::~SPELLconditionPOSIX()
{
- pthread_cond_destroy(&m_condition);
+//#ifdef WITH_DEBUG
+// std::stringstream buf;
+// buf << "SPELLconditionPOSIX destroy " << &m_condition;
+// DEBUG( buf.str());
+//#endif
+ pthread_cond_destroy(&m_condition);
}
//=============================================================================
@@ -73,8 +92,23 @@ bool SPELLconditionPOSIX::wait( SPELLmutex* m, unsigned long timeoutMsec )
clock_gettime(CLOCK_REALTIME, &abstime);
abstime.tv_sec += timeoutMsec / 1000;
abstime.tv_nsec += ( timeoutMsec - (timeoutMsec / 1000)*1000 ) * 1000;
+ if (abstime.tv_nsec >= 1000000000){
+ DEBUG("[SPELLconditionPOSIX.wait] abstime.tv_nsec is >= 1000000000. This may cause Condition error EINVAL. Value will be corrected.");
+ abstime.tv_sec += abstime.tv_nsec / 1000000000;
+ abstime.tv_nsec = abstime.tv_nsec % 1000000000;
+ }
+ if (abstime.tv_nsec < 0) {
+ DEBUG("[SPELLconditionPOSIX.wait] abstime.tv_nsec is < 0. This may cause Condition error EINVAL. Value will be corrected.");
+ abstime.tv_sec -= 1;
+ abstime.tv_nsec = (abstime.tv_nsec + 1000000000) % 1000000000;
+ }
SPELLmutexPOSIX* pmutex = dynamic_cast(m->getImpl());
assert(pmutex->get() != 0);
+//#ifdef WITH_DEBUG
+// std::stringstream buf;
+// buf << "SPELLconditionPOSIX pthread_cond_timedwait " << &m_condition;
+// DEBUG( buf.str());
+//#endif
int ret = pthread_cond_timedwait(&m_condition, pmutex->get(), &abstime);
if (ret == ETIMEDOUT)
{
diff --git a/lib/SPELL_SYN/src/SPELLevent.C b/lib/SPELL_SYN/src/SPELLevent.C
index 644d4e3..8ded4c3 100644
--- a/lib/SPELL_SYN/src/SPELLevent.C
+++ b/lib/SPELL_SYN/src/SPELLevent.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the event mechanism
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -42,7 +42,7 @@ SPELLevent::SPELLevent( bool log )
{
m_log = log;
m_isClear = false;
- DEBUG("[EVE] Event " + PSTR(this) + " created with mutex " + PSTR(&m_mutex))
+ //DEBUG("[EVE] Event " + PSTR(this) + " created with mutex " + PSTR(&m_mutex))
if (m_log) std::cerr << " CREATE EVENT " << (void*) this << std::endl;
}
@@ -51,7 +51,7 @@ SPELLevent::SPELLevent( bool log )
//=============================================================================
SPELLevent::~SPELLevent()
{
- DEBUG("[EVE] Event " + PSTR(this) + " destroyed")
+ //DEBUG("[EVE] Event " + PSTR(this) + " destroyed")
if (m_log) std::cerr << " DESTROY EVENT " << (void*) this << std::endl;
}
@@ -61,7 +61,7 @@ SPELLevent::~SPELLevent()
void SPELLevent::set()
{
if (m_log) std::cerr << "SET EVENT TRY IN " << (void*) this << std::endl;
- DEBUG("[EVE] Event " + PSTR(this) + " set")
+ //DEBUG("[EVE] Event " + PSTR(this) + " set")
m_mutex.lock();
if (m_isClear)
{
@@ -80,7 +80,7 @@ void SPELLevent::set()
void SPELLevent::clear()
{
if (m_log) std::cerr << "CHECK CLEAR EVENT IN " << (void*) this << std::endl;
- DEBUG("[EVE] Event " + PSTR(this) + " clear")
+ //DEBUG("[EVE] Event " + PSTR(this) + " clear")
m_mutex.lock();
m_isClear = true;
m_mutex.unlock();
@@ -93,14 +93,14 @@ void SPELLevent::clear()
void SPELLevent::wait()
{
if (m_log) std::cerr << "WAIT EVENT TRY IN " << (void*) this << std::endl;
- DEBUG("[EVE] Event " + PSTR(this) + " wait in with mutex " + PSTR(&m_mutex))
+ //DEBUG("[EVE] Event " + PSTR(this) + " wait in with mutex " + PSTR(&m_mutex))
m_mutex.lock();
while (m_isClear)
{
m_condition.wait(&m_mutex);
}
m_mutex.unlock();
- DEBUG("[EVE] Event " + PSTR(this) + " wait out")
+ //DEBUG("[EVE] Event " + PSTR(this) + " wait out")
if (m_log) std::cerr << "WAIT EVENT FINISH " << (void*) this << std::endl;
}
@@ -110,7 +110,7 @@ void SPELLevent::wait()
bool SPELLevent::wait( unsigned long timeoutMsec )
{
bool timedout = false;
- DEBUG("[EVE] Event " + PSTR(this) + " wait in with mutex " + PSTR(&m_mutex))
+ //DEBUG("[EVE] Event " + PSTR(this) + " wait in with mutex " + PSTR(&m_mutex))
if (m_log) std::cerr << " WAIT EVENT T.O. TRY IN " << (void*) this << std::endl;
m_mutex.lock();
while (m_isClear && !timedout)
@@ -121,7 +121,7 @@ bool SPELLevent::wait( unsigned long timeoutMsec )
}
m_mutex.unlock();
if (m_log) std::cerr << " WAIT EVENT T.O. FINISH" << (void*) this << std::endl;
- DEBUG("[EVE] Event " + PSTR(this) + " wait out")
+ //DEBUG("[EVE] Event " + PSTR(this) + " wait out")
return timedout;
}
@@ -131,7 +131,7 @@ bool SPELLevent::wait( unsigned long timeoutMsec )
bool SPELLevent::isClear()
{
if (m_log) std::cerr << " IS CLEAR EVENT IN " << (void*) this << std::endl;
- DEBUG("[EVE] Event " + PSTR(this) + " isclear with mutex " + PSTR(&m_mutex))
+ //DEBUG("[EVE] Event " + PSTR(this) + " isclear with mutex " + PSTR(&m_mutex))
bool isClear = false;
m_mutex.lock();
isClear = m_isClear;
diff --git a/lib/SPELL_SYN/src/SPELLmutexFactoryPOSIX.C b/lib/SPELL_SYN/src/SPELLmutexFactoryPOSIX.C
index c9c759e..e81712c 100644
--- a/lib/SPELL_SYN/src/SPELLmutexFactoryPOSIX.C
+++ b/lib/SPELL_SYN/src/SPELLmutexFactoryPOSIX.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the mutex factory for POSIX
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_SYN/src/SPELLmutexPOSIX.C b/lib/SPELL_SYN/src/SPELLmutexPOSIX.C
index f3fe595..e98e9fb 100644
--- a/lib/SPELL_SYN/src/SPELLmutexPOSIX.C
+++ b/lib/SPELL_SYN/src/SPELLmutexPOSIX.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the mutex mechanism for POSIX
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -36,6 +36,7 @@
SPELLmutexPOSIX::SPELLmutexPOSIX()
: SPELLmutexIF()
{
+ m_threadId = 0;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
diff --git a/lib/SPELL_SYN/src/SPELLthread.C b/lib/SPELL_SYN/src/SPELLthread.C
index 5746b09..cbaa733 100644
--- a/lib/SPELL_SYN/src/SPELLthread.C
+++ b/lib/SPELL_SYN/src/SPELLthread.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the thread mechanism
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -55,7 +55,7 @@ SPELLthread::SPELLthread( std::string id )
pthread_attr_init(&m_threadAttr);
pthread_attr_setdetachstate(&m_threadAttr, PTHREAD_CREATE_JOINABLE);
m_threadRunning = false;
- DEBUG("[THR] Thread " + m_threadId + " created")
+ // DEBUG("[THR] Thread " + m_threadId + " created")
}
//=============================================================================
@@ -63,7 +63,7 @@ SPELLthread::SPELLthread( std::string id )
//=============================================================================
SPELLthread::~SPELLthread()
{
- DEBUG("[THR] Thread " + m_threadId + " do destroy");
+ //DEBUG("[THR] Thread " + m_threadId + " do destroy");
m_threadRunning = false;
pthread_attr_destroy(&m_threadAttr);
}
@@ -74,12 +74,24 @@ SPELLthread::~SPELLthread()
void SPELLthread::start()
{
SPELLmonitor m(m_threadLock);
- int result = pthread_create(&m_thread, (const pthread_attr_t*) &m_threadAttr, do_run, this );
- //std::cerr << "==== create thread " << m_thread << " " << m_threadId << std::endl;
- if( result != 0)
- {
- throw SPELLsyncError("Unable to start thread", "Cannot create thread: " + ISTR(result));
- }
+ int result;
+ int tries = 0;
+ do {
+ result = pthread_create(&m_thread, (const pthread_attr_t*) &m_threadAttr, do_run, this );
+ tries++;
+ if (result != 0)
+ {
+ if (tries > 10)
+ {
+ perror("pthread_create");
+ throw SPELLsyncError("Unable to start thread", "Cannot create thread: " + ISTR(result));
+ }
+ else
+ {
+ usleep(500000);
+ }
+ }
+ } while (result != 0);
}
//=============================================================================
@@ -116,10 +128,10 @@ void SPELLthread::doRun()
void SPELLthread::join()
{
//std::cerr << "==== before join " << m_thread << " " << m_threadId << std::endl;
- SPELLmonitor m(m_threadLock);
- if (m_thread != 0)
+ pthread_t thread = m_thread;
+ if (thread != 0)
{
- pthread_join(m_thread, NULL);
+ pthread_join(thread, NULL);
//std::cerr << "==== after join " << m_thread << " " << m_threadId << std::endl;
m_thread = 0;
m_threadRunning = false;
diff --git a/lib/SPELL_SYN/src/SPELLthreadPool.C b/lib/SPELL_SYN/src/SPELLthreadPool.C
index a1447d8..be732e9 100644
--- a/lib/SPELL_SYN/src/SPELLthreadPool.C
+++ b/lib/SPELL_SYN/src/SPELLthreadPool.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the thread pool mechanism
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_SYN/src/SPELLthreadWorker.C b/lib/SPELL_SYN/src/SPELLthreadWorker.C
index e11d396..a3de9a2 100644
--- a/lib/SPELL_SYN/src/SPELLthreadWorker.C
+++ b/lib/SPELL_SYN/src/SPELLthreadWorker.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the thread worker mechanism
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -44,6 +44,7 @@ SPELLthreadWorker::SPELLthreadWorker( const std::string& id )
m_work = NULL;
m_shutdown = false;
m_newWork.clear();
+ m_busy = false;
}
//=============================================================================
diff --git a/lib/SPELL_SYN/src/SPELLtimer.C b/lib/SPELL_SYN/src/SPELLtimer.C
index 18290b8..4f2400b 100644
--- a/lib/SPELL_SYN/src/SPELLtimer.C
+++ b/lib/SPELL_SYN/src/SPELLtimer.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the timer mechanism
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -46,7 +46,7 @@ SPELLtimer::SPELLtimer( unsigned long period, SPELLtimerListener& listener )
m_period = period;
m_elapsed = 0;
m_timeout = 0;
- DEBUG("[TMR] Timer created (1) " + PSTR(this))
+ //DEBUG("[TMR] Timer created (1) " + PSTR(this))
}
//=============================================================================
@@ -61,7 +61,7 @@ SPELLtimer::SPELLtimer( unsigned long period, SPELLtimerListener& listener, unsi
m_period = period;
m_elapsed = 0;
m_timeout = timeout;
- DEBUG("[TMR] Timer created (2) " + PSTR(this))
+ //DEBUG("[TMR] Timer created (2) " + PSTR(this))
}
//=============================================================================
@@ -79,26 +79,26 @@ SPELLtimer::~SPELLtimer()
//=============================================================================
void SPELLtimer::run()
{
- DEBUG("[TMR] Timer thread started: " + PSTR(this))
+ //DEBUG("[TMR] Timer thread started: " + PSTR(this))
setCounting(true);
while(isCounting())
{
usleep(m_period*1000);// Period is given in msec
if (callTimerCallback())
{
- DEBUG("[TMR] Ending timer thread (callback) for " + PSTR(this))
+ //DEBUG("[TMR] Ending timer thread (callback) for " + PSTR(this))
return;
}
if (checkTimeout())
{
- DEBUG("[TMR] Ending timer thread (timeout) for " + PSTR(this))
+ //DEBUG("[TMR] Ending timer thread (timeout) for " + PSTR(this))
return;
}
- DEBUG("[TMR] Stop event wait in " + PSTR(this))
+ //DEBUG("[TMR] Stop event wait in " + PSTR(this))
wait();
- DEBUG("[TMR] Stop event wait out " + PSTR(this))
+ //DEBUG("[TMR] Stop event wait out " + PSTR(this))
}
- DEBUG("[TMR] Ending timer thread for " + PSTR(this))
+ //DEBUG("[TMR] Ending timer thread for " + PSTR(this))
}
//=============================================================================
@@ -137,10 +137,10 @@ bool SPELLtimer::checkTimeout()
//=============================================================================
void SPELLtimer::cancel()
{
- DEBUG("[TMR] Cancelling timer thread IN" + PSTR(this))
+ //DEBUG("[TMR] Cancelling timer thread IN" + PSTR(this))
setCounting(false);
cont();
- DEBUG("[TMR] Cancelling timer thread " + PSTR(this) + " OUT ")
+ //DEBUG("[TMR] Cancelling timer thread " + PSTR(this) + " OUT ")
}
//=============================================================================
@@ -166,7 +166,7 @@ void SPELLtimer::setCounting( bool counting )
//=============================================================================
void SPELLtimer::stop()
{
- DEBUG("[TMR] Stopping timer IN" + PSTR(this))
+ //DEBUG("[TMR] Stopping timer IN" + PSTR(this))
SPELLmonitor monitor(m_mutex);
m_stopEvent.clear();
}
@@ -176,7 +176,7 @@ void SPELLtimer::stop()
//=============================================================================
void SPELLtimer::cont()
{
- DEBUG("[TMR] Continue timer IN" + PSTR(this))
+ //DEBUG("[TMR] Continue timer IN" + PSTR(this))
SPELLmonitor monitor(m_mutex);
m_stopEvent.set();
}
@@ -186,6 +186,6 @@ void SPELLtimer::cont()
//=============================================================================
void SPELLtimer::wait()
{
- DEBUG("[TMR] Wait timer IN" + PSTR(this))
+ //DEBUG("[TMR] Wait timer IN" + PSTR(this))
m_stopEvent.wait();
}
diff --git a/lib/SPELL_UTIL/Makefile.am b/lib/SPELL_UTIL/Makefile.am
index fbfa0e5..a2d346e 100644
--- a/lib/SPELL_UTIL/Makefile.am
+++ b/lib/SPELL_UTIL/Makefile.am
@@ -1,41 +1,51 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
include ${top_srcdir}/common.mk
-lib_LTLIBRARIES= libSPELL_UTIL.la
+lib_LTLIBRARIES = libSPELL_UTIL_v2.la libSPELL_UTIL_v3.la
-libSPELL_UTIL_la_LDFLAGS = -version-info 3:0:0
-libSPELL_UTIL_la_SOURCES = \
- src/SPELLtime.C \
- src/SPELLutils.C \
- src/SPELLlog.C \
- src/SPELLpythonHelper.C \
- src/SPELLlogPython.C \
- src/SPELLpyArgs.C \
- src/SPELLcompression.C \
- src/SPELLerror.C
-
+libSPELL_UTIL_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+
+libSPELL_UTIL_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_UTIL_v2_la_SOURCES = src/SPELLtime.C \
+ src/SPELLutils.C \
+ src/SPELLlog.C \
+ src/SPELLpythonHelper.C \
+ src/SPELLlogPython.C \
+ src/SPELLpyArgs.C \
+ src/SPELLcompression.C \
+ src/SPELLerror.C
+
+
+libSPELL_UTIL_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS}
+
+libSPELL_UTIL_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_UTIL_v3_la_SOURCES = src/SPELLtime.C \
+ src/SPELLutils.C \
+ src/SPELLlog.C \
+ src/SPELLpythonHelper.C \
+ src/SPELLlogPython.C \
+ src/SPELLpyArgs.C \
+ src/SPELLcompression.C \
+ src/SPELLerror.C
diff --git a/lib/SPELL_UTIL/src/SPELLcompression.C b/lib/SPELL_UTIL/src/SPELLcompression.C
index 6e4dd38..4d35184 100644
--- a/lib/SPELL_UTIL/src/SPELLcompression.C
+++ b/lib/SPELL_UTIL/src/SPELLcompression.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the compression utility
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_UTIL/src/SPELLerror.C b/lib/SPELL_UTIL/src/SPELLerror.C
index b431062..49939d0 100644
--- a/lib/SPELL_UTIL/src/SPELLerror.C
+++ b/lib/SPELL_UTIL/src/SPELLerror.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the Python error bindings
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -101,8 +101,7 @@ static PyMethodDef ExecutionAborted_Methods[] =
//============================================================================
static PyTypeObject ExecutionAborted_Type =
{
- PyObject_HEAD_INIT(NULL)
- 0, //ob_size
+ PyVarObject_HEAD_INIT(NULL,0)
"executor.ExecutionAborted", //tp_name
sizeof(PyExecutionAbortedObject), //tp_basicsize
0, //tp_itemsize
@@ -163,8 +162,7 @@ static PyMethodDef ExecutionTerminated_Methods[] =
//============================================================================
static PyTypeObject ExecutionTerminated_Type =
{
- PyObject_HEAD_INIT(NULL)
- 0, //ob_size
+ PyVarObject_HEAD_INIT(NULL,0)
"executor.ExecutionTerminated", //tp_name
sizeof(PyExecutionTerminatedObject), //tp_basicsize
0, //tp_itemsize
@@ -232,7 +230,7 @@ static int ExecutionAborted_Init( PyExecutionAbortedObject* self, PyObject* args
static void ExecutionAborted_Dealloc( PyExecutionAbortedObject* self )
{
Py_XDECREF(self->message);
- self->ob_type->tp_free( (PyObject*) self );
+ Py_TYPE(self)->tp_free( (PyObject*) self );
}
//============================================================================
@@ -269,7 +267,7 @@ static int ExecutionTerminated_Init( PyExecutionTerminatedObject* self, PyObject
//============================================================================
static void ExecutionTerminated_Dealloc( PyExecutionTerminatedObject* self )
{
- self->ob_type->tp_free( (PyObject*) self );
+ Py_TYPE(self)->tp_free( (PyObject*) self );
}
//============================================================================
@@ -499,7 +497,7 @@ SPELLcoreException* SPELLerror::errorToException( PyObject* err, PyObject* ptype
}
else
{
- message = " (no back trace information)\n";
+ message = "";
}
LOG_ERROR("**************************************");
@@ -513,7 +511,7 @@ SPELLcoreException* SPELLerror::errorToException( PyObject* err, PyObject* ptype
else
{
PyObject* data = PyTuple_GetItem(pvalue, 1);
- if (PyTuple_Size(data)==4)
+ if (data && PyTuple_Size(data)==4)
{
PyObject* filename = PyTuple_GetItem( data, 0);
PyObject* lineno = PyTuple_GetItem( data, 1);
@@ -555,7 +553,7 @@ SPELLcoreException* SPELLerror::errorToException( PyObject* err, PyObject* ptype
else if (PyErr_GivenExceptionMatches(err, PyExc_SyntaxError))
{
// It is a tuple like ('invalid syntax', ('file.py', lineno, offset, 'text'))
- message = "Unknown syntax error (could not gather information)\n" + message;
+ message = "Syntax error\n" + message;
if (PyTuple_Size(pvalue)==2)
{
PyObject* data = PyTuple_GetItem(pvalue, 1);
diff --git a/lib/SPELL_UTIL/src/SPELLlog.C b/lib/SPELL_UTIL/src/SPELLlog.C
index dea7c12..5a8139e 100644
--- a/lib/SPELL_UTIL/src/SPELLlog.C
+++ b/lib/SPELL_UTIL/src/SPELLlog.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the logger
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -109,7 +109,7 @@ void SPELLlog::setLogFile( const std::string& filename, const std::string timest
logfilename = logbase + "/" + logfilename;
m_logFileName = logfilename;
- log4cplus::SharedFileAppenderPtr appender( new log4cplus::RollingFileAppender(LOG4CPLUS_TEXT(logfilename), 10*1024*1024, 5, false, true));
+ log4cplus::SharedFileAppenderPtr appender( new log4cplus::RollingFileAppender(LOG4CPLUS_TEXT(logfilename), 10*1024*1024, 5, true, true));
appender->setLayout( std::auto_ptr(new log4cplus::PatternLayout(LOG_PATTERN)) );
appender->getloc();
log4cplus::Logger::getRoot().addAppender( log4cplus::SharedAppenderPtr(appender.get()) );
diff --git a/lib/SPELL_UTIL/src/SPELLlogPython.C b/lib/SPELL_UTIL/src/SPELLlogPython.C
index 72465d6..5c87bc6 100644
--- a/lib/SPELL_UTIL/src/SPELLlogPython.C
+++ b/lib/SPELL_UTIL/src/SPELLlogPython.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the logger bindings
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -88,8 +88,7 @@ static PyMethodDef Log_Methods[] =
//============================================================================
static PyTypeObject Log_Type =
{
- PyObject_HEAD_INIT(NULL)
- 0, //ob_size
+ PyVarObject_HEAD_INIT(NULL, 0)
"executor.LOG", //tp_name
sizeof(PyLogObject), //tp_basicsize
0, //tp_itemsize
@@ -143,7 +142,7 @@ static int Log_Init( PyLogObject* self, PyObject* args, PyObject* kwds )
//============================================================================
static void Log_Dealloc( PyLogObject* self )
{
- self->ob_type->tp_free( (PyObject*) self );
+ Py_TYPE(self)->tp_free( (PyObject*) self );
}
//============================================================================
@@ -232,6 +231,8 @@ static PyObject* Log_Call( PyObject* self, PyObject* args, PyObject* kargs )
case LOG_ERROR:
LOG_ERROR_PY(message);
break;
+ default:
+ break;
}
Py_RETURN_NONE;
diff --git a/lib/SPELL_UTIL/src/SPELLpyArgs.C b/lib/SPELL_UTIL/src/SPELLpyArgs.C
index 13cd96c..3fe504a 100644
--- a/lib/SPELL_UTIL/src/SPELLpyArgs.C
+++ b/lib/SPELL_UTIL/src/SPELLpyArgs.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the argument helper
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -220,7 +220,7 @@ SPELLtime SPELLpyArgs::getModifier_AsTime( const std::string& modifier ) const
bool SPELLpyArgs::getModifier_AsBoolean( const std::string& modifier ) const
{
PyObject* valueObj = (*this)[modifier];
- DEBUG("[CFGHLP] Configured modifier: " + PYREPR(valueObj))
+ DEBUG("[CFGHLP] Configured modifier: " + PYREPR(valueObj));
bool value = false;
if (valueObj != NULL)
{
@@ -282,7 +282,7 @@ SPELLtime SPELLpyArgs::getModifier_Delay() const
std::string SPELLpyArgs::getModifier_ValueFormat() const
{
PyObject* formatObj = (*this)[LanguageModifiers::ValueFormat];
- DEBUG("[CFGHLP] Configured ValueFormat: " + PYREPR(formatObj))
+ DEBUG("[CFGHLP] Configured ValueFormat: " + PYREPR(formatObj));
std::string format = LanguageConstants::ENG;
@@ -310,7 +310,7 @@ std::string SPELLpyArgs::getModifier_ValueFormat() const
std::string SPELLpyArgs::getModifier_Expected() const
{
PyObject* expectedObj = (*this)[LanguageModifiers::Expected];
- DEBUG("[CFGHLP] Configured Expected: " + PYREPR(expectedObj))
+ DEBUG("[CFGHLP] Configured Expected: " + PYREPR(expectedObj));
std::string expected = "";
if ( expectedObj != NULL )
@@ -333,7 +333,7 @@ std::string SPELLpyArgs::getModifier_Expected() const
std::string SPELLpyArgs::getModifier_LoRed() const
{
PyObject* valueObj = (*this)[LanguageModifiers::LoRed];
- DEBUG("[CFGHLP] Configured LoRed: " + PYREPR(valueObj))
+ DEBUG("[CFGHLP] Configured LoRed: " + PYREPR(valueObj));
std::string value = "";
if ( valueObj != NULL )
@@ -349,7 +349,7 @@ std::string SPELLpyArgs::getModifier_LoRed() const
std::string SPELLpyArgs::getModifier_LoYel() const
{
PyObject* valueObj = (*this)[LanguageModifiers::LoYel];
- DEBUG("[CFGHLP] Configured LoYel: " + PYREPR(valueObj))
+ DEBUG("[CFGHLP] Configured LoYel: " + PYREPR(valueObj));
std::string value = "";
if ( valueObj != NULL )
@@ -365,7 +365,7 @@ std::string SPELLpyArgs::getModifier_LoYel() const
std::string SPELLpyArgs::getModifier_HiRed() const
{
PyObject* valueObj = (*this)[LanguageModifiers::HiRed];
- DEBUG("[CFGHLP] Configured HiRed: " + PYREPR(valueObj))
+ DEBUG("[CFGHLP] Configured HiRed: " + PYREPR(valueObj));
std::string value = "";
if ( valueObj != NULL )
@@ -381,7 +381,39 @@ std::string SPELLpyArgs::getModifier_HiRed() const
std::string SPELLpyArgs::getModifier_HiYel() const
{
PyObject* valueObj = (*this)[LanguageModifiers::HiYel];
- DEBUG("[CFGHLP] Configured HiYel: " + PYREPR(valueObj))
+ DEBUG("[CFGHLP] Configured HiYel: " + PYREPR(valueObj));
+
+ std::string value = "";
+ if ( valueObj != NULL )
+ {
+ value = PYSSTR(valueObj);
+ }
+ return value;
+}
+
+//=============================================================================
+// METHOD: SPELLpyArgs::getModifier_Select()
+//=============================================================================
+std::string SPELLpyArgs::getModifier_Select() const
+{
+ PyObject* valueObj = (*this)[LanguageModifiers::Select];
+ DEBUG("[CFGHLP] Configured Select: " + PYREPR(valueObj));
+
+ std::string value = "";
+ if ( valueObj != NULL )
+ {
+ value = PYSSTR(valueObj);
+ }
+ return value;
+}
+
+//=============================================================================
+// METHOD: SPELLpyArgs::getModifier_LimitType()
+//=============================================================================
+std::string SPELLpyArgs::getModifier_LimitType() const
+{
+ PyObject* valueObj = (*this)[LanguageModifiers::Type];
+ DEBUG("[CFGHLP] Configured Limit Type: " + PYREPR(valueObj));
std::string value = "";
if ( valueObj != NULL )
@@ -546,10 +578,16 @@ std::string SPELLpyArgs::getModifier_Default() const
}
else if (PyFloat_Check( valueObj ))
{
+#if PY_MAJOR_VERSION >= 3
+ PyObject* obj = PyObject_Str(valueObj);
+ value = PyUnicode_AsUTF8(obj);
+ Py_DECREF(obj);
+#else
char* buffer = new char[512];
- PyFloat_AsString(buffer, (PyFloatObject*) (valueObj) );
- value = std::string(buffer);
- delete buffer;
+ PyFloat_AsString(buffer, (PyFloatObject*) (valueObj) );
+ value = std::string(buffer);
+ delete buffer;
+#endif
}
else if (PyBool_Check( valueObj ))
{
@@ -573,3 +611,4 @@ std::string SPELLpyArgs::getModifier_Default() const
}
return value;
}
+
diff --git a/lib/SPELL_UTIL/src/SPELLpythonHelper.C b/lib/SPELL_UTIL/src/SPELLpythonHelper.C
index 1cc035d..5357c39 100644
--- a/lib/SPELL_UTIL/src/SPELLpythonHelper.C
+++ b/lib/SPELL_UTIL/src/SPELLpythonHelper.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the Python helper
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -39,7 +39,12 @@
#include "Python-ast.h"
#include "opcode.h"
#include "traceback.h"
-
+#include "pystate.h"
+#if PY_MAJOR_VERSION >= 3
+# include "code.h"
+# include "frameobject.h"
+# include "structmember.h"
+#endif
// See setNewLine method
#undef MIN
#undef MAX
@@ -63,7 +68,7 @@ static PyObject * objargs_mktuple(va_list va)
int i, n = 0;
va_list countva;
PyObject *result, *tmp;
- countva = va;
+ va_copy(countva, va);
while ( ( (PyObject *) va_arg(countva, PyObject *)) != NULL)
{
++n;
@@ -139,7 +144,7 @@ void SPELLpythonHelper::importAllFrom( const std::string& package )
moduleDict = PyModule_GetDict( module );
}
- PyObject* mainModule = PyImport_AddModule("__main__");
+ PyObject* mainModule = PyImport_ImportModule(BUILTINS);
if (mainModule == NULL)
{
THROW_EXCEPTION("Cannot import " + package, "Unable to access main module", SPELL_ERROR_PYTHON_API );
@@ -152,18 +157,59 @@ void SPELLpythonHelper::importAllFrom( const std::string& package )
PyDict_Merge(main_dict, moduleDict, 0);
DEBUG("[PYH] Imported all from module " + package);
}
+void SPELLpythonHelper::updateBuiltinsWith( const std::string& package )
+{
+ LOG_INFO("Import all from " + package);
+ PyObject* dict = PyDict_New();
+ PyObject* module = PyImport_ImportModuleEx( const_cast(package.c_str()), dict, dict, NULL);
+ if ( module == NULL )
+ {
+ SPELLcoreException* ex = SPELLerror::instance().errorToException();
+ throw *ex;
+ }
+
+ // Borrowed
+ PyObject* moduleDict = PyModule_GetDict( module );
+ std::vector tokens = SPELLutils::tokenize( package, "." );
+
+ std::vector::iterator it;
+ for( it = tokens.begin(); it != tokens.end(); it++ )
+ {
+ // Skip the first token
+ if (it == tokens.begin()) continue;
+ // Get the submodule
+ // Borrowed reference
+ module = PyDict_GetItemString( moduleDict, (*it).c_str() );
+ moduleDict = PyModule_GetDict( module );
+ }
+
+ PyObject* mainModule = PyImport_ImportModule(BUILTINS);
+ if (mainModule == NULL)
+ {
+ THROW_EXCEPTION("Cannot import " + package, "Unable to access "BUILTINS" module", SPELL_ERROR_PYTHON_API );
+ }
+ PyObject* main_dict = PyModule_GetDict(mainModule);
+ if (main_dict== NULL)
+ {
+ THROW_EXCEPTION("Cannot import " + package, "Unable to access "BUILTINS" module dictionary", SPELL_ERROR_PYTHON_API );
+ }
+ PyDict_Merge(main_dict, moduleDict, 0);
+ DEBUG("[PYH] Imported all from module " + package);
+}
//============================================================================
// METROD : SPELLpythonHelper::importUserLibraries
//============================================================================
-void SPELLpythonHelper::importUserLibraries( const std::string& libraryPath )
+bool SPELLpythonHelper::importUserLibraries( const std::string& libraryPath, std::string& errors )
{
+ bool success = true;
+
if (libraryPath != "" && libraryPath != "None" )
{
if (SPELLutils::isDirectory(libraryPath))
{
// Import the main module first
- PyObject* mainModule = PyImport_AddModule("__main__");
+ PyObject* mainModule = PyImport_ImportModule(BUILTINS);
if (mainModule == NULL)
{
THROW_EXCEPTION("Cannot import user libraries", "Unable to access main module", SPELL_ERROR_PYTHON_API );
@@ -179,7 +225,7 @@ void SPELLpythonHelper::importUserLibraries( const std::string& libraryPath )
if (PyDict_Contains( main_dict, flag.get()) )
{
LOG_WARN("[PYH] No need to re-import user libraries");
- return;
+ return true;
}
LOG_INFO("Loading user libraries in " + libraryPath);
@@ -205,12 +251,12 @@ void SPELLpythonHelper::importUserLibraries( const std::string& libraryPath )
}
catch(SPELLcoreException& ex)
{
- LOG_ERROR("Failed to import user library " + filename + ": " + ex.what());
- PyErr_Clear();
+ success = false;
+ if (errors != "") errors += "\n - ";
+ errors += "When importing library " + filename + ": " + ex.what();
}
}
-
// Now ensure that all libraries contain all imported names as well
for( it = files.begin(); it != end; it++)
{
@@ -228,8 +274,9 @@ void SPELLpythonHelper::importUserLibraries( const std::string& libraryPath )
}
catch(SPELLcoreException& ex)
{
- LOG_ERROR("Failed to update user library " + filename + ": " + ex.what());
- PyErr_Clear();
+ success = false;
+ if (errors != "") errors += "\n - ";
+ errors += "When updating library " + filename + ": " + ex.what();
}
}
@@ -238,9 +285,12 @@ void SPELLpythonHelper::importUserLibraries( const std::string& libraryPath )
}
else
{
- THROW_EXCEPTION("Unable to load USER libraries", "Library path '" + libraryPath + "' is not a directory", SPELL_ERROR_FILESYSTEM);
+ success = false;
+ if (errors != "") errors += "\n - ";
+ errors += "Path '" + libraryPath + "' is not a directory";
}
}
+ return success;
}
//============================================================================
@@ -320,7 +370,7 @@ void SPELLpythonHelper::importUserLibrary( PyObject* main_dict, const std::strin
//============================================================================
PyObject* SPELLpythonHelper::getMainDict()
{
- PyObject* mainModule = PyImport_AddModule("__main__");
+ PyObject* mainModule = PyImport_AddModule(BUILTINS);
if (mainModule == NULL)
{
THROW_EXCEPTION("Cannot access main dictionary", "Unable to access main module", SPELL_ERROR_PYTHON_API );
@@ -335,7 +385,7 @@ PyObject* SPELLpythonHelper::getMainDict()
void SPELLpythonHelper::install( PyObject* object, const std::string& name )
{
DEBUG("[PYH] Installing object in globals: " + name);
- install(object,name,"__main__");
+ install(object,name,BUILTINS);
}
//============================================================================
@@ -343,7 +393,7 @@ void SPELLpythonHelper::install( PyObject* object, const std::string& name )
//============================================================================
void SPELLpythonHelper::install( PyObject* object, const std::string& name, const std::string& module )
{
- PyObject* moduleObj = PyImport_AddModule( module.c_str() );
+ PyObject* moduleObj = PyImport_ImportModule( module.c_str() );
if (moduleObj == NULL)
{
THROW_EXCEPTION("Cannot install " + name, "Unable to access module " + module, SPELL_ERROR_PYTHON_API );
@@ -365,9 +415,8 @@ void SPELLpythonHelper::install( PyObject* object, const std::string& name, cons
//=============================================================================
PyObject* SPELLpythonHelper::callMethod( PyObject* obj, const std::string& method, ... )
{
- DEBUG("[PYH] Call method " + method + " on " + PYREPR(obj));
-
SPELLsafePythonOperations ops("SPELLpythonHelper::callMethod " + method);
+ DEBUG("[PYH] Call method " + method + " on " + PYREPR(obj));
// Returns new reference
@@ -487,8 +536,10 @@ PyObject* SPELLpythonHelper::getModule( const std::string& module )
moduleObj = PyImport_ImportModule( module.c_str() );
if (moduleObj == NULL || moduleObj == Py_None )
{
+ checkError();
THROW_EXCEPTION("Unable to get module " + module, "Import failed", SPELL_ERROR_PYTHON_API );
}
+ Py_INCREF(moduleObj);
DEBUG("[PYH] Get module done");
return moduleObj;
}
@@ -498,7 +549,8 @@ PyObject* SPELLpythonHelper::getModule( const std::string& module )
//=============================================================================
void SPELLpythonHelper::initialize()
{
- m_initialized = false;
+ if (m_initialized)
+ return;
LOG_INFO("[PYH] Initializing Python");
// Initialize python, builtins, main module, etc.
@@ -531,11 +583,16 @@ void SPELLpythonHelper::initialize()
}
// Initialize the system arguments to empty list (no script is executed)
- char** argv = new char*[1];
- argv[0] = (char*) "";
- PySys_SetArgv(1,argv);
+
+ CHAR** argv = new CHAR*[1];
+ argv[0] = (CHAR*) L"";
+ PySys_SetArgv(-1,argv);
m_initialized = true;
+ Py_BEGIN_ALLOW_THREADS};
+// PyEval_ReleaseThread(PyThreadState_Get());
+// PyEval_ReleaseLock();
+
}
//=============================================================================
@@ -543,13 +600,13 @@ void SPELLpythonHelper::initialize()
//=============================================================================
void SPELLpythonHelper::loadFramework()
{
- importAllFrom("spell.lang.functions");
- importAllFrom("spell.lang.constants");
- importAllFrom("spell.lang.modifiers");
- importAllFrom("spell.lang.user");
- importAllFrom("spell.lib.adapter.utctime");
- importAllFrom("spell.lib.adapter.file");
- importAllFrom("math");
+ updateBuiltinsWith("spell.lang.functions");
+ updateBuiltinsWith("spell.lang.constants");
+ updateBuiltinsWith("spell.lang.modifiers");
+ updateBuiltinsWith("spell.lang.user");
+ updateBuiltinsWith("spell.lib.adapter.utctime");
+ updateBuiltinsWith("spell.lib.adapter.file");
+ updateBuiltinsWith("math");
}
//=============================================================================
@@ -569,7 +626,7 @@ void SPELLpythonHelper::finalize()
void SPELLpythonHelper::addToPath( const std::string& path )
{
LOG_INFO("[PYH] Append to python path: " + path);
-
+ SPELLsafePythonOperations ops("SPELLpythonHelper::addToPath");
// Retrieve first the current path
std::string libs = "";
PyObject* sys = PySys_GetObject( (char*) "path" );
@@ -582,8 +639,11 @@ void SPELLpythonHelper::addToPath( const std::string& path )
}
if (!libs.empty()) libs += ":";
libs += path;
-
+#if PY_MAJOR_VERSION >= 3
+ PySys_SetPath( const_cast(std::wstring(libs.begin(),libs.end()).c_str()) );
+#else
PySys_SetPath( const_cast(libs.c_str()) );
+#endif
}
//=============================================================================
@@ -663,36 +723,60 @@ SPELLtime SPELLpythonHelper::evalTime( PyObject* expression )
if (isTime(expression))
{
SPELLpyHandle isRel = callMethod(expression,"isRel",NULL);
+ long secs = 0;
+ unsigned int msecs = 0;
+ unsigned int usecs = 0;
+ SPELLpyHandle h = callMethod(expression,"millisecond",NULL);
+ msecs = PyLong_AsLong(h.get());
+ h = callMethod(expression,"microsecond",NULL);
+ usecs = PyLong_AsLong(h.get());
if (isRel.get() == Py_True)
{
SPELLpyHandle pySecs = callMethod(expression,"rel",NULL);
- long secs = PyLong_AsLong(pySecs.get());
+ if (PyFloat_Check(pySecs.get()))
+ {
+ double fsecs = PyFloat_AsDouble(pySecs.get());
+ // New reference
+ SPELLpyHandle pyDoub = PyLong_FromDouble(fsecs);
+ secs = PyLong_AsLong(pyDoub.get());
+ }
+ else
+ {
+ secs = PyLong_AsLong(pySecs.get());
+ }
DEBUG("[PYH] Evaluate time from python object done");
- return SPELLtime( secs, 0, true );
+ //DEBUG("@@@@ Initialized rel values:");
+ //DEBUG(" - secs: " + ISTR(secs) );
+ //DEBUG(" - msecs: " + ISTR(msecs) );
+ //DEBUG(" - usecs: " + ISTR(usecs) );
+ return SPELLtime( secs, msecs, usecs, true );
}
else
{
// New reference
SPELLpyHandle pySecs = callMethod(expression,"abs",NULL);
- int seconds = 0;
if (PyFloat_Check(pySecs.get()))
{
double fsecs = PyFloat_AsDouble(pySecs.get());
// New reference
SPELLpyHandle pyDoub = PyLong_FromDouble(fsecs);
- seconds = PyLong_AsLong(pyDoub.get());
+ secs = PyLong_AsLong(pyDoub.get());
}
else
{
- seconds = PyLong_AsLong(pySecs.get());
+ secs = PyLong_AsLong(pySecs.get());
}
DEBUG("[PYH] Evaluate time from python object done");
- return SPELLtime( seconds, 0, false );
+ //DEBUG("@@@@ Initialized abs values:");
+ //DEBUG(" - secs: " + ISTR(secs) );
+ //DEBUG(" - msecs: " + ISTR(msecs) );
+ //DEBUG(" - usecs: " + ISTR(usecs) );
+ return SPELLtime( secs, msecs, usecs, false );
}
}
else
{
- THROW_FATAL_EXCEPTION("Unable to evaluate time", "Not a TIME instance", SPELL_ERROR_PYTHON_API );
+ return evalTime(PYSSTR(expression));
}
// Just to avoid warnings...
return SPELLtime();
@@ -764,12 +848,26 @@ PyObject* SPELLpythonHelper::pythonTime( const SPELLtime& time )
//=============================================================================
PyThreadState* SPELLpythonHelper::beginSafeAllowThreads()
{
+ // Don't call PyEval_SaveThread if this thread doesn't hold the GIL! This would cause weird CPython crashes.
+ PyThreadState *hasGIL = PyGILState_GetThisThreadState();
+ if (hasGIL == NULL)
+ return NULL;
+#if PY_MAJOR_VERSION >= 3
+ // Need to check whether we hold the python lock in py3 as well.
+ if (!PyGILState_Check())
+ return NULL;
+#endif
PyThreadState *tstate = PyThreadState_GET();
+
if (tstate != NULL)
{
-// std::cerr << "BEGIN ALLOW THREADS ##########################################################" << std::endl;
- tstate = PyEval_SaveThread();
-// std::cerr << "FRAME: " << PSTR(tstate->frame) << std::endl;
+ //std::cerr << "BEGIN ALLOW THREADS ##########################################################" << std::endl;
+ // Make sure this thread is holding the GIL when trying to call PyEval_SaveThread which requires the GIL
+ if (hasGIL == tstate)
+ tstate = PyEval_SaveThread();
+ else
+ return NULL;
+ //std::cerr << "FRAME: " << PSTR(tstate->frame) << std::endl;
}
return tstate;
}
@@ -781,8 +879,8 @@ void SPELLpythonHelper::endSafeAllowThreads( PyThreadState* tstate )
{
if (tstate != NULL)
{
-// std::cerr << "END ALLOW THREADS ############################################################" << std::endl;
-// std::cerr << "FRAME: " << PSTR(tstate->frame) << std::endl;
+ //std::cerr << "END ALLOW THREADS ############################################################" << std::endl;
+ //std::cerr << "FRAME: " << PSTR(tstate->frame) << std::endl;
PyEval_RestoreThread(tstate);
}
}
@@ -792,10 +890,10 @@ void SPELLpythonHelper::endSafeAllowThreads( PyThreadState* tstate )
//=============================================================================
PyGILState_STATE SPELLpythonHelper::acquireGIL()
{
-// std::cerr << "ACQUIRE GIL ##################################################################" << std::endl;
+ //std::cerr << "ACQUIRE GIL ##################################################################" << std::endl;
PyGILState_STATE state = PyGILState_Ensure();
-// std::cerr << "FRAME: " << PSTR(PyEval_GetFrame()) << std::endl;
-// std::cerr << "STATE: " << state << std::endl;
+ //std::cerr << "FRAME: " << PSTR(PyEval_GetFrame()) << std::endl;
+ //std::cerr << "STATE: " << state << std::endl;
return state;
}
@@ -804,9 +902,9 @@ PyGILState_STATE SPELLpythonHelper::acquireGIL()
//=============================================================================
void SPELLpythonHelper::releaseGIL( PyGILState_STATE state )
{
-// std::cerr << "RELEASE GIL ##################################################################" << std::endl;
-// std::cerr << "FRAME: " << PSTR(PyEval_GetFrame()) << std::endl;
-// std::cerr << "STATE: " << state << std::endl;
+ //std::cerr << "RELEASE GIL ##################################################################" << std::endl;
+ //std::cerr << "FRAME: " << PSTR(PyEval_GetFrame()) << std::endl;
+ //std::cerr << "STATE: " << state << std::endl;
PyGILState_Release(state);
}
@@ -858,7 +956,7 @@ std::string SPELLpythonHelper::readProcedureFile( const std::string& filename )
//=============================================================================
PyCodeObject* SPELLpythonHelper::compile( const std::string& filePath )
{
- DEBUG("[PYH] Compiling procedure " + filePath)
+ DEBUG("[PYH] Compiling procedure " + filePath);
// Will hold the AST preprocessed bytecode
mod_ty ast;
@@ -1001,13 +1099,424 @@ PyCodeObject* SPELLpythonHelper::compileScript( const std::string& source )
return code;
}
+
+#if PY_MAJOR_VERSION >= 3
+
+#define OFF(x) offsetof(PyFrameObject, x)
+
+/* Setter for f_lineno - you can set f_lineno from within a trace function in
+ * order to jump to a given line of code, subject to some restrictions. Most
+ * lines are OK to jump to because they don't make any assumptions about the
+ * state of the stack (obvious because you could remove the line and the code
+ * would still work without any stack errors), but there are some constructs
+ * that limit jumping:
+ *
+ * o Lines with an 'except' statement on them can't be jumped to, because
+ * they expect an exception to be on the top of the stack.
+ * o Lines that live in a 'finally' block can't be jumped from or to, since
+ * the END_FINALLY expects to clean up the stack after the 'try' block.
+ * o 'try'/'for'/'while' blocks can't be jumped into because the blockstack
+ * needs to be set up before their code runs, and for 'for' loops the
+ * iterator needs to be on the stack.
+ * o Jumps cannot be made from within a trace function invoked with a
+ * 'return' or 'exception' event since the eval loop has been exited at
+ * that time.
+ */
+static int
+frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignored))
+{
+ int new_lineno = 0; /* The new value of f_lineno */
+ long l_new_lineno;
+ int overflow;
+ int new_lasti = 0; /* The new value of f_lasti */
+ int new_iblock = 0; /* The new value of f_iblock */
+ unsigned char *code = NULL; /* The bytecode for the frame... */
+ Py_ssize_t code_len = 0; /* ...and its length */
+ unsigned char *lnotab = NULL; /* Iterating over co_lnotab */
+ Py_ssize_t lnotab_len = 0; /* (ditto) */
+ int offset = 0; /* (ditto) */
+ int line = 0; /* (ditto) */
+ int addr = 0; /* (ditto) */
+ int min_addr = 0; /* Scanning the SETUPs and POPs */
+ int max_addr = 0; /* (ditto) */
+ int delta_iblock = 0; /* (ditto) */
+ int min_delta_iblock = 0; /* (ditto) */
+ int min_iblock = 0; /* (ditto) */
+ int f_lasti_setup_addr = 0; /* Policing no-jump-into-finally */
+ int new_lasti_setup_addr = 0; /* (ditto) */
+ int blockstack[CO_MAXBLOCKS]; /* Walking the 'finally' blocks */
+ int in_finally[CO_MAXBLOCKS]; /* (ditto) */
+ int blockstack_top = 0; /* (ditto) */
+ unsigned char setup_op = 0; /* (ditto) */
+
+ if (p_new_lineno == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
+ return -1;
+ }
+ /* f_lineno must be an integer. */
+ if (!PyLong_CheckExact(p_new_lineno)) {
+ PyErr_SetString(PyExc_ValueError,
+ "lineno must be an integer");
+ return -1;
+ }
+
+ /* Upon the 'call' trace event of a new frame, f->f_lasti is -1 and
+ * f->f_trace is NULL, check first on the first condition.
+ * Forbidding jumps from the 'call' event of a new frame is a side effect
+ * of allowing to set f_lineno only from trace functions. */
+ if (f->f_lasti == -1) {
+ PyErr_Format(PyExc_ValueError,
+ "can't jump from the 'call' trace event of a new frame");
+ return -1;
+ }
+
+ /* You can only do this from within a trace function, not via
+ * _getframe or similar hackery. */
+// if (!f->f_trace) {
+// PyErr_Format(PyExc_ValueError,
+// "f_lineno can only be set by a trace function");
+// return -1;
+// }
+
+ /* Forbid jumps upon a 'return' trace event (except after executing a
+ * YIELD_VALUE or YIELD_FROM opcode, f_stacktop is not NULL in that case)
+ * and upon an 'exception' trace event.
+ * Jumps from 'call' trace events have already been forbidden above for new
+ * frames, so this check does not change anything for 'call' events. */
+ if (f->f_stacktop == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "can only jump from a 'line' trace event");
+ return -1;
+ }
+
+ /* Fail if the line comes before the start of the code block. */
+ l_new_lineno = PyLong_AsLongAndOverflow(p_new_lineno, &overflow);
+ if (overflow
+#if SIZEOF_LONG > SIZEOF_INT
+ || l_new_lineno > INT_MAX
+ || l_new_lineno < INT_MIN
+#endif
+ ) {
+ PyErr_SetString(PyExc_ValueError,
+ "lineno out of range");
+ return -1;
+ }
+ new_lineno = (int)l_new_lineno;
+
+ if (new_lineno < f->f_code->co_firstlineno) {
+ PyErr_Format(PyExc_ValueError,
+ "line %d comes before the current code block",
+ new_lineno);
+ return -1;
+ }
+ else if (new_lineno == f->f_code->co_firstlineno) {
+ new_lasti = 0;
+ new_lineno = f->f_code->co_firstlineno;
+ }
+ else {
+ /* Find the bytecode offset for the start of the given
+ * line, or the first code-owning line after it. */
+ char *tmp;
+ PyBytes_AsStringAndSize(f->f_code->co_lnotab,
+ &tmp, &lnotab_len);
+ lnotab = (unsigned char *) tmp;
+ addr = 0;
+ line = f->f_code->co_firstlineno;
+ new_lasti = -1;
+ for (offset = 0; offset < lnotab_len; offset += 2) {
+ addr += lnotab[offset];
+ line += (signed char)lnotab[offset+1];
+ if (line >= new_lineno) {
+ new_lasti = addr;
+ new_lineno = line;
+ break;
+ }
+ }
+ }
+
+ /* If we didn't reach the requested line, return an error. */
+ if (new_lasti == -1) {
+ PyErr_Format(PyExc_ValueError,
+ "line %d comes after the current code block",
+ new_lineno);
+ return -1;
+ }
+
+ /* We're now ready to look at the bytecode. */
+ PyBytes_AsStringAndSize(f->f_code->co_code, (char **)&code, &code_len);
+
+ /* The trace function is called with a 'return' trace event after the
+ * execution of a yield statement. */
+ assert(f->f_lasti != -1);
+ if (code[f->f_lasti] == YIELD_VALUE || code[f->f_lasti] == YIELD_FROM) {
+ PyErr_SetString(PyExc_ValueError,
+ "can't jump from a yield statement");
+ return -1;
+ }
+
+ min_addr = Py_MIN(new_lasti, f->f_lasti);
+ max_addr = Py_MAX(new_lasti, f->f_lasti);
+
+ /* You can't jump onto a line with an 'except' statement on it -
+ * they expect to have an exception on the top of the stack, which
+ * won't be true if you jump to them. They always start with code
+ * that either pops the exception using POP_TOP (plain 'except:'
+ * lines do this) or duplicates the exception on the stack using
+ * DUP_TOP (if there's an exception type specified). See compile.c,
+ * 'com_try_except' for the full details. There aren't any other
+ * cases (AFAIK) where a line's code can start with DUP_TOP or
+ * POP_TOP, but if any ever appear, they'll be subject to the same
+ * restriction (but with a different error message). */
+ if (code[new_lasti] == DUP_TOP || code[new_lasti] == POP_TOP) {
+ PyErr_SetString(PyExc_ValueError,
+ "can't jump to 'except' line as there's no exception");
+ return -1;
+ }
+
+ /* You can't jump into or out of a 'finally' block because the 'try'
+ * block leaves something on the stack for the END_FINALLY to clean
+ * up. So we walk the bytecode, maintaining a simulated blockstack.
+ * When we reach the old or new address and it's in a 'finally' block
+ * we note the address of the corresponding SETUP_FINALLY. The jump
+ * is only legal if neither address is in a 'finally' block or
+ * they're both in the same one. 'blockstack' is a stack of the
+ * bytecode addresses of the SETUP_X opcodes, and 'in_finally' tracks
+ * whether we're in a 'finally' block at each blockstack level. */
+ f_lasti_setup_addr = -1;
+ new_lasti_setup_addr = -1;
+ memset(blockstack, '\0', sizeof(blockstack));
+ memset(in_finally, '\0', sizeof(in_finally));
+ blockstack_top = 0;
+ for (addr = 0; addr < code_len; addr += sizeof(_Py_CODEUNIT)) {
+ unsigned char op = code[addr];
+ switch (op) {
+ case SETUP_LOOP:
+ case SETUP_EXCEPT:
+ case SETUP_FINALLY:
+ case SETUP_WITH:
+ case SETUP_ASYNC_WITH:
+ blockstack[blockstack_top++] = addr;
+ in_finally[blockstack_top-1] = 0;
+ break;
+
+ case POP_BLOCK:
+ assert(blockstack_top > 0);
+ setup_op = code[blockstack[blockstack_top-1]];
+ if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH
+ || setup_op == SETUP_ASYNC_WITH) {
+ in_finally[blockstack_top-1] = 1;
+ }
+ else {
+ blockstack_top--;
+ }
+ break;
+
+ case END_FINALLY:
+ /* Ignore END_FINALLYs for SETUP_EXCEPTs - they exist
+ * in the bytecode but don't correspond to an actual
+ * 'finally' block. (If blockstack_top is 0, we must
+ * be seeing such an END_FINALLY.) */
+ if (blockstack_top > 0) {
+ setup_op = code[blockstack[blockstack_top-1]];
+ if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH
+ || setup_op == SETUP_ASYNC_WITH) {
+ blockstack_top--;
+ }
+ }
+ break;
+ }
+
+ /* For the addresses we're interested in, see whether they're
+ * within a 'finally' block and if so, remember the address
+ * of the SETUP_FINALLY. */
+ if (addr == new_lasti || addr == f->f_lasti) {
+ int i = 0;
+ int setup_addr = -1;
+ for (i = blockstack_top-1; i >= 0; i--) {
+ if (in_finally[i]) {
+ setup_addr = blockstack[i];
+ break;
+ }
+ }
+
+ if (setup_addr != -1) {
+ if (addr == new_lasti) {
+ new_lasti_setup_addr = setup_addr;
+ }
+
+ if (addr == f->f_lasti) {
+ f_lasti_setup_addr = setup_addr;
+ }
+ }
+ }
+ }
+
+ /* Verify that the blockstack tracking code didn't get lost. */
+ //assert(blockstack_top == 0);
+ if (blockstack_top != 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "can't jump blockstack_top pointer got lost");
+ return -1;
+ }
+
+ /* After all that, are we jumping into / out of a 'finally' block? */
+ if (new_lasti_setup_addr != f_lasti_setup_addr) {
+ PyErr_SetString(PyExc_ValueError,
+ "can't jump into or out of a 'finally' block");
+ return -1;
+ }
+
+
+ /* Police block-jumping (you can't jump into the middle of a block)
+ * and ensure that the blockstack finishes up in a sensible state (by
+ * popping any blocks we're jumping out of). We look at all the
+ * blockstack operations between the current position and the new
+ * one, and keep track of how many blocks we drop out of on the way.
+ * By also keeping track of the lowest blockstack position we see, we
+ * can tell whether the jump goes into any blocks without coming out
+ * again - in that case we raise an exception below. */
+ delta_iblock = 0;
+ for (addr = min_addr; addr < max_addr; addr += sizeof(_Py_CODEUNIT)) {
+ unsigned char op = code[addr];
+ switch (op) {
+ case SETUP_LOOP:
+ case SETUP_EXCEPT:
+ case SETUP_FINALLY:
+ case SETUP_WITH:
+ case SETUP_ASYNC_WITH:
+ delta_iblock++;
+ break;
+
+ case POP_BLOCK:
+ delta_iblock--;
+ break;
+ }
+
+ min_delta_iblock = Py_MIN(min_delta_iblock, delta_iblock);
+ }
+
+ /* Derive the absolute iblock values from the deltas. */
+ min_iblock = f->f_iblock + min_delta_iblock;
+ if (new_lasti > f->f_lasti) {
+ /* Forwards jump. */
+ new_iblock = f->f_iblock + delta_iblock;
+ }
+ else {
+ /* Backwards jump. */
+ new_iblock = f->f_iblock - delta_iblock;
+ }
+
+ /* Are we jumping into a block? */
+ if (new_iblock > min_iblock) {
+ PyErr_SetString(PyExc_ValueError,
+ "can't jump into the middle of a block");
+ return -1;
+ }
+
+ /* Pop any blocks that we're jumping out of. */
+ while (f->f_iblock > new_iblock) {
+ PyTryBlock *b = &f->f_blockstack[--f->f_iblock];
+ while ((f->f_stacktop - f->f_valuestack) > b->b_level) {
+ PyObject *v = (*--f->f_stacktop);
+ Py_DECREF(v);
+ }
+ if (b->b_type == SETUP_FINALLY &&
+ code[b->b_handler] == WITH_CLEANUP_START)
+ {
+ /* Pop the exit function. */
+ PyObject *v = (*--f->f_stacktop);
+ Py_DECREF(v);
+ }
+ }
+
+ /* Finally set the new f_lineno and f_lasti and return OK. */
+ f->f_lineno = new_lineno;
+ f->f_lasti = new_lasti;
+ return 0;
+}
+
+
+#endif
+
//=============================================================================
// METHOD : SPELLpythonHelper::setNewLine();
//=============================================================================
bool SPELLpythonHelper::setNewLine( PyFrameObject* frame, const int& new_lineno, const int& new_lasti )
{
LOG_WARN("[PYH] Changing line number on frame " + PYCREPR(frame));
+ LOG_WARN("[PYH] new_lineno = " + ISTR(new_lineno) + " new_lasti = " + ISTR(new_lasti));
+
+#if PY_MAJOR_VERSION >= 3
+ PyObject* line = PyLong_FromLong(new_lineno);
+ int success = -1;
+ // In case frame->f_stacktop is NULL and frame->f_back is not NULL,
+ // (case when just returned from a function call)
+ // set current frame to the previous frame
+ // Otherwise, keep using current frame
+ // (case of a return into the root frame for example)
+ if (frame->f_stacktop == NULL && frame->f_back != NULL)
+ frame = frame->f_back;
+ success = frame_setlineno(frame, line, NULL);
+ PyObject* err = PyErr_Occurred();
+ if (err != NULL)
+ {
+ std::cerr << std::endl << "===============================" << std::endl;
+ //PyErr_Print();
+ PyObject* ptype;
+ PyObject* pvalue;
+ PyObject* ptraceback;
+ PyErr_Fetch( &ptype, &pvalue, &ptraceback );
+ std::cerr << "TYPE : " << PYREPR(ptype) << std::endl;
+ std::cerr << "VALUE: " << PYREPR(pvalue) << std::endl;
+ if (ptraceback)
+ {
+ std::cerr << "Traceback: " << std::endl;
+ PyTracebackObject* traceback = (PyTracebackObject*) ptraceback;
+ while(traceback != NULL)
+ {
+ std::cerr << "at " << PYREPR(traceback->tb_frame->f_code->co_filename) << ":" << traceback->tb_lineno << std::endl;
+ traceback = traceback->tb_next;
+ }
+ }
+
+ std::cerr << "===============================" << std::endl << std::endl;
+ // Parse the exception to give better information about the error on python side
+ PyObject* spellException = SPELLpythonHelper::instance().getObject("spell.lib.exception", "SpellException");
+ std::string excType = PYREPR(ptype);
+ if (PyObject_IsInstance( pvalue, spellException ))
+ {
+ PyObject* msg = PyObject_GetAttrString( pvalue, "message" );
+ PyObject* rea = PyObject_GetAttrString( pvalue, "reason" );
+ std::string message = "";
+ std::string reason = "";
+ if (msg != NULL)
+ {
+ message = PYSSTR(msg);
+ }
+ if (rea != NULL )
+ {
+ reason = PYSSTR(rea);
+ }
+ /** \todo decide the fatal flag value */
+ std::cerr << "RAISING INTERNAL DRIVER EXCEPTION" << std::endl;
+ PyErr_Clear();
+ THROW_EXCEPTION("Cannot set new line", reason, SPELL_DRIVER_ERROR );
+ }
+ else if ( PYREPR(pvalue) == "EXECUTION ABORTED" || PYREPR(pvalue) == "EXECUTION TERMINATED" )
+ {
+ // Do not raise exceptions if the detected exception is an aborted or finished internal exception
+ PyErr_Clear();
+ return false;
+ }
+ else
+ {
+ std::cerr << "RAISING PYTHON ERROR EXCEPTION" << std::endl;
+ PyErr_Clear();
+ THROW_EXCEPTION("Cannot set new line", PYSSTR(pvalue), SPELL_ERROR_PYTHON_API );
+ }
+ }
+#else
/////////////////////////////////////////////////////////
// THIS IS NASTY: copied from Python 2.5 implementation
/////////////////////////////////////////////////////////
@@ -1051,10 +1560,10 @@ bool SPELLpythonHelper::setNewLine( PyFrameObject* frame, const int& new_lineno,
* cases (AFAIK) where a line's code can start with DUP_TOP or
* POP_TOP, but if any ever appear, they'll be subject to the same
* restriction (but with a different error message). */
- if (code[new_lasti] == DUP_TOP || code[new_lasti] == POP_TOP)
- {
- THROW_EXCEPTION("Cannot set new line", "Cannot go inside a try/except block", SPELL_ERROR_PYTHON_API);
- }
+ //if (code[new_lasti] == DUP_TOP || code[new_lasti] == POP_TOP)
+ //{
+ // THROW_EXCEPTION("Cannot set new line", "Cannot go inside a try/except block", SPELL_ERROR_PYTHON_API);
+ //}
/* You can't jump into or out of a 'finally' block because the 'try'
* block leaves something on the stack for the END_FINALLY to clean
@@ -1215,6 +1724,7 @@ bool SPELLpythonHelper::setNewLine( PyFrameObject* frame, const int& new_lineno,
/* Finally set the new f_lineno and f_lasti and return OK. */
frame->f_lineno = new_lineno;
frame->f_lasti = new_lasti;
+#endif
LOG_WARN("[PYH] Set frame lineno " + ISTR(new_lineno) + ":" + ISTR(new_lasti));
return true;
}
@@ -1230,6 +1740,7 @@ PyFrameObject* SPELLpythonHelper::createFrame( const std::string& filename, PyCo
PyObject* mainModule = PyImport_AddModule("__main__");
+
if (mainModule == NULL)
{
THROW_EXCEPTION("Unable to create frame", "Cannot access main module", SPELL_ERROR_PYTHON_API );
@@ -1256,11 +1767,32 @@ PyFrameObject* SPELLpythonHelper::createFrame( const std::string& filename, PyCo
return NULL;
}
}
+
DEBUG("[PYH] Frame creation");
- frame = PyFrame_New( PyThreadState_Get(), code, mainDict, mainDict );
+
+ frame = PyFrame_New( PyThreadState_Get(), code,mainDict , NULL );
Py_INCREF(frame);
return frame;
}
+//=============================================================================
+// METHOD : SPELLpythonHelper::createFrame();
+//=============================================================================
+PyFrameObject* SPELLpythonHelper::createFrameFromFunction( const std::string& filename, PyObject* func )
+{
+ DEBUG("[PYH] Creating frame for code " + PYCREPR(func));
+
+ PyFrameObject* frame = NULL;
+
+ PyCodeObject* code = (PyCodeObject*)PyFunction_GetCode(func);
+ PyObject* globals = PyFunction_GetGlobals(func);
+ Py_INCREF(globals);
+ Py_INCREF(code);
+ frame = PyFrame_New( PyThreadState_Get(), code,globals , NULL);
+
+ Py_INCREF(frame);
+ checkError();
+ return frame;
+}
//=============================================================================
// METHOD : SPELLpythonHelper::checkError
@@ -1290,6 +1822,7 @@ void SPELLpythonHelper::checkError()
traceback = traceback->tb_next;
}
}
+
std::cerr << "===============================" << std::endl << std::endl;
// Parse the exception to give better information about the error on python side
PyObject* spellException = SPELLpythonHelper::instance().getObject("spell.lib.exception", "SpellException");
diff --git a/lib/SPELL_UTIL/src/SPELLtime.C b/lib/SPELL_UTIL/src/SPELLtime.C
index 71015be..3c9a666 100644
--- a/lib/SPELL_UTIL/src/SPELLtime.C
+++ b/lib/SPELL_UTIL/src/SPELLtime.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the time object
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -47,7 +47,7 @@ SPELLtime::SPELLtime()
//=============================================================================
SPELLtime::SPELLtime( unsigned long secs, bool delta )
{
- set(secs,0,delta);
+ set(secs,0,0,delta);
}
//=============================================================================
@@ -55,7 +55,15 @@ SPELLtime::SPELLtime( unsigned long secs, bool delta )
//=============================================================================
SPELLtime::SPELLtime( unsigned long secs, unsigned int msecs, bool delta )
{
- set(secs,msecs,delta);
+ set(secs,msecs,0,delta);
+}
+
+//=============================================================================
+// CONSTRUCTOR: SPELLtime::SPELLtime
+//=============================================================================
+SPELLtime::SPELLtime( unsigned long secs, unsigned int msecs, unsigned int usecs, bool delta )
+{
+ set(secs,msecs,usecs,delta);
}
//=============================================================================
@@ -63,7 +71,7 @@ SPELLtime::SPELLtime( unsigned long secs, unsigned int msecs, bool delta )
//=============================================================================
SPELLtime::SPELLtime( const SPELLtime& other )
{
- set(other.m_secs,other.m_msecs,other.m_delta);
+ set(other.m_secs,other.m_msecs,other.m_usecs,other.m_delta);
}
//=============================================================================
@@ -83,6 +91,7 @@ SPELLtime& SPELLtime::operator=( const SPELLtime& other )
{
m_secs = other.m_secs;
m_msecs = other.m_msecs;
+ m_usecs = other.m_usecs;
m_delta = other.m_delta;
}
// by convention, always return this
@@ -95,7 +104,12 @@ SPELLtime& SPELLtime::operator=( const SPELLtime& other )
SPELLtime SPELLtime::operator+(const SPELLtime& other)
{
SPELLtime result(0,true);
- result.set( m_secs + other.m_secs, m_msecs + other.m_msecs, m_delta && other.m_delta );
+ // Check for overflow
+ unsigned long secs = m_secs + other.m_secs;
+ unsigned int usecs = m_usecs + other.m_usecs;
+ secs += usecs / (1000*1000);
+ usecs %= (1000*1000);
+ result.set( secs, usecs/1000, usecs, m_delta && other.m_delta );
return result;
}
@@ -104,7 +118,12 @@ SPELLtime SPELLtime::operator+(const SPELLtime& other)
//=============================================================================
SPELLtime& SPELLtime::operator+=(SPELLtime& other)
{
- set( m_secs + other.m_secs, m_msecs + other.m_msecs, m_delta && other.m_delta );
+ // Check for overflow
+ unsigned long secs = m_secs + other.m_secs;
+ unsigned int usecs = m_usecs + other.m_usecs;
+ secs += usecs / (1000*1000);
+ usecs %= (1000*1000);
+ set( secs, usecs/1000, usecs, m_delta && other.m_delta );
return *this;
}
@@ -117,7 +136,8 @@ SPELLtime SPELLtime::operator-(const SPELLtime& other)
bool delta = (m_delta && other.m_delta) || (!m_delta && !other.m_delta);
long secs = m_secs - other.m_secs;
int msecs = m_msecs - other.m_msecs;
- result.set( (secs>0)? secs: 0, (msecs>0)? msecs: 0, delta );
+ int usecs = m_usecs - other.m_usecs;
+ result.set( (secs>0)? secs: 0, (msecs>0)? msecs: 0, (usecs>0)? usecs: 0, delta );
return result;
}
@@ -129,7 +149,8 @@ SPELLtime& SPELLtime::operator-=(SPELLtime& other)
bool delta = (m_delta && other.m_delta) || (!m_delta && !other.m_delta);
long secs = m_secs - other.m_secs;
int msecs = m_msecs - other.m_msecs;
- set( (secs>0)? secs: 0, (msecs>0)? msecs: 0, delta );
+ int usecs = m_usecs - other.m_usecs;
+ set( (secs>0)? secs: 0, (msecs>0)? msecs: 0, (usecs>0)? usecs: 0, delta );
return *this;
}
@@ -142,6 +163,10 @@ bool SPELLtime::operator<( const SPELLtime& other ) const
if (m_secs == other.m_secs)
{
if (m_msecs < other.m_msecs) return true;
+ if (m_msecs == other.m_msecs)
+ {
+ if (m_usecs < other.m_usecs) return true;
+ }
}
return false;
}
@@ -155,6 +180,10 @@ bool SPELLtime::operator>( const SPELLtime& other ) const
if (m_secs == other.m_secs)
{
if (m_msecs > other.m_msecs) return true;
+ if (m_msecs == other.m_msecs)
+ {
+ if (m_usecs > other.m_usecs) return true;
+ }
}
return false;
}
@@ -178,25 +207,25 @@ bool SPELLtime::operator<( const unsigned long& secs ) const
}
//=============================================================================
-// METHOD: SPELLtime::operator<
+// METHOD: SPELLtime::operator==
//=============================================================================
bool SPELLtime::operator==( const SPELLtime& other ) const
{
- if (m_secs == other.m_secs)
+ if (m_secs == other.m_secs && m_msecs == other.m_msecs && m_usecs == other.m_usecs)
{
- if (m_msecs == other.m_msecs) return true;
+ return true;
}
return false;
}
//=============================================================================
-// METHOD: SPELLtime::operator<
+// METHOD: SPELLtime::operator==
//=============================================================================
bool SPELLtime::operator==( const unsigned long& secs ) const
{
if (m_secs == secs)
{
- if (m_msecs == 0) return true;
+ if (m_msecs == 0 && m_usecs == 0) return true;
}
return false;
}
@@ -206,10 +235,14 @@ bool SPELLtime::operator==( const unsigned long& secs ) const
//=============================================================================
bool SPELLtime::operator>=( const SPELLtime& other ) const
{
- if (m_secs >= other.m_secs) return true;
+ if (m_secs > other.m_secs ) return true;
if (m_secs == other.m_secs)
{
- if (m_msecs >= other.m_msecs) return true;
+ if (m_msecs > other.m_msecs) return true;
+ if (m_msecs == other.m_msecs)
+ {
+ if (m_usecs >= other.m_usecs) return true;
+ }
}
return false;
}
@@ -219,10 +252,14 @@ bool SPELLtime::operator>=( const SPELLtime& other ) const
//=============================================================================
bool SPELLtime::operator<=( const SPELLtime& other ) const
{
- if (m_secs <= other.m_secs) return true;
+ if (m_secs < other.m_secs) return true;
if (m_secs == other.m_secs)
{
- if (m_msecs <= other.m_msecs) return true;
+ if (m_msecs < other.m_msecs) return true;
+ if (m_msecs == other.m_msecs)
+ {
+ if (m_usecs <= other.m_usecs) return true;
+ }
}
return false;
}
@@ -232,7 +269,7 @@ bool SPELLtime::operator<=( const SPELLtime& other ) const
//=============================================================================
std::string SPELLtime::toString() const
{
- if (m_secs==0)
+ if (m_secs==0 && m_msecs==0 && m_usecs==0)
{
return "0";
}
@@ -245,6 +282,7 @@ std::string SPELLtime::toString() const
if (seconds<60) // Very short date format
{
timeStr = ISTR(seconds);
+ timeStr += getMicrosecondsSuffix();
}
else
{
@@ -267,6 +305,8 @@ std::string SPELLtime::toString() const
//Seconds
if ( seconds < 10 ) timeStr += "0";
timeStr += ISTR(seconds);
+ //Milliseconds+Microseconds
+ timeStr += getMicrosecondsSuffix();
}
}
//Absolute date e.g. 2009-12-07 16:55:12
@@ -274,7 +314,7 @@ std::string SPELLtime::toString() const
{
time_t seconds = m_secs;
struct tm* ptm = localtime(&seconds);
- if (ptm==NULL)
+ if (ptm==NULL && m_msecs==0 && m_usecs==0)
{
return "\?\?\?\?-\?\?-\?\? \?\?:\?\?:\?\?";
}
@@ -294,16 +334,19 @@ std::string SPELLtime::toString() const
//Seconds
if ( ptm->tm_sec < 10 ) timeStr += "0";
timeStr += ISTR(ptm->tm_sec);
+ //Milliseconds+Microseconds
+ timeStr += getMicrosecondsSuffix();
}
return timeStr;
}
+
//=============================================================================
// METHOD: SPELLtime::toString
//=============================================================================
std::string SPELLtime::toTIMEString() const
{
- if (m_secs==0)
+ if (m_secs==0 && m_msecs==0 && m_usecs==0)
{
return "+000 00:00:00";
}
@@ -336,13 +379,15 @@ std::string SPELLtime::toTIMEString() const
//Seconds
if ( seconds < 10 ) timeStr += "0";
timeStr += ISTR(seconds);
+ //Milliseconds+Microseconds
+ timeStr += getMicrosecondsSuffix();
}
//Absolute date e.g. e.g. 2009-12-07:16:55:12
else
{
time_t seconds = m_secs;
struct tm* ptm = localtime(&seconds);
- if (ptm==NULL)
+ if (ptm==NULL && m_msecs==0 && m_usecs==0)
{
return "\?\?\?\?-\?\?-\?\? \?\?:\?\?:\?\?";
}
@@ -353,7 +398,7 @@ std::string SPELLtime::toTIMEString() const
if (month.length()==1) month = "0" + month;
std::string day = ISTR(ptm->tm_mday);
if (day.length()==1) day = "0" + day;
- timeStr += month + "-" + day + ":";
+ timeStr += month + "-" + day + " ";
//Hours
if ( ptm->tm_hour < 10 ) timeStr += "0";
@@ -364,6 +409,8 @@ std::string SPELLtime::toTIMEString() const
//Seconds
if ( ptm->tm_sec < 10 ) timeStr += "0";
timeStr += ISTR(ptm->tm_sec);
+ //Milliseconds+Microseconds
+ timeStr += getMicrosecondsSuffix();
}
return timeStr;
}
@@ -374,7 +421,7 @@ std::string SPELLtime::toTIMEString() const
void SPELLtime::setCurrent()
{
SPELLutils::SPELLtimeDesc time = SPELLutils::getSystemTime();
- set( time.seconds, time.useconds/1000, false );
+ set( time.seconds, time.useconds/1000, time.useconds%1000, false );
}
//=============================================================================
@@ -382,20 +429,46 @@ void SPELLtime::setCurrent()
//=============================================================================
void SPELLtime::set( unsigned long secs, unsigned int msecs )
{
- set(secs,msecs,true);
+ set(secs,msecs,0,true);
}
//=============================================================================
// METHOD: SPELLtime::set
//=============================================================================
-void SPELLtime::set( unsigned long secs, unsigned int msecs, bool delta )
+void SPELLtime::set( unsigned long secs, unsigned int msecs, unsigned int usecs )
+{
+ set(secs,msecs,usecs,true);
+}
+
+//=============================================================================
+// METHOD: SPELLtime::set
+//=============================================================================
+void SPELLtime::set( unsigned long secs, unsigned int msecs, unsigned int usecs, bool delta )
{
m_secs = secs;
m_msecs = msecs;
+ m_usecs = usecs;
m_delta = delta;
- //DEBUG("[TIME] Set time: " + ISTR(m_secs) + ", " + ISTR(m_msecs) + ", " + BSTR(m_delta))
+ //DEBUG("[TIME] Set time: " + ISTR(m_secs) + ", " + ISTR(m_msecs) + ", " + ISTR(m_usecs) + ", " + BSTR(m_delta))
}
+//=============================================================================
+// METHOD: SPELLtime::getMicrosecondsSuffix
+//=============================================================================
+std::string SPELLtime::getMicrosecondsSuffix() const {
+ std::stringstream ss;
+ if ( m_msecs == 0 && m_usecs == 0 )
+ {
+ return "";
+ }
+ ss << ".";
+ ss << std::setfill('0') << std::setw(3) << m_msecs;
+ if ( m_usecs%1000 != 0) {
+ ss << std::setfill('0') << std::setw(3) << m_usecs%1000;
+ }
+ return ss.str();
+};
+
//=============================================================================
// STATIC: SPELLticker::tickIn
//=============================================================================
diff --git a/lib/SPELL_UTIL/src/SPELLutils.C b/lib/SPELL_UTIL/src/SPELLutils.C
index 47a0352..36770b5 100644
--- a/lib/SPELL_UTIL/src/SPELLutils.C
+++ b/lib/SPELL_UTIL/src/SPELLutils.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the utilities
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -29,6 +29,7 @@
#include "SPELL_UTIL/SPELLbase.H"
#include "SPELL_UTIL/SPELLerror.H"
#include "SPELL_UTIL/SPELLpythonMonitors.H"
+#include "SPELL_IPC/SPELLipcError.H"
// Project includes --------------------------------------------------------
#include "SPELL_WRP/SPELLpyHandle.H"
// System includes ---------------------------------------------------------
@@ -36,8 +37,6 @@
static int s_timeFormat = TIME_FORMAT_DEFAULT;
-
-
//============================================================================
// FUNCTION : PYSIZE
//============================================================================
@@ -146,7 +145,7 @@ std::string SPELLutils::pyObjectRepr( PyObject* obj )
SPELLpyHandle str = PyObject_Repr(obj);
if (str.get() != NULL)
{
- result = PyString_AsString(str.get());
+ result = std::string(PyString_AsString(str.get()));
}
return result;
}
@@ -186,7 +185,6 @@ std::map > SPELLutils::tokenizeData( const std::s
std::vector value;
unsigned int keyLength;
unsigned int valueLength;
- unsigned int byte;
unsigned int pos;
for( pos = 0 ; pos < data.size() ; )
@@ -201,6 +199,10 @@ std::map > SPELLutils::tokenizeData( const std::s
valueLength += (((unsigned char) data[pos+2]) << 8);
valueLength += (unsigned char) data[pos+3];
pos += 4;
+ if (pos + valueLength > data.size())
+ {
+ throw SPELLipcError( "Peer has sent bad data disconnecting!", 0);
+ }
value.assign(data.begin() + pos, data.begin() + pos + valueLength);
pos += valueLength;
@@ -428,6 +430,20 @@ bool SPELLutils::isFile( const std::string& path )
return isFile;
}
+//============================================================================
+// FUNCTION : SPELLutils::isLink
+//============================================================================
+bool SPELLutils::isLink( const std::string& path )
+{
+ struct stat buf;
+ bool isLink = false;
+ if (stat(path.c_str(),&buf) == 0)
+ {
+ isLink = S_ISLNK( buf.st_mode );
+ }
+ return isLink;
+}
+
//============================================================================
// FUNCTION : SPELLutils::fileCopy
//============================================================================
@@ -448,6 +464,18 @@ void SPELLutils::copyFile( const std::string& sourcePath, const std::string& tar
outfile.close();
}
+bool compare_nocase (const std::string& first, const std::string& second)
+{
+ unsigned int i=0;
+ while ( (itolower(second[i])) return false;
+ ++i;
+ }
+ return ( first.length() < second.length() );
+}
+
//============================================================================
// FUNCTION : SPELLutils::getFilesInDir
//============================================================================
@@ -455,6 +483,7 @@ std::list SPELLutils::getFilesInDir( const std::string& path )
{
DIR *dirp;
struct dirent *dp;
+ char buffer[512];
std::list files;
@@ -463,7 +492,29 @@ std::list SPELLutils::getFilesInDir( const std::string& path )
{
while ( (dp = readdir(dirp)) != NULL )
{
- if (dp->d_type & DT_REG)
+ if (dp->d_type == DT_LNK)
+ {
+ // Check the target of the link
+ std::string abspath = path + "/" + dp->d_name;
+ ssize_t fwd = readlink( abspath.c_str(), buffer, 512);
+ // Ignore it in case of errors
+ if (fwd<0)
+ {
+ LOG_ERROR("Unable to follow link " + std::string(dp->d_name));
+ continue;
+ }
+ std::string target_name(buffer,fwd);
+ if (target_name.find("/") != 0) // root path target
+ {
+ target_name = path + "/" + target_name;
+ }
+ LOG_WARN("Resolving file link " + std::string(dp->d_name) + " to " + target_name);
+ if (SPELLutils::isFile(target_name))
+ {
+ files.push_back(dp->d_name);
+ }
+ }
+ else if (dp->d_type == DT_REG)
{
files.push_back(dp->d_name);
}
@@ -484,6 +535,8 @@ std::list SPELLutils::getFilesInDir( const std::string& path )
{
LOG_ERROR("Failed to open directory '" + path + "' to read");
}
+ files.sort(compare_nocase);
+
return files;
}
@@ -494,10 +547,11 @@ std::list SPELLutils::getSubdirs( const std::string& path )
{
DIR* dirp;
struct dirent *dp;
+ char buffer[512];
std::string dot = ".";
std::string pdot = "..";
- std::string svn = ".svn";
+
std::list subdirs;
dirp = opendir( path.c_str() );
@@ -505,23 +559,45 @@ std::list SPELLutils::getSubdirs( const std::string& path )
{
while ( (dp = readdir(dirp)) != NULL )
{
- if (dp->d_type & DT_DIR)
+ std::string fname = dp->d_name;
+ if ( fname.find(".") == 0 )
+ continue; // discard ., .., all hidden directories including .svn and .git
+
+ if (dp->d_type == DT_LNK)
{
- if ( dp->d_name != dot && dp->d_name != pdot && dp->d_name != svn )
+ // Check the target of the link
+ std::string abspath = path + "/" + dp->d_name;
+ LOG_WARN("Found link " + abspath);
+
+ ssize_t fwd = readlink( abspath.c_str(), buffer, 512);
+ // Ignore it in case of errors
+ if (fwd<0)
+ {
+ LOG_ERROR("Unable to follow link " + std::string(dp->d_name));
+ continue;
+ }
+ std::string target_name(buffer,fwd);
+ if (target_name.find("/") != 0) // root path target
+ {
+ target_name = path + "/" + target_name;
+ }
+ LOG_WARN("Resolving directory link " + std::string(dp->d_name) + " to " + target_name);
+ if (SPELLutils::isDirectory(target_name))
{
subdirs.push_back(dp->d_name);
}
}
+ else if (dp->d_type & DT_DIR)
+ {
+ subdirs.push_back(dp->d_name);
+ }
// IMPORTANT: in some filesystems, the type may be impossible
// to get with readdir. In these cases we need to use stat().
else if (dp->d_type == DT_UNKNOWN)
{
if ( isDirectory( path + PATH_SEPARATOR + std::string(dp->d_name) ) )
{
- if ( dp->d_name != dot && dp->d_name != pdot && dp->d_name != svn )
- {
- subdirs.push_back(dp->d_name);
- }
+ subdirs.push_back(dp->d_name);
}
}
// Ignore other types like symbolic links, sockets, etc.
@@ -665,9 +741,7 @@ void SPELLutils::showEnvironment()
envVar("SPELL_COTS");
envVar("SPELL_DATA");
envVar("SPELL_CONFIG");
- envVar("SPELL_SYS_DATA");
envVar("SPELL_LOG");
- envVar("SPELL_PROCS");
std::cerr << "==============================================================================" << std::endl;
}
@@ -771,7 +845,11 @@ void SPELLutils::dumpInterpreterInfo( const std::string& id )
dumpFile << "Modules : " << PYSIZE(currIS->modules) << " items." << std::endl;
dumpFile << "Sysdict : " << PYSIZE(currIS->sysdict) << " items." << std::endl;
dumpFile << "Builtins : " << PYSIZE(currIS->builtins) << " items." << std::endl;
+#if PY_MAJOR_VERSION >= 3
+
+#else
dumpFile << "Reloading : " << PYSIZE(currIS->modules_reloading) << " items." << std::endl;
+#endif
dumpFile << "Search path : " << PYSIZE(currIS->codec_search_path) << " items." << std::endl;
dumpFile << "Search cache: " << PYSIZE(currIS->codec_search_cache) << " items." << std::endl;
dumpFile << "Error regst.: " << PYSIZE(currIS->codec_error_registry) << " items." << std::endl;
@@ -825,11 +903,22 @@ void SPELLutils::dumpThreadStateInfo( const std::string& id, PyThreadState* ts,
dumpFile << "Current exc. type : " << PYREPR(ts->curexc_type) << std::endl;
dumpFile << "Current exc. value: " << PYREPR(ts->curexc_value) << std::endl;
dumpFile << "Current exc. tback: " << PYREPR(ts->curexc_traceback) << std::endl;
+#if PY_MAJOR_VERSION >= 3
+ if (ts->exc_info)
+ {
+ dumpFile << "Exception type : " << PYREPR(ts->exc_info->exc_type) << std::endl;
+ dumpFile << "Exception value : " << PYREPR(ts->exc_info->exc_value) << std::endl;
+ dumpFile << "Exception tback : " << PYREPR(ts->exc_info->exc_traceback) << std::endl;
+ }
+#else
dumpFile << "Exception type : " << PYREPR(ts->exc_type) << std::endl;
dumpFile << "Exception value : " << PYREPR(ts->exc_value) << std::endl;
dumpFile << "Exception tback : " << PYREPR(ts->exc_traceback) << std::endl;
+#endif
dumpFile << "Main dict : " << PYSIZE(ts->dict) << " items." << std::endl;
+#if PY_MAJOR_VERSION < 3
dumpFile << "Tick counter : " << ts->tick_counter << std::endl;
+#endif
dumpFile << "GIL state counter : " << ts->gilstate_counter << std::endl;
dumpFile << "Async. exception : " << PYREPR(ts->async_exc) << std::endl;
dumpFile << "Thread id : " << ts->thread_id << std::endl;
@@ -866,7 +955,9 @@ void SPELLutils::dumpFrameInfo( const std::string& id, PyFrameObject* frame, int
dumpFile << "--------------------------------------" << std::endl;
dumpFile << "Address : " << PSTR(frame) << std::endl;
dumpFile << "Next address : " << PSTR(frame->f_back) << std::endl;
+#if PY_MAJOR_VERSION < 3
dumpFile << "Thread state address : " << PSTR(frame->f_tstate) << std::endl;
+#endif
dumpFile << "Last instruction : " << frame->f_lasti << std::endl;
dumpFile << "Last line : " << frame->f_lineno << std::endl;
dumpFile << "Try blocks count : " << frame->f_iblock << std::endl;
@@ -875,9 +966,11 @@ void SPELLutils::dumpFrameInfo( const std::string& id, PyFrameObject* frame, int
dumpFile << "Stack top : " << PSTR(frame->f_stacktop) << std::endl;
dumpFile << "Stack count : " << (frame->f_stacktop - frame->f_valuestack) << std::endl;
dumpFile << "Fast locals : " << (frame->f_code->co_nlocals-1) << std::endl;
+#if PY_MAJOR_VERSION < 3
dumpFile << "Exception type : " << PYREPR(frame->f_exc_type) << std::endl;
dumpFile << "Exception value : " << PYREPR(frame->f_exc_value) << std::endl;
dumpFile << "Exception traceback : " << PYREPR(frame->f_exc_traceback) << std::endl;
+#endif
dumpFile << "Trace function : " << PYREPR(frame->f_trace) << std::endl;
dumpFile << "Builtins : " << PYSIZE(frame->f_builtins) << std::endl;
dumpFile << "Globals : " << PYSIZE(frame->f_globals) << std::endl;
@@ -991,3 +1084,18 @@ SPELLutils::SPELLdateDesc SPELLutils::getSystemDate()
return date;
}
+
+//============================================================================
+// FUNCTION: SPELLutils::compareNocase (const std::string& first, const std::string& second)
+//============================================================================
+bool SPELLutils::compareNocase (const std::string& first, const std::string& second)
+{
+ unsigned int i=0;
+ while ( (itolower(second[i])) return false;
+ ++i;
+ }
+ return ( first.length() < second.length() );
+}
diff --git a/lib/SPELL_WRP/Makefile.am b/lib/SPELL_WRP/Makefile.am
index dad5810..8967b5a 100644
--- a/lib/SPELL_WRP/Makefile.am
+++ b/lib/SPELL_WRP/Makefile.am
@@ -1,36 +1,44 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
include ${top_srcdir}/common.mk
-lib_LTLIBRARIES= libSPELL_WRP.la
-libSPELL_WRP_la_LDFLAGS = -version-info 1:0:0
-libSPELL_WRP_la_SOURCES = \
- src/SPELLdriverManager.C \
- src/SPELLdatabaseManager.C \
- src/SPELLpyValue.C \
- src/SPELLconfigDict.C \
- src/SPELLregistry.C
-
+
+lib_LTLIBRARIES = libSPELL_WRP_v2.la libSPELL_WRP_v3.la
+
+libSPELL_WRP_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+
+libSPELL_WRP_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_WRP_v2_la_SOURCES = src/SPELLdriverManager.C \
+ src/SPELLdatabaseManager.C \
+ src/SPELLpyValue.C \
+ src/SPELLconfigDict.C \
+ src/SPELLregistry.C
+
+libSPELL_WRP_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS}
+
+libSPELL_WRP_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_WRP_v3_la_SOURCES = src/SPELLdriverManager.C \
+ src/SPELLdatabaseManager.C \
+ src/SPELLpyValue.C \
+ src/SPELLconfigDict.C \
+ src/SPELLregistry.C
\ No newline at end of file
diff --git a/lib/SPELL_WRP/src/SPELLconfigDict.C b/lib/SPELL_WRP/src/SPELLconfigDict.C
index 4be6332..72a97f0 100644
--- a/lib/SPELL_WRP/src/SPELLconfigDict.C
+++ b/lib/SPELL_WRP/src/SPELLconfigDict.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the configuration dictionary wrapper
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_WRP/src/SPELLdatabaseManager.C b/lib/SPELL_WRP/src/SPELLdatabaseManager.C
index f6bb4b1..774fb3d 100644
--- a/lib/SPELL_WRP/src/SPELLdatabaseManager.C
+++ b/lib/SPELL_WRP/src/SPELLdatabaseManager.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the database manager wrapper
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -83,15 +83,26 @@ PyObject* SPELLdatabaseManager::getDatabaseManagerObject()
//=============================================================================
void SPELLdatabaseManager::loadBuiltinDatabases()
{
- SPELLsafePythonOperations ops("SPELLdatabaseManager::loadBuiltinDatabases()");
- PyObject* mgr = getDatabaseManagerObject();
- // New reference
- PyObject* scdb = SPELLpythonHelper::instance().callMethod( mgr, "loadDatabase", STRPY("SCDB"), NULL);
- SPELLpythonHelper::instance().checkError();
- // New reference
- PyObject* gdb = SPELLpythonHelper::instance().callMethod( mgr, "loadDatabase", STRPY("GDB"), NULL );
- SPELLpythonHelper::instance().checkError();
- SPELLpythonHelper::instance().install( scdb, "SCDB" );
- SPELLpythonHelper::instance().install( gdb, "GDB" );
- SPELLpythonHelper::instance().checkError();
+ try {
+ PyObject* mgr = getDatabaseManagerObject();
+ // New reference
+ PyObject* scdb = SPELLpythonHelper::instance().callMethod( mgr, "loadDatabase", STRPY("SCDB"), NULL);
+ SPELLpythonHelper::instance().checkError();
+ // New reference
+ PyObject* gdb = SPELLpythonHelper::instance().callMethod( mgr, "loadDatabase", STRPY("GDB"), NULL );
+ SPELLpythonHelper::instance().checkError();
+ SPELLpythonHelper::instance().install( scdb, "SCDB" );
+ SPELLpythonHelper::instance().install( gdb, "GDB" );
+ SPELLpythonHelper::instance().checkError();
+ }
+ catch(SPELLcoreException& ex)
+ {
+ LOG_ERROR("loadBuiltinDatabases failed: " + ex.what());
+ throw ex;
+ }
+ catch(...)
+ {
+ LOG_ERROR("loadBuiltinDatabases failed: Unknown!");
+ throw;
+ }
}
diff --git a/lib/SPELL_WRP/src/SPELLdriverManager.C b/lib/SPELL_WRP/src/SPELLdriverManager.C
index cddf1f4..48a14a3 100644
--- a/lib/SPELL_WRP/src/SPELLdriverManager.C
+++ b/lib/SPELL_WRP/src/SPELLdriverManager.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the driver manager wrapper
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -35,7 +35,6 @@
#include "SPELL_CFG/SPELLconfiguration.H"
-
SPELLdriverManager* SPELLdriverManager::s_instance = 0;
//=============================================================================
@@ -73,6 +72,7 @@ PyObject* SPELLdriverManager::getDriverManagerObject()
if (m_dManager == 0)
{
// Borrowed
+ SPELLsafePythonOperations ops("SPELLdriverManager::setup()");
PyObject* classObj = SPELLpythonHelper::instance().getObject("spell.lib.drivermgr", "DriverManager");
m_dManager = SPELLpythonHelper::instance().callMethod( classObj, "instance", NULL );
Py_XINCREF(m_dManager);
@@ -85,17 +85,29 @@ PyObject* SPELLdriverManager::getDriverManagerObject()
//=============================================================================
void SPELLdriverManager::setup( const std::string& ctxName, const std::string& interfaces )
{
- SPELLsafePythonOperations ops("SPELLdriverManager::setup()");
- PyObject* pmgr = getDriverManagerObject();
- if (interfaces.empty())
+ try
+ {
+ PyObject* pmgr = getDriverManagerObject();
+ if (interfaces.empty())
+ {
+ SPELLpythonHelper::instance().callMethod( pmgr, "setup", SSTRPY(ctxName), NULL);
+ }
+ else
+ {
+ SPELLpythonHelper::instance().callMethod( pmgr, "setup", SSTRPY(ctxName), SSTRPY(interfaces), NULL);
+ }
+ SPELLpythonHelper::instance().checkError();
+ }
+ catch(SPELLcoreException& ex)
{
- SPELLpythonHelper::instance().callMethod( pmgr, "setup", SSTRPY(ctxName), NULL);
+ LOG_ERROR("Setup failed: " + ex.what());
+ throw ex;
}
- else
+ catch(...)
{
- SPELLpythonHelper::instance().callMethod( pmgr, "setup", SSTRPY(ctxName), SSTRPY(interfaces), NULL);
+ LOG_ERROR("Setup failed: Unknown!");
+ throw;
}
- SPELLpythonHelper::instance().checkError();
}
//=============================================================================
@@ -103,17 +115,27 @@ void SPELLdriverManager::setup( const std::string& ctxName, const std::string& i
//=============================================================================
void SPELLdriverManager::cleanup( bool shutdown )
{
- SPELLsafePythonOperations ops("SPELLdriverManager::cleanup()");
- PyObject* pmgr = getDriverManagerObject();
- if (shutdown)
+ try
+ {
+ PyObject* pmgr = getDriverManagerObject();
+ if (shutdown)
+ {
+ SPELLpythonHelper::instance().callMethod( pmgr, "cleanup", Py_False, Py_True, NULL );
+ }
+ else
+ {
+ SPELLpythonHelper::instance().callMethod( pmgr, "cleanup", NULL);
+ }
+ SPELLpythonHelper::instance().checkError();
+ }
+ catch(SPELLcoreException& ex)
{
- SPELLpythonHelper::instance().callMethod( pmgr, "cleanup", Py_False, Py_True, NULL );
+ LOG_ERROR("Cleanup failed: " + ex.what());
}
- else
+ catch(...)
{
- SPELLpythonHelper::instance().callMethod( pmgr, "cleanup", NULL);
+ LOG_ERROR("Cleanup failed: Unknown!");
}
- SPELLpythonHelper::instance().checkError();
}
//=============================================================================
@@ -121,11 +143,12 @@ void SPELLdriverManager::cleanup( bool shutdown )
//=============================================================================
void SPELLdriverManager::onCommand( const std::string& commandId )
{
- PyObject* pmgr = getDriverManagerObject();
- PyObject* cmd = SSTRPY(commandId);
- Py_INCREF(cmd);
try
{
+ SPELLsafePythonOperations ops("SPELLdriverManager::onCommand");
+ PyObject* pmgr = getDriverManagerObject();
+ PyObject* cmd = SSTRPY(commandId);
+ Py_INCREF(cmd);
SPELLpythonHelper::instance().callMethod( pmgr, "onCommand", cmd, NULL );
SPELLpythonHelper::instance().checkError();
}
diff --git a/lib/SPELL_WRP/src/SPELLpyValue.C b/lib/SPELL_WRP/src/SPELLpyValue.C
index 5da3343..f534302 100644
--- a/lib/SPELL_WRP/src/SPELLpyValue.C
+++ b/lib/SPELL_WRP/src/SPELLpyValue.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Data variable implementation
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -94,7 +94,7 @@ void SPELLpyValue::set( PyObject* pyValue )
{
DEBUG("[PYVAL] Int check");
m_type = LONG;
- m_intValue = PyInt_AsLong(pyValue);
+ m_intValue = PyLong_AsLongLong(pyValue);
}
else if (PyFloat_Check(pyValue))
{
@@ -103,7 +103,7 @@ void SPELLpyValue::set( PyObject* pyValue )
}
else if (SPELLpythonHelper::instance().isTime(pyValue))
{
- m_timeValue = SPELLpythonHelper::instance().evalTime(PYSSTR(pyValue));
+ m_timeValue = SPELLpythonHelper::instance().evalTime(pyValue);
if (m_timeValue.isDelta())
{
m_type = RELTIME;
@@ -173,7 +173,7 @@ PyObject* SPELLpyValue::get() const
}
else if (m_type == LONG )
{
- return PyLong_FromLong(m_intValue);
+ return PyLong_FromLongLong(m_intValue);
}
else if (m_type == DOUBLE)
{
diff --git a/lib/SPELL_WRP/src/SPELLregistry.C b/lib/SPELL_WRP/src/SPELLregistry.C
index e682910..7f503a0 100644
--- a/lib/SPELL_WRP/src/SPELLregistry.C
+++ b/lib/SPELL_WRP/src/SPELLregistry.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the registry wrapper
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_WS/Makefile.am b/lib/SPELL_WS/Makefile.am
index 92b0900..1001f30 100644
--- a/lib/SPELL_WS/Makefile.am
+++ b/lib/SPELL_WS/Makefile.am
@@ -1,55 +1,71 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
include ${top_srcdir}/common.mk
-lib_LTLIBRARIES= libSPELL_WS.la
-
-libSPELL_WS_la_CPPFLAGS = ${AM_CPPFLAGS}
-libSPELL_WS_la_LDFLAGS = -version-info 3:0:0
-
-libSPELL_WS_la_SOURCES = \
- src/SPELLwsStorage.C \
- src/SPELLwsDataHandler.C \
- src/SPELLwsDataCodes.C \
- src/SPELLwsDataHandlerFactory.C \
- src/SPELLwsObjectDataHandler.C \
- src/SPELLwsInstanceDataHandler.C \
- src/SPELLwsCustomTypeDataHandler.C \
- src/SPELLwsTmItemDataHandler.C \
- src/SPELLwsClassDataHandler.C \
- src/SPELLwsDictDataHandler.C \
- src/SPELLwsListDataHandler.C \
- src/SPELLwsTupleDataHandler.C \
- src/SPELLwsDbDataHandler.C \
- src/SPELLwsTimeDataHandler.C \
- src/SPELLwsWorkingMode.C \
- src/SPELLwsFrame.C \
- src/SPELLwsDynamicData.C \
- src/SPELLwsStaticData.C \
- src/SPELLwsWarmStartImpl.C
-
-
+lib_LTLIBRARIES = libSPELL_WS_v2.la libSPELL_WS_v3.la
+
+libSPELL_WS_v2_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+
+libSPELL_WS_v2_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_WS_v2_la_SOURCES = src/SPELLwsStorage.C \
+ src/SPELLwsDataHandler.C \
+ src/SPELLwsDataCodes.C \
+ src/SPELLwsDataHandlerFactory.C \
+ src/SPELLwsObjectDataHandler.C \
+ src/SPELLwsInstanceDataHandler.C \
+ src/SPELLwsCustomTypeDataHandler.C \
+ src/SPELLwsTmItemDataHandler.C \
+ src/SPELLwsClassDataHandler.C \
+ src/SPELLwsDictDataHandler.C \
+ src/SPELLwsListDataHandler.C \
+ src/SPELLwsTupleDataHandler.C \
+ src/SPELLwsDbDataHandler.C \
+ src/SPELLwsTimeDataHandler.C \
+ src/SPELLwsWorkingMode.C \
+ src/SPELLwsFrame.C \
+ src/SPELLwsDynamicData.C \
+ src/SPELLwsStaticData.C \
+ src/SPELLwsWarmStartImpl.C
+
+libSPELL_WS_v3_la_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS}
+
+libSPELL_WS_v3_la_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+
+libSPELL_WS_v3_la_SOURCES = src/SPELLwsStorage.C \
+ src/SPELLwsDataHandler.C \
+ src/SPELLwsDataCodes.C \
+ src/SPELLwsDataHandlerFactory.C \
+ src/SPELLwsObjectDataHandler.C \
+ src/SPELLwsCustomTypeDataHandler.C \
+ src/SPELLwsTmItemDataHandler.C \
+ src/SPELLwsDictDataHandler.C \
+ src/SPELLwsListDataHandler.C \
+ src/SPELLwsTupleDataHandler.C \
+ src/SPELLwsDbDataHandler.C \
+ src/SPELLwsTimeDataHandler.C \
+ src/SPELLwsWorkingMode.C \
+ src/SPELLwsFrame.C \
+ src/SPELLwsDynamicData.C \
+ src/SPELLwsStaticData.C \
+ src/SPELLwsWarmStartImpl.C
+
\ No newline at end of file
diff --git a/lib/SPELL_WS/src/SPELLwsClassDataHandler.C b/lib/SPELL_WS/src/SPELLwsClassDataHandler.C
index bf455d4..5a9762d 100644
--- a/lib/SPELL_WS/src/SPELLwsClassDataHandler.C
+++ b/lib/SPELL_WS/src/SPELLwsClassDataHandler.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the data handler for classes
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_WS/src/SPELLwsCustomTypeDataHandler.C b/lib/SPELL_WS/src/SPELLwsCustomTypeDataHandler.C
index f64a3b3..5cd4b9b 100644
--- a/lib/SPELL_WS/src/SPELLwsCustomTypeDataHandler.C
+++ b/lib/SPELL_WS/src/SPELLwsCustomTypeDataHandler.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the data handler for instances
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_WS/src/SPELLwsDataCodes.C b/lib/SPELL_WS/src/SPELLwsDataCodes.C
index f0a50f7..029cf81 100644
--- a/lib/SPELL_WS/src/SPELLwsDataCodes.C
+++ b/lib/SPELL_WS/src/SPELLwsDataCodes.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Data code functions
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_WS/src/SPELLwsDataHandler.C b/lib/SPELL_WS/src/SPELLwsDataHandler.C
index 33ebf07..247762f 100644
--- a/lib/SPELL_WS/src/SPELLwsDataHandler.C
+++ b/lib/SPELL_WS/src/SPELLwsDataHandler.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the base data handler
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_WS/src/SPELLwsDataHandlerFactory.C b/lib/SPELL_WS/src/SPELLwsDataHandlerFactory.C
index b52fed6..29525c3 100644
--- a/lib/SPELL_WS/src/SPELLwsDataHandlerFactory.C
+++ b/lib/SPELL_WS/src/SPELLwsDataHandlerFactory.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the data handler factory
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -27,8 +27,10 @@
// FILES TO INCLUDE ////////////////////////////////////////////////////////
// Local includes ----------------------------------------------------------
#include "SPELL_WS/SPELLwsDataHandlerFactory.H"
+#if PY_MAJOR_VERSION < 3
#include "SPELL_WS/SPELLwsClassDataHandler.H"
#include "SPELL_WS/SPELLwsInstanceDataHandler.H"
+#endif
#include "SPELL_WS/SPELLwsCustomTypeDataHandler.H"
#include "SPELL_WS/SPELLwsTmItemDataHandler.H"
#include "SPELL_WS/SPELLwsDictDataHandler.H"
@@ -85,6 +87,7 @@ SPELLwsDataHandler* SPELLwsDataHandlerFactory::createDataHandler( PyObject* obje
//DEBUG("[DHF] Object is TIME");
handler = new SPELLwsTimeDataHandler(object);
}
+#if PY_MAJOR_VERSION < 3
else if (PyClass_Check(object))
{
DEBUG("[DHF] Object is a class: " + PYCREPR(object));
@@ -95,6 +98,7 @@ SPELLwsDataHandler* SPELLwsDataHandlerFactory::createDataHandler( PyObject* obje
//DEBUG("[DHF] Object is a instance: " + PYCREPR(object));
handler = new SPELLwsInstanceDataHandler(object);
}
+#endif
else if (SPELLpythonHelper::instance().isSubclassInstance(object, "TmItemClass", "spell.lib.adapter.tm_item"))
{
//DEBUG("[DHF] Object is a TM item: " + PYCREPR(object));
@@ -129,12 +133,14 @@ SPELLwsDataHandler* SPELLwsDataHandlerFactory::createDataHandler( SPELLwsData::C
case SPELLwsData::DATA_GENERIC:
handler = new SPELLwsObjectDataHandler(NULL);
break;
+#if PY_MAJOR_VERSION < 3
case SPELLwsData::DATA_CLASS:
handler = new SPELLwsClassDataHandler(NULL);
break;
case SPELLwsData::DATA_INSTANCE:
handler = new SPELLwsInstanceDataHandler(NULL);
break;
+#endif
case SPELLwsData::DATA_CUSTOM_TYPE:
handler = new SPELLwsCustomTypeDataHandler(NULL);
break;
diff --git a/lib/SPELL_WS/src/SPELLwsDbDataHandler.C b/lib/SPELL_WS/src/SPELLwsDbDataHandler.C
index 6878064..974e272 100644
--- a/lib/SPELL_WS/src/SPELLwsDbDataHandler.C
+++ b/lib/SPELL_WS/src/SPELLwsDbDataHandler.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the data handler for SPELL databases
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_WS/src/SPELLwsDictDataHandler.C b/lib/SPELL_WS/src/SPELLwsDictDataHandler.C
index cf4e6fd..2a84ec6 100644
--- a/lib/SPELL_WS/src/SPELLwsDictDataHandler.C
+++ b/lib/SPELL_WS/src/SPELLwsDictDataHandler.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the data handler for dictionaries
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_WS/src/SPELLwsDynamicData.C b/lib/SPELL_WS/src/SPELLwsDynamicData.C
index 13ffa10..0bc2b03 100644
--- a/lib/SPELL_WS/src/SPELLwsDynamicData.C
+++ b/lib/SPELL_WS/src/SPELLwsDynamicData.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the dynamic runtime data manager
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -59,13 +59,13 @@ SPELLwsDynamicData::SPELLwsDynamicData( const SPELLwsStartupInfo& info, unsigned
: m_startup(info),
m_frame(frame)
{
- DEBUG("[DYN] Created dynamic data manager for frame " + PYCREPR(m_frame));
+ //DEBUG("[DYN] Created dynamic data manager for frame " + PYCREPR(m_frame));
assert(m_frame != NULL);
if (info.persistentFile != "")
{
m_persistentFile = info.persistentFile + "_" + ISTR(depth) + ".wsd";
- DEBUG("DYN Using persistent file: '" + m_persistentFile + "'");
+ //DEBUG("DYN Using persistent file: '" + m_persistentFile + "'");
}
else
{
@@ -75,15 +75,15 @@ SPELLwsDynamicData::SPELLwsDynamicData( const SPELLwsStartupInfo& info, unsigned
if (info.recoveryFile != "")
{
m_recoveryFile = info.recoveryFile + "_" + ISTR(depth) + ".wsd";
- DEBUG("DYN Using recovery file: '" + m_recoveryFile + "'");
+ //DEBUG("DYN Using recovery file: '" + m_recoveryFile + "'");
}
else
{
m_recoveryFile = "";
}
- DEBUG("DYN working mode: " + WorkingModeToString(m_startup.workingMode));
- DEBUG("DYN perform recovery: " + BSTR(m_startup.performRecovery));
+ //DEBUG("DYN working mode: " + WorkingModeToString(m_startup.workingMode));
+ //DEBUG("DYN perform recovery: " + BSTR(m_startup.performRecovery));
// If we are in recovery mode
if (m_startup.performRecovery && m_recoveryFile != "")
@@ -102,7 +102,7 @@ SPELLwsDynamicData::SPELLwsDynamicData( const SPELLwsStartupInfo& info, unsigned
//=============================================================================
SPELLwsDynamicData::~SPELLwsDynamicData()
{
- DEBUG("[DYN] Destroyed dynamic data manager for frame " + PYCREPR(m_frame));
+ //DEBUG("[DYN] Destroyed dynamic data manager for frame " + PYCREPR(m_frame));
}
//=============================================================================
@@ -110,7 +110,7 @@ SPELLwsDynamicData::~SPELLwsDynamicData()
//=============================================================================
void SPELLwsDynamicData::reset()
{
- DEBUG("[DYN] Reset dynamic data for frame " + PYCREPR(m_frame));
+ //DEBUG("[DYN] Reset dynamic data for frame " + PYCREPR(m_frame));
m_storage->reset();
m_iBlocks.clear();
// IMPORTANT do not DECREF objects in ValueStack or FastLocals, since they
@@ -124,7 +124,7 @@ void SPELLwsDynamicData::reset()
//=============================================================================
void SPELLwsDynamicData::cleanup()
{
- DEBUG("[DYN] Remove dynamic data file for frame " + PYCREPR(m_frame));
+ //DEBUG("[DYN] Remove dynamic data file for frame " + PYCREPR(m_frame));
if (m_persistentFile != "")
{
SPELLutils::deleteFile( m_persistentFile );
@@ -136,7 +136,7 @@ void SPELLwsDynamicData::cleanup()
//=============================================================================
void SPELLwsDynamicData::update()
{
- DEBUG("[DYN] Update dynamic data for frame " + PYCREPR(m_frame));
+ //DEBUG("[DYN] Update dynamic data for frame " + PYCREPR(m_frame));
// We need to keep a copy of these these data structures, since the Python interpreter code
// unwinds the stack and the try-blocks in case of exceptions.
updateTryBlocks();
@@ -149,7 +149,7 @@ void SPELLwsDynamicData::update()
//=============================================================================
void SPELLwsDynamicData::recover()
{
- DEBUG("[DYN] Recover dynamic data for frame " + PYCREPR(m_frame));
+ //DEBUG("[DYN] Recover dynamic data for frame " + PYCREPR(m_frame));
// We need to re-create these data structures, since the Python interpreter code
// unwinds the stack and the try-blocks in case of exceptions.
recoverTryBlocks();
@@ -162,13 +162,13 @@ void SPELLwsDynamicData::recover()
//=============================================================================
void SPELLwsDynamicData::save()
{
- DEBUG("[DYN] Save dynamic data for frame " + PYCREPR(m_frame));
- DEBUG("[DYN] Pre-check errors...");
+ //DEBUG("[DYN] Save dynamic data for frame " + PYCREPR(m_frame));
+ //DEBUG("[DYN] Pre-check errors...");
SPELLpythonHelper::instance().checkError();
// Empty the file. We only want the latest change
// NOTE: this can be removed in case we want the full history of
// changes, although some mods would need to be done to the load code
- DEBUG("[DYN] Resetting storage first");
+ //DEBUG("[DYN] Resetting storage first");
m_storage->reset();
// Store current data
storeParameters();
@@ -186,7 +186,7 @@ void SPELLwsDynamicData::save()
storeDTA("ARGS");
SPELLpythonHelper::instance().checkError();
storeDTA("IVARS");
- DEBUG("[DYN] Save dynamic data for frame " + PYCREPR(m_frame) + " done");
+ //DEBUG("[DYN] Save dynamic data for frame " + PYCREPR(m_frame) + " done");
}
//=============================================================================
@@ -199,7 +199,7 @@ void SPELLwsDynamicData::restore()
THROW_EXCEPTION("Failed to restore dynamic data", "Storage not ready", SPELL_ERROR_WSTART);
}
- DEBUG("[DYN] Restore dynamic data for frame " + PYCREPR(m_frame));
+ //DEBUG("[DYN] Restore dynamic data for frame " + PYCREPR(m_frame));
loadParameters();
loadTryBlocks();
loadValueStack();
@@ -211,13 +211,13 @@ void SPELLwsDynamicData::restore()
recover();
- DEBUG("[DYN] Restore dynamic data for frame " + PYCREPR(m_frame) + " done");
+ //DEBUG("[DYN] Restore dynamic data for frame " + PYCREPR(m_frame) + " done");
if (m_persistentFile != "")
{
// Reset the storage to mode write, using now the assigned persistent file,
// not the recovery file
- DEBUG("[DYN] Switching to saving state mode");
+ //DEBUG("[DYN] Switching to saving state mode");
delete m_storage;
m_storage = new SPELLwsStorage( m_persistentFile, SPELLwsStorage::MODE_WRITE );
// Re-save the state, so that the persistent file contains the current state
@@ -235,14 +235,14 @@ void SPELLwsDynamicData::updateTryBlocks()
unsigned int numTryBlocks = m_frame->f_iblock;
if (numTryBlocks>0)
{
- DEBUG("[DYN] Updating try blocks on frame " + PYCREPR(m_frame));
+ //DEBUG("[DYN] Updating try blocks on frame " + PYCREPR(m_frame));
// If there is a different number of blocks than before, update. We assume they dont change once created...
if ( numTryBlocks > m_iBlocks.size())
{
PyTryBlock block = m_frame->f_blockstack[m_frame->f_iblock-1];
m_iBlocks.push_back(block);
- DEBUG("[DYN] add block: [" + ISTR(block.b_type) + "," + ISTR(block.b_handler) + "," + ISTR(block.b_level) + "]");
+ //DEBUG("[DYN] add block: [" + ISTR(block.b_type) + "," + ISTR(block.b_handler) + "," + ISTR(block.b_level) + "]");
}
// Less blocks...
else if ((unsigned int) m_frame->f_iblock < m_iBlocks.size())
@@ -250,9 +250,9 @@ void SPELLwsDynamicData::updateTryBlocks()
// Just throw it away
TryBlocks::iterator it = m_iBlocks.end(); it--;
m_iBlocks.erase(it);
- DEBUG("[DYN] remove block");
+ //DEBUG("[DYN] remove block");
}
- DEBUG("[DYN] Updating try blocks done");
+ //DEBUG("[DYN] Updating try blocks done");
}
// Take into account the case of going out loops and try blocks ( the frame
// does not have blocks defined, so we must clear ours )
@@ -272,18 +272,18 @@ void SPELLwsDynamicData::recoverTryBlocks()
// If there were blocks defined...
if (m_iBlocks.size()>0)
{
- DEBUG("[DYN] Restoring try blocks on frame " + PYCREPR(m_frame));
+ //DEBUG("[DYN] Restoring try blocks on frame " + PYCREPR(m_frame));
TryBlocks::iterator it;
unsigned int count = 0;
for( it = m_iBlocks.begin(); it != m_iBlocks.end(); it++)
{
PyTryBlock& block = (*it);
- DEBUG("[DYN] block " + ISTR(count) + ": [" + ISTR(block.b_type) + "," + ISTR(block.b_handler) + "," + ISTR(block.b_level) + "]");
+ //DEBUG("[DYN] block " + ISTR(count) + ": [" + ISTR(block.b_type) + "," + ISTR(block.b_handler) + "," + ISTR(block.b_level) + "]");
PyFrame_BlockSetup( m_frame, block.b_type, block.b_handler, block.b_level );
count++;
}
m_frame->f_iblock = m_iBlocks.size();
- DEBUG("[DYN] Restoring try blocks done");
+ //DEBUG("[DYN] Restoring try blocks done");
}
}
@@ -292,7 +292,7 @@ void SPELLwsDynamicData::recoverTryBlocks()
//=============================================================================
void SPELLwsDynamicData::storeTryBlocks()
{
- DEBUG("[DYN] Storing try blocks (" + ISTR(m_iBlocks.size()) + ")" );
+ //DEBUG("[DYN] Storing try blocks (" + ISTR(m_iBlocks.size()) + ")" );
// Store tryblocks first. Size of the list:
m_storage->storeLong( m_iBlocks.size() );
// Store the blocks now, if any
@@ -302,7 +302,7 @@ void SPELLwsDynamicData::storeTryBlocks()
m_storage->storeLong( (*bit).b_type );
m_storage->storeLong( (*bit).b_handler );
m_storage->storeLong( (*bit).b_level );
- DEBUG(" - [" + ISTR((*bit).b_type) + "," + ISTR((*bit).b_handler) + "," + ISTR((*bit).b_level) + "]");
+ //DEBUG(" - [" + ISTR((*bit).b_type) + "," + ISTR((*bit).b_handler) + "," + ISTR((*bit).b_level) + "]");
}
}
@@ -312,14 +312,14 @@ void SPELLwsDynamicData::storeTryBlocks()
void SPELLwsDynamicData::loadTryBlocks()
{
int numBlocks = m_storage->loadLong();
- DEBUG("[DYN] Loading try blocks (" + ISTR(numBlocks) + ")" );
+ //DEBUG("[DYN] Loading try blocks (" + ISTR(numBlocks) + ")" );
for( int count=0; countb_type = m_storage->loadLong();
block->b_handler = m_storage->loadLong();
block->b_level = m_storage->loadLong();
- DEBUG(" - [" + ISTR(block->b_type) + "," + ISTR(block->b_handler) + "," + ISTR(block->b_level) + "]");
+ //DEBUG(" - [" + ISTR(block->b_type) + "," + ISTR(block->b_handler) + "," + ISTR(block->b_level) + "]");
m_iBlocks.push_back(*block);
}
}
@@ -338,17 +338,18 @@ void SPELLwsDynamicData::updateValueStack()
// Add a new item to the stack information
if ((unsigned int) stackCount > m_valueStack.size())
{
- DEBUG("[DYN] Updating value stack on frame " + PYCREPR(m_frame));
+ //DEBUG("[DYN] Updating value stack on frame " + PYCREPR(m_frame));
PyObject** p;
p = m_frame->f_valuestack;
-
+ if (!p || !*p) // Check for Nullpointer on stack
+ return;
PyTypeObject* type = (PyTypeObject*) PyObject_Type(*p);
if (STR(type->tp_name)=="listiterator" )
{
// Get the iterator characteristics
ListIteratorMirror* iterator = (ListIteratorMirror*) (*p);
- DEBUG("[DYN] add list iterator: [" + ISTR(iterator->it_index) + "," + PYCREPR(iterator->it_seq) + "]");
+ //DEBUG("[DYN] add list iterator: [" + ISTR(iterator->it_index) + "," + PYCREPR(iterator->it_seq) + "]");
// Create a copy
PyObject* newIterator = PyObject_GetIter( (PyObject*)iterator->it_seq );
@@ -356,24 +357,24 @@ void SPELLwsDynamicData::updateValueStack()
ListIteratorMirror* itm = (ListIteratorMirror*)newIterator;
itm->it_index = iterator->it_index;
// IMPORTANT this is a borrowed reference
- DEBUG("[DYN] stored iterator: [" + ISTR(itm->it_index) + "," + PYCREPR(itm->it_seq) + "]");
+ //DEBUG("[DYN] stored iterator: [" + ISTR(itm->it_index) + "," + PYCREPR(itm->it_seq) + "]");
m_valueStack.push_back(newIterator);
}
else
{
- DEBUG("[DYN] Adding to valuestack, unprocessed: " + PYREPR(*p));
+ //DEBUG("[DYN] Adding to valuestack, unprocessed: " + PYREPR(*p));
// IMPORTANT this is a borrowed reference
m_valueStack.push_back(*p);
}
- DEBUG("[DYN] Updating value stack done");
+ //DEBUG("[DYN] Updating value stack done");
}
// Less items
else if ((unsigned int) stackCount < m_valueStack.size())
{
// Throw it away...
ObjectList::iterator it = m_valueStack.end(); it--;
- DEBUG("[DYN] remove value stack object");
+ //DEBUG("[DYN] remove value stack object");
// IMPORTANT do not DECREF objects in ValueStack or FastLocals, since they
// are borrowed references managed by Python layer.
m_valueStack.erase(it);
@@ -386,14 +387,14 @@ void SPELLwsDynamicData::updateValueStack()
for( unsigned int index = 0; index < m_valueStack.size(); index++)
{
if (*p == NULL) break;
- DEBUG("[DYN] checking value stack object: " + PYREPR(*p));
+ //DEBUG("[DYN] checking value stack object: " + PYREPR(*p));
PyTypeObject* type = (PyTypeObject*) PyObject_Type(*p);
if (STR(type->tp_name)=="listiterator" )
{
ListIteratorMirror* stackIterator = (ListIteratorMirror*) (*p);
ListIteratorMirror* storedIterator = (ListIteratorMirror*) m_valueStack[index];
storedIterator->it_index = stackIterator->it_index;
- DEBUG("[DYN] update iterator: [" + ISTR(stackIterator->it_index) + "," + PYCREPR(stackIterator->it_seq) + "]");
+ //DEBUG("[DYN] update iterator: [" + ISTR(stackIterator->it_index) + "," + PYCREPR(stackIterator->it_seq) + "]");
}
}
}
@@ -416,19 +417,21 @@ void SPELLwsDynamicData::recoverValueStack()
// If there are values to recover
if (m_valueStack.size()>0)
{
- DEBUG("[DYN] Restoring value stack on frame " + PYCREPR(m_frame));
+ //DEBUG("[DYN] Restoring value stack on frame " + PYCREPR(m_frame));
PyObject** stack_pointer = m_frame->f_valuestack;
for( unsigned int count = 0; counttp_name));
+ //DEBUG("[DYN] Type is " + STR(type->tp_name));
if (STR(type->tp_name)=="listiterator" )
{
ListIteratorMirror* stackIterator = (ListIteratorMirror*) (stackObject);
- DEBUG("[DYN] restoring iterator: [" + ISTR(stackIterator->it_index) + "," + PYCREPR(stackIterator->it_seq) + "]");
+ //DEBUG("[DYN] restoring iterator: [" + ISTR(stackIterator->it_index) + "," + PYCREPR(stackIterator->it_seq) + "]");
PyObject* newIterator = PyObject_GetIter( (PyObject*)stackIterator->it_seq );
newIterator->ob_refcnt = stackObject->ob_refcnt;
*stack_pointer++ = newIterator;
@@ -440,7 +443,7 @@ void SPELLwsDynamicData::recoverValueStack()
}
m_frame->f_stacktop = stack_pointer--;
m_frame->f_code->co_stacksize = m_valueStack.size();
- DEBUG("[DYN] Restoring value stack done");
+ //DEBUG("[DYN] Restoring value stack done");
}
// Otherwise define the top as the same value as the bottom of the stack
else
@@ -456,7 +459,7 @@ void SPELLwsDynamicData::storeValueStack()
{
// Store the value stack. Size of the list first:
m_storage->storeLong( m_valueStack.size() );
- DEBUG("[DYN] Storing value stack for frame " + PYCREPR(m_frame));
+ //DEBUG("[DYN] Storing value stack for frame " + PYCREPR(m_frame));
ObjectList::iterator it;
for( it = m_valueStack.begin(); it != m_valueStack.end(); it++)
{
@@ -509,7 +512,7 @@ void SPELLwsDynamicData::storeValueStack()
void SPELLwsDynamicData::loadValueStack()
{
long numValues = m_storage->loadLong();
- DEBUG("[DYN] Loading value stack for frame " + PYCREPR(m_frame));
+ //DEBUG("[DYN] Loading value stack for frame " + PYCREPR(m_frame));
for( int count = 0; count < numValues; count++)
{
// Retrieve the marker
@@ -551,7 +554,7 @@ void SPELLwsDynamicData::updateFastLocals()
{
assert(m_frame != NULL);
int numLocals = m_frame->f_code->co_nlocals-1;
- DEBUG("[DYN] Update fast locals: " + ISTR(numLocals));
+ //DEBUG("[DYN] Update fast locals: " + ISTR(numLocals));
if (numLocals<0) numLocals = 0;
m_fastLocals.clear();
if ((numLocals>0) && ((unsigned int)numLocals != m_fastLocals.size()))
@@ -561,7 +564,7 @@ void SPELLwsDynamicData::updateFastLocals()
{
if (*lplus)
{
- DEBUG(" add fast local: " + PYREPR(*lplus));
+ //DEBUG(" add fast local: " + PYREPR(*lplus));
// IMPORTANT this is a borrowed reference
m_fastLocals.push_back(*lplus);
lplus++;
@@ -576,13 +579,13 @@ void SPELLwsDynamicData::updateFastLocals()
void SPELLwsDynamicData::recoverFastLocals()
{
assert(m_frame != NULL);
- DEBUG("[DYN] Recover fast locals: " + ISTR(m_fastLocals.size()));
+ //DEBUG("[DYN] Recover fast locals: " + ISTR(m_fastLocals.size()));
if (m_fastLocals.size()>0)
{
for( unsigned int count = 0; countf_localsplus[count] = obj;
}
m_frame->f_code->co_nlocals = m_fastLocals.size()+1;
@@ -594,13 +597,13 @@ void SPELLwsDynamicData::recoverFastLocals()
//=============================================================================
void SPELLwsDynamicData::storeFastLocals()
{
- DEBUG("[DYN] Store fast locals: " + ISTR(m_fastLocals.size()));
+ //DEBUG("[DYN] Store fast locals: " + ISTR(m_fastLocals.size()));
// Store the fast locals. Size of list first
m_storage->storeLong( m_fastLocals.size() );
ObjectList::iterator it;
for( it = m_fastLocals.begin(); it != m_fastLocals.end(); it++)
{
- DEBUG(" storing fast local " + PYREPR(*it));
+ //DEBUG(" storing fast local " + PYREPR(*it));
m_storage->storeObjectOrNone(*it);
}
}
@@ -611,11 +614,11 @@ void SPELLwsDynamicData::storeFastLocals()
void SPELLwsDynamicData::loadFastLocals()
{
long numLocals = m_storage->loadLong();
- DEBUG("[DYN] Load fast locals: " + ISTR(numLocals));
+ //DEBUG("[DYN] Load fast locals: " + ISTR(numLocals));
for(int count=0; countloadObject();
- DEBUG(" loaded fast local " + PYREPR(obj));
+ //DEBUG(" loaded fast local " + PYREPR(obj));
m_fastLocals.push_back( obj );
}
}
@@ -625,7 +628,7 @@ void SPELLwsDynamicData::loadFastLocals()
//=============================================================================
void SPELLwsDynamicData::storeGlobals()
{
- DEBUG("[DYN] Storing globals");
+ //DEBUG("[DYN] Storing globals");
assert( m_frame->f_globals != NULL );
storeDictionary( m_frame->f_globals );
storeConstReferences( m_frame->f_globals );
@@ -676,7 +679,7 @@ void SPELLwsDynamicData::loadGlobals()
//=============================================================================
void SPELLwsDynamicData::storeLocals()
{
- DEBUG("[DYN] Storing locals");
+ //DEBUG("[DYN] Storing locals");
// IMPORTANT: do not remove this PyFrame calls. Inside functions, local variables MAY be defined in the
// fast locals, depending on their contents. These calls are needed so that the storeDictionary() call
// is able to store those local variables which were not moved to fast locals. Fast locals and locals
@@ -697,7 +700,7 @@ void SPELLwsDynamicData::loadLocals()
if (restored != NULL)
{
- DEBUG("[DYN] Restored locals dictionary");
+ //DEBUG("[DYN] Restored locals dictionary");
// IMPORTANT: do not remove this PyFrame calls. Inside functions, local variables MAY be defined in the
// fast locals, depending on their contents. These calls are needed so that the storeDictionary() call
// is able to store those local variables which were not moved to fast locals. Fast locals and locals
@@ -723,7 +726,7 @@ void SPELLwsDynamicData::loadLocals()
//=============================================================================
void SPELLwsDynamicData::storeConstReferences( PyObject* dictionary )
{
- DEBUG("[DYN] Store const references");
+ //DEBUG("[DYN] Store const references");
if (dictionary == NULL)
{
m_storage->storeLong( 0 );
@@ -731,7 +734,7 @@ void SPELLwsDynamicData::storeConstReferences( PyObject* dictionary )
}
// Store possibly loaded functions which are ignored by the dictionary
// handler, if they are part of the code definition
- DEBUG("[DYN] Counting const references");
+ //DEBUG("[DYN] Counting const references");
// Store first the amount of code references
unsigned int numReferences = 0;
int numConsts = 0;
@@ -739,7 +742,7 @@ void SPELLwsDynamicData::storeConstReferences( PyObject* dictionary )
if (co_consts != NULL)
{
numConsts = PyTuple_Size(co_consts);
- DEBUG("[DYN] Defined " + ISTR(numConsts) + " constants in code");
+ //DEBUG("[DYN] Defined " + ISTR(numConsts) + " constants in code");
for( int index = 0; index < numConsts; index++ )
{
PyObject* item = PyTuple_GetItem(co_consts,index);
@@ -756,7 +759,7 @@ void SPELLwsDynamicData::storeConstReferences( PyObject* dictionary )
}
}
- DEBUG("[DYN] Number of code references: " + ISTR(numReferences));
+ //DEBUG("[DYN] Number of code references: " + ISTR(numReferences));
m_storage->storeLong( numReferences );
if (numReferences>0)
@@ -771,7 +774,7 @@ void SPELLwsDynamicData::storeConstReferences( PyObject* dictionary )
// And the code object has been loaded in the globals dictionary
if (PyDict_Contains( dictionary, code->co_name ))
{
- DEBUG("[DYN] Storing code reference: " + PYSTR(code->co_name));
+ //DEBUG("[DYN] Storing code reference: " + PYSTR(code->co_name));
m_storage->storeObject( code->co_name );
}
}
@@ -789,7 +792,7 @@ void SPELLwsDynamicData::loadConstReferences( PyObject* dictionary )
if (numReferences > 0)
{
- DEBUG("[DYN] " + ISTR(numReferences) + " global references to load");
+ //DEBUG("[DYN] " + ISTR(numReferences) + " global references to load");
for(unsigned int count = 0; count < numReferences; count++ )
{
PyObject* codeName = m_storage->loadObject();
@@ -804,7 +807,7 @@ void SPELLwsDynamicData::loadConstReferences( PyObject* dictionary )
PyCodeObject* code = (PyCodeObject*) item;
if (PYSTR(code->co_name) == PYSTR(codeName))
{
- DEBUG("[DYN] Loading reference to " + PYREPR(codeName));
+ //DEBUG("[DYN] Loading reference to " + PYREPR(codeName));
PyDict_SetItem( dictionary, code->co_name, PyFunction_New( (PyObject*) code, m_frame->f_globals) );
}
}
@@ -813,7 +816,7 @@ void SPELLwsDynamicData::loadConstReferences( PyObject* dictionary )
}
else
{
- DEBUG("[DYN] No global references to load");
+ //DEBUG("[DYN] No global references to load");
}
}
@@ -822,13 +825,13 @@ void SPELLwsDynamicData::loadConstReferences( PyObject* dictionary )
//=============================================================================
void SPELLwsDynamicData::storeParameters()
{
- DEBUG("[DYN] Storing frame parameters");
+ //DEBUG("[DYN] Storing frame parameters");
m_storage->storeLong(m_frame->f_lineno);
- DEBUG(" - Lineno : " + ISTR(m_frame->f_lineno));
+ //DEBUG(" - Lineno : " + ISTR(m_frame->f_lineno));
m_storage->storeLong(m_frame->f_lasti);
- DEBUG(" - Instruction: " + ISTR(m_frame->f_lasti));
+ //DEBUG(" - Instruction: " + ISTR(m_frame->f_lasti));
m_storage->storeLong(m_frame->f_iblock);
- DEBUG(" - IBlocks : " + ISTR(m_frame->f_iblock));
+ //DEBUG(" - IBlocks : " + ISTR(m_frame->f_iblock));
}
//=============================================================================
@@ -836,9 +839,9 @@ void SPELLwsDynamicData::storeParameters()
//=============================================================================
void SPELLwsDynamicData::loadParameters()
{
- DEBUG("[DYN] Loading frame parameters");
+ //DEBUG("[DYN] Loading frame parameters");
m_frame->f_lineno = m_storage->loadLong();
- DEBUG(" - Lineno : " + ISTR(m_frame->f_lineno));
+ //DEBUG(" - Lineno : " + ISTR(m_frame->f_lineno));
m_frame->f_lasti = m_storage->loadLong();
// The last instruction pointer needs to be adjusted. Same as for fixState() algorithm
@@ -849,29 +852,29 @@ void SPELLwsDynamicData::loadParameters()
THROW_EXCEPTION("Unable to restore frame dynamic data", "Cannot restore frame parameters", SPELL_ERROR_WSTART);
}
- DEBUG("[DYN] Adjusting offset");
+ //DEBUG("[DYN] Adjusting offset");
int offsetForLine = lnotab.offset(m_frame->f_lineno);
// If the current offset matches the first offset corresponding to the restored
// line in the lnotab, we are in the main proc and NO function call. We need
// to decrease the last instruction offset by 1 (see PyEval_EvalFrameEx)
if (offsetForLine == m_frame->f_lasti)
{
- DEBUG("[DYN] Corresponds to normal statement");
+ //DEBUG("[DYN] Corresponds to normal statement");
m_frame->f_lasti = offsetForLine-1;
}
// Otherwise, we need to increase the offset by 2 (+3,-1) in order to position
// the interpreter right after the CALL_FUNCTION opcode, in the POP_TOP opcode
else
{
- DEBUG("[DYN] Corresponds to function call");
+ //DEBUG("[DYN] Corresponds to function call");
int nextLine = lnotab.lineAfter(m_frame->f_lineno);
- DEBUG("[DYN] Next line is " + ISTR(nextLine));
+ //DEBUG("[DYN] Next line is " + ISTR(nextLine));
int nextInstruction = lnotab.offset(nextLine);
m_frame->f_lasti = nextInstruction -1; // Will position it in the lastLine but POP_TOP instr.
}
- DEBUG(" - Instruction: " + ISTR(m_frame->f_lasti));
+ //DEBUG(" - Instruction: " + ISTR(m_frame->f_lasti));
m_frame->f_iblock = m_storage->loadLong();
- DEBUG(" - IBlocks : " + ISTR(m_frame->f_iblock));
+ //DEBUG(" - IBlocks : " + ISTR(m_frame->f_iblock));
}
//=============================================================================
@@ -900,7 +903,7 @@ PyObject* SPELLwsDynamicData::loadDictionary()
//=============================================================================
void SPELLwsDynamicData::storeDTA( const std::string& container )
{
- DEBUG("[DYN] Store DTA container: " + container);
+ //DEBUG("[DYN] Store DTA container: " + container);
PyObject* pyObj = PyDict_GetItemString(SPELLpythonHelper::instance().getMainDict(), container.c_str() );
@@ -917,7 +920,7 @@ void SPELLwsDynamicData::storeDTA( const std::string& container )
m_storage->storeLong(numKeys);
- DEBUG("[DYN] " + ISTR(numKeys) + " items");
+ //DEBUG("[DYN] " + ISTR(numKeys) + " items");
for(unsigned int index=0; index < numKeys; index++)
{
@@ -931,13 +934,13 @@ void SPELLwsDynamicData::storeDTA( const std::string& container )
std::string format = var->getFormat();
std::string type = var->getType();
- DEBUG(" - key: " + var->getName());
+ //DEBUG(" - key: " + var->getName());
// 0. Key
m_storage->storeObject( SSTRPY(var->getName()) );
// 1. Value
- DEBUG(" - value: " + PYREPR(value));
+ //DEBUG(" - value: " + PYREPR(value));
SPELLwsDataHandler* handler = SPELLwsDataHandlerFactory::createDataHandler(value);
handler->setStorage(m_storage);
m_storage->storeLong(handler->getCode());
@@ -946,22 +949,22 @@ void SPELLwsDynamicData::storeDTA( const std::string& container )
// 2. Format, Type and Confirm
if (format.empty())
{
- DEBUG(" - no format given");
+ //DEBUG(" - no format given");
m_storage->storeObject( Py_None );
}
else
{
- DEBUG(" - format: " + format);
+ //DEBUG(" - format: " + format);
m_storage->storeObject( SSTRPY(format) );
}
if (type.empty())
{
- DEBUG(" - no type given");
+ //DEBUG(" - no type given");
m_storage->storeObject( Py_None );
}
else
{
- DEBUG(" - type: " + type);
+ //DEBUG(" - type: " + type);
m_storage->storeObject( SSTRPY(type) );
}
m_storage->storeObject( confirmGet ? Py_True : Py_False );
@@ -983,7 +986,7 @@ void SPELLwsDynamicData::storeDTA( const std::string& container )
}
}
- DEBUG("[DYN] Data container stored");
+ //DEBUG("[DYN] Data container stored");
}
//=============================================================================
@@ -991,7 +994,7 @@ void SPELLwsDynamicData::storeDTA( const std::string& container )
//=============================================================================
void SPELLwsDynamicData::loadDTA( const std::string& container )
{
- DEBUG("[DYN] Loading data container: " + container);
+ //DEBUG("[DYN] Loading data container: " + container);
PyObject* pyObj = PyDict_GetItemString(SPELLpythonHelper::instance().getMainDict(), container.c_str() );
@@ -1006,14 +1009,14 @@ void SPELLwsDynamicData::loadDTA( const std::string& container )
unsigned int numKeys = m_storage->loadLong();
- DEBUG("[DYN] Items to load: " + ISTR(numKeys));
+ //DEBUG("[DYN] Items to load: " + ISTR(numKeys));
for(unsigned int index=0; index < numKeys; index++)
{
// 0. Key
PyObject* pyName = m_storage->loadObject();
- DEBUG(" - key: " + PYREPR(pyName));
+ //DEBUG(" - key: " + PYREPR(pyName));
// 1. Value
SPELLwsData::Code code = (SPELLwsData::Code) m_storage->loadLong();
@@ -1023,13 +1026,13 @@ void SPELLwsDynamicData::loadDTA( const std::string& container )
PyObject* value = handler->getObject();
- DEBUG(" - value: " + PYREPR(value));
+ //DEBUG(" - value: " + PYREPR(value));
// 2. Format, Type and Confirm
PyObject* pyFormat = m_storage->loadObject();
- DEBUG(" - format: " + PYREPR(pyFormat));
+ //DEBUG(" - format: " + PYREPR(pyFormat));
PyObject* pyType = m_storage->loadObject();
- DEBUG(" - type: " + PYREPR(pyType));
+ //DEBUG(" - type: " + PYREPR(pyType));
PyObject* pyConfirm = m_storage->loadObject();
// 3. Expected
@@ -1055,7 +1058,7 @@ void SPELLwsDynamicData::loadDTA( const std::string& container )
}
// Create the variable
- PyObject* varClass = SPELLpythonHelper::instance().getObject("libSPELL_DTA", "Var");
+ PyObject* varClass = SPELLpythonHelper::instance().getObject(MOD_NAME(libSPELL_DTA), "Var");
Py_INCREF(varClass);
assert(varClass != NULL);
PyObject* dict = PyDict_New();
@@ -1090,6 +1093,6 @@ void SPELLwsDynamicData::loadDTA( const std::string& container )
args->setValue(pyName,instance);
}
- DEBUG("[DYN] Data container loaded");
+ //DEBUG("[DYN] Data container loaded");
}
diff --git a/lib/SPELL_WS/src/SPELLwsFrame.C b/lib/SPELL_WS/src/SPELLwsFrame.C
index bf535d0..21948aa 100644
--- a/lib/SPELL_WS/src/SPELLwsFrame.C
+++ b/lib/SPELL_WS/src/SPELLwsFrame.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the frame data manager
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -139,16 +139,19 @@ void SPELLwsFrame::fixState( PyThreadState* newState, bool isHead )
// Reset the frame values
m_frame->f_lasti = m_lastInstruction;
m_frame->f_lineno = m_lastLine;
+#if PY_MAJOR_VERSION < 3
m_frame->f_tstate = newState;
+#endif
m_frame->f_stacktop = m_frame->f_valuestack;
// Reset exception trace
+#if PY_MAJOR_VERSION < 3
Py_XDECREF(m_frame->f_exc_traceback);
Py_XDECREF(m_frame->f_exc_type);
Py_XDECREF(m_frame->f_exc_value);
m_frame->f_exc_traceback = NULL;
m_frame->f_exc_type = NULL;
m_frame->f_exc_value = NULL;
-
+#endif
// Recover the dynamic data and update the frame
DEBUG("[FRM] Recovering dynamic data");
m_dynamic->recover();
diff --git a/lib/SPELL_WS/src/SPELLwsInstanceDataHandler.C b/lib/SPELL_WS/src/SPELLwsInstanceDataHandler.C
index f2c3087..e7d92f0 100644
--- a/lib/SPELL_WS/src/SPELLwsInstanceDataHandler.C
+++ b/lib/SPELL_WS/src/SPELLwsInstanceDataHandler.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the data handler for instances
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_WS/src/SPELLwsListDataHandler.C b/lib/SPELL_WS/src/SPELLwsListDataHandler.C
index ac0ea9c..35cb0b5 100644
--- a/lib/SPELL_WS/src/SPELLwsListDataHandler.C
+++ b/lib/SPELL_WS/src/SPELLwsListDataHandler.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the data handler for lists
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_WS/src/SPELLwsObjectDataHandler.C b/lib/SPELL_WS/src/SPELLwsObjectDataHandler.C
index 6a9c6ce..a9bc45c 100644
--- a/lib/SPELL_WS/src/SPELLwsObjectDataHandler.C
+++ b/lib/SPELL_WS/src/SPELLwsObjectDataHandler.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the data handler for objects
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_WS/src/SPELLwsStaticData.C b/lib/SPELL_WS/src/SPELLwsStaticData.C
index f7cbe77..f4841b4 100644
--- a/lib/SPELL_WS/src/SPELLwsStaticData.C
+++ b/lib/SPELL_WS/src/SPELLwsStaticData.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the static data manager
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_WS/src/SPELLwsStorage.C b/lib/SPELL_WS/src/SPELLwsStorage.C
index 75b8f08..55ce1bb 100644
--- a/lib/SPELL_WS/src/SPELLwsStorage.C
+++ b/lib/SPELL_WS/src/SPELLwsStorage.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the storage model
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -148,7 +148,7 @@ void SPELLwsStorage::storeObject( PyObject* object )
SPELLpythonHelper::instance().checkError();
int marshal_len = PyObject_Length(marshal);
DEBUG("Marshal length: " + ISTR(marshal_len));
- char* encoded = PyString_AsString(marshal);
+ const char* encoded = PyString_AsString(marshal);
// FORMAT IN FILE:
// COUNT \1 PTYPE \1 MARSHAL LENGTH
diff --git a/lib/SPELL_WS/src/SPELLwsTimeDataHandler.C b/lib/SPELL_WS/src/SPELLwsTimeDataHandler.C
index a1dafda..220c3c6 100644
--- a/lib/SPELL_WS/src/SPELLwsTimeDataHandler.C
+++ b/lib/SPELL_WS/src/SPELLwsTimeDataHandler.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the data handler for SPELL TIME
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_WS/src/SPELLwsTmItemDataHandler.C b/lib/SPELL_WS/src/SPELLwsTmItemDataHandler.C
index 4c8a9ca..9735f2e 100644
--- a/lib/SPELL_WS/src/SPELLwsTmItemDataHandler.C
+++ b/lib/SPELL_WS/src/SPELLwsTmItemDataHandler.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the data handler for tm items
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_WS/src/SPELLwsTupleDataHandler.C b/lib/SPELL_WS/src/SPELLwsTupleDataHandler.C
index 4ebbaa6..9ad43b6 100644
--- a/lib/SPELL_WS/src/SPELLwsTupleDataHandler.C
+++ b/lib/SPELL_WS/src/SPELLwsTupleDataHandler.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the data handler for lists
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/lib/SPELL_WS/src/SPELLwsWarmStartImpl.C b/lib/SPELL_WS/src/SPELLwsWarmStartImpl.C
index b8b617a..a89e819 100644
--- a/lib/SPELL_WS/src/SPELLwsWarmStartImpl.C
+++ b/lib/SPELL_WS/src/SPELLwsWarmStartImpl.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the warm start mechanism controller
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -175,6 +175,7 @@ void SPELLwsWarmStartImpl::saveState()
SPELLsafePythonOperations ops("SPELLwsWarmstartImpl::saveState()");
//TODO check, possibly there are several states that need to be saved
+#if PY_MAJOR_VERSION < 3
PyThreadState* state = m_topFrame->getFrameObject()->f_tstate;
DEBUG("Current thread state: " + PSTR(state));
@@ -188,6 +189,7 @@ void SPELLwsWarmStartImpl::saveState()
m_storage->storeLong( state->tick_counter );
DEBUG(" - GIL counter : " + ISTR(state->gilstate_counter));
m_storage->storeLong( state->gilstate_counter );
+#endif
DEBUG(" - Number of frames: " + ISTR(m_frames.size()));
m_storage->storeLong( m_frames.size() );
@@ -233,8 +235,10 @@ PyFrameObject* SPELLwsWarmStartImpl::restoreState()
tstate->recursion_depth = m_storage->loadLong();
DEBUG(" - Recursion depth : " + ISTR(tstate->recursion_depth));
+#if PY_MAJOR_VERSION < 3
tstate->tick_counter = m_storage->loadLong();
DEBUG(" - Tcik counter : " + ISTR(tstate->tick_counter));
+#endif
tstate->gilstate_counter = m_storage->loadLong();
DEBUG(" - GIL counter : " + ISTR(tstate->gilstate_counter));
int numFrames = m_storage->loadLong();
@@ -338,7 +342,9 @@ PyFrameObject* SPELLwsWarmStartImpl::fixState()
newState->recursion_depth = oldState->recursion_depth;
newState->tracing = oldState->tracing;
newState->use_tracing = oldState->use_tracing;
+#if PY_MAJOR_VERSION < 3
newState->tick_counter = oldState->tick_counter;
+#endif
newState->gilstate_counter = oldState->gilstate_counter;
newState->dict = PyDict_Copy(oldState->dict);
@@ -349,7 +355,7 @@ PyFrameObject* SPELLwsWarmStartImpl::fixState()
for( unsigned int index = 0; index < frameCount; index++)
{
bool isHead = (index == (frameCount-1));
- DEBUG("[WS] Fix state on frame index " + ISTR(index) + " frame=" + PYCREPR(m_frames[index]));
+ DEBUG("[WS] Fix state on frame index " + ISTR(index) + " frame=" + PYCREPR(m_frames[index]->getFrameObject()));
m_topFrame = m_frames[index];
m_topFrame->fixState(newState, isHead);
}
diff --git a/lib/SPELL_WS/src/SPELLwsWorkingMode.C b/lib/SPELL_WS/src/SPELLwsWorkingMode.C
index 2abc876..004d1ae 100644
--- a/lib/SPELL_WS/src/SPELLwsWorkingMode.C
+++ b/lib/SPELL_WS/src/SPELLwsWorkingMode.C
@@ -5,7 +5,7 @@
// DESCRIPTION: Implementation of the warmstart working mode
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
diff --git a/m4/.gitignore b/m4/.gitignore
new file mode 100644
index 0000000..94e6f26
--- /dev/null
+++ b/m4/.gitignore
@@ -0,0 +1,5 @@
+/libtool.m4
+/ltoptions.m4
+/ltsugar.m4
+/ltversion.m4
+/lt~obsolete.m4
diff --git a/m4/ax_compare_version.m4 b/m4/ax_compare_version.m4
new file mode 100644
index 0000000..9c8e208
--- /dev/null
+++ b/m4/ax_compare_version.m4
@@ -0,0 +1,177 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_compare_version.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
+#
+# DESCRIPTION
+#
+# This macro compares two version strings. Due to the various number of
+# minor-version numbers that can exist, and the fact that string
+# comparisons are not compatible with numeric comparisons, this is not
+# necessarily trivial to do in a autoconf script. This macro makes doing
+# these comparisons easy.
+#
+# The six basic comparisons are available, as well as checking equality
+# limited to a certain number of minor-version levels.
+#
+# The operator OP determines what type of comparison to do, and can be one
+# of:
+#
+# eq - equal (test A == B)
+# ne - not equal (test A != B)
+# le - less than or equal (test A <= B)
+# ge - greater than or equal (test A >= B)
+# lt - less than (test A < B)
+# gt - greater than (test A > B)
+#
+# Additionally, the eq and ne operator can have a number after it to limit
+# the test to that number of minor versions.
+#
+# eq0 - equal up to the length of the shorter version
+# ne0 - not equal up to the length of the shorter version
+# eqN - equal up to N sub-version levels
+# neN - not equal up to N sub-version levels
+#
+# When the condition is true, shell commands ACTION-IF-TRUE are run,
+# otherwise shell commands ACTION-IF-FALSE are run. The environment
+# variable 'ax_compare_version' is always set to either 'true' or 'false'
+# as well.
+#
+# Examples:
+#
+# AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8])
+# AX_COMPARE_VERSION([3.15],[lt],[3.15.8])
+#
+# would both be true.
+#
+# AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8])
+# AX_COMPARE_VERSION([3.15],[gt],[3.15.8])
+#
+# would both be false.
+#
+# AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8])
+#
+# would be true because it is only comparing two minor versions.
+#
+# AX_COMPARE_VERSION([3.15.7],[eq0],[3.15])
+#
+# would be true because it is only comparing the lesser number of minor
+# versions of the two values.
+#
+# Note: The characters that separate the version numbers do not matter. An
+# empty string is the same as version 0. OP is evaluated by autoconf, not
+# configure, so must be a string, not a variable.
+#
+# The author would like to acknowledge Guido Draheim whose advice about
+# the m4_case and m4_ifvaln functions make this macro only include the
+# portions necessary to perform the specific comparison specified by the
+# OP argument in the final configure script.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Tim Toolan
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 12
+
+dnl #########################################################################
+AC_DEFUN([AX_COMPARE_VERSION], [
+ AC_REQUIRE([AC_PROG_AWK])
+
+ # Used to indicate true or false condition
+ ax_compare_version=false
+
+ # Convert the two version strings to be compared into a format that
+ # allows a simple string comparison. The end result is that a version
+ # string of the form 1.12.5-r617 will be converted to the form
+ # 0001001200050617. In other words, each number is zero padded to four
+ # digits, and non digits are removed.
+ AS_VAR_PUSHDEF([A],[ax_compare_version_A])
+ A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
+ -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/[[^0-9]]//g'`
+
+ AS_VAR_PUSHDEF([B],[ax_compare_version_B])
+ B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
+ -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/[[^0-9]]//g'`
+
+ dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary
+ dnl # then the first line is used to determine if the condition is true.
+ dnl # The sed right after the echo is to remove any indented white space.
+ m4_case(m4_tolower($2),
+ [lt],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"`
+ ],
+ [gt],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"`
+ ],
+ [le],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"`
+ ],
+ [ge],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"`
+ ],[
+ dnl Split the operator from the subversion count if present.
+ m4_bmatch(m4_substr($2,2),
+ [0],[
+ # A count of zero means use the length of the shorter version.
+ # Determine the number of characters in A and B.
+ ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'`
+ ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'`
+
+ # Set A to no more than B's length and B to no more than A's length.
+ A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"`
+ B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"`
+ ],
+ [[0-9]+],[
+ # A count greater than zero means use only that many subversions
+ A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
+ B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
+ ],
+ [.+],[
+ AC_WARNING(
+ [illegal OP numeric parameter: $2])
+ ],[])
+
+ # Pad zeros at end of numbers to make same length.
+ ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`"
+ B="$B`echo $A | sed 's/./0/g'`"
+ A="$ax_compare_version_tmp_A"
+
+ # Check for equality or inequality as necessary.
+ m4_case(m4_tolower(m4_substr($2,0,2)),
+ [eq],[
+ test "x$A" = "x$B" && ax_compare_version=true
+ ],
+ [ne],[
+ test "x$A" != "x$B" && ax_compare_version=true
+ ],[
+ AC_WARNING([illegal OP parameter: $2])
+ ])
+ ])
+
+ AS_VAR_POPDEF([A])dnl
+ AS_VAR_POPDEF([B])dnl
+
+ dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE.
+ if test "$ax_compare_version" = "true" ; then
+ m4_ifvaln([$4],[$4],[:])dnl
+ m4_ifvaln([$5],[else $5])dnl
+ fi
+]) dnl AX_COMPARE_VERSION
diff --git a/m4/ax_python_devel.m4 b/m4/ax_python_devel.m4
index 92054e6..c6bf445 100644
--- a/m4/ax_python_devel.m4
+++ b/m4/ax_python_devel.m4
@@ -23,7 +23,7 @@
# version number. Don't use "PYTHON_VERSION" for this: that environment
# variable is declared as precious and thus reserved for the end-user.
#
-# This macro should work for all versions of Python >= 2.1.0. As an end
+# This macro should work fior all versions of Python >= 2.1.0. As an end
# user, you can disable the check for the python version by setting the
# PYTHON_NOVERSIONCHECK environment variable to something else than the
# empty string.
@@ -68,31 +68,31 @@
#serial 3
-AU_ALIAS([AC_PYTHON_DEVEL], [AX_PYTHON_DEVEL])
-AC_DEFUN([AX_PYTHON_DEVEL],[
+AU_ALIAS([AC_PYTHON_DEVEL_V2], [AX_PYTHON_DEVEL_V2])
+AC_DEFUN([AX_PYTHON_DEVEL_V2],[
#
# Allow the use of a (user set) custom python version
#
- AC_ARG_VAR([PYTHON_VERSION],[The installed Python
+ AC_ARG_VAR([PYTHON2_VERSION],[The installed Python
version to use, for example '2.3'. This string
will be appended to the Python interpreter
canonical name.])
- AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
- if test -z "$PYTHON"; then
- AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
- PYTHON_VERSION=""
+ AC_PATH_PROG([PYTHON2],[python[$PYTHON2_VERSION]])
+ if test -z "$PYTHON2"; then
+ AC_MSG_ERROR([Cannot find python$PYTHON2_VERSION in your system path])
+ PYTHON2_VERSION=""
fi
#
# Check for a version of Python >= 2.5.0
#
AC_MSG_CHECKING([for a version of Python >= '2.5.0'])
- ac_supports_python_ver=`$PYTHON -c "import sys; \
+ ac_supports_python_ver=`$PYTHON2 -c "import sys; \
ver = sys.version.split ()[[0]]; \
print (ver >= '2.5.0')"`
if test "$ac_supports_python_ver" != "True"; then
- if test -z "$PYTHON_NOVERSIONCHECK"; then
+ if test -z "$PYTHON2_NOVERSIONCHECK"; then
AC_MSG_RESULT([no])
AC_MSG_FAILURE([
This version of the AC@&t@_PYTHON_DEVEL macro
@@ -115,9 +115,9 @@ to something else than an empty string.
#
if test -n "$1"; then
AC_MSG_CHECKING([for a version of Python $1])
- ac_supports_python_ver=`$PYTHON -c "import sys; \
- ver = sys.version.split ()[[0]]; \
- print (ver $1)"`
+ ac_supports_python_ver=`$PYTHON2 -c "import sys; \
+ ver = sys.version.split()[[0]]; \
+ print (ver >= '$1')"`
if test "$ac_supports_python_ver" = "True"; then
AC_MSG_RESULT([yes])
else
@@ -127,7 +127,7 @@ If you have it installed, but it isn't the default Python
interpreter in your system path, please pass the PYTHON_VERSION
variable to configure. See ``configure --help'' for reference.
])
- PYTHON_VERSION=""
+ PYTHON2_VERSION=""
fi
fi
@@ -135,7 +135,7 @@ variable to configure. See ``configure --help'' for reference.
# Check if you have distutils, else fail
#
AC_MSG_CHECKING([for the distutils Python package])
- ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
+ ac_distutils_result=`$PYTHON2 -c "import distutils" 2>&1`
if test -z "$ac_distutils_result"; then
AC_MSG_RESULT([yes])
else
@@ -143,32 +143,32 @@ variable to configure. See ``configure --help'' for reference.
AC_MSG_ERROR([cannot import Python module "distutils".
Please check your Python installation. The error was:
$ac_distutils_result])
- PYTHON_VERSION=""
+ PYTHON2_VERSION=""
fi
#
# Check for Python include path
#
AC_MSG_CHECKING([for Python include path])
- if test -z "$PYTHON_CPPFLAGS"; then
- python_path=`$PYTHON -c "import distutils.sysconfig; \
+ if test -z "$PYTHON2_CPPFLAGS"; then
+ python2_path=`$PYTHON2 -c "import distutils.sysconfig; \
print (distutils.sysconfig.get_python_inc ());"`
- if test -n "${python_path}"; then
- python_path="-I$python_path"
+ if test -n "${python2_path}"; then
+ python2_path="-I$python2_path"
fi
- PYTHON_CPPFLAGS=$python_path
+ PYTHON2_CPPFLAGS=$python2_path
fi
- AC_MSG_RESULT([$PYTHON_CPPFLAGS])
- AC_SUBST([PYTHON_CPPFLAGS])
+ AC_MSG_RESULT([$PYTHON2_CPPFLAGS])
+ AC_SUBST([PYTHON2_CPPFLAGS])
#
# Check for Python library path
#
AC_MSG_CHECKING([for Python library path])
- if test -z "$PYTHON_LDFLAGS"; then
+ if test -z "$PYTHON2_LDFLAGS"; then
# (makes two attempts to ensure we've got a version number
# from the interpreter)
- ac_python_version=`cat<]],
@@ -316,7 +316,7 @@ EOD`
for your distribution. The exact name of this package varies among them.
============================================================================
])
- PYTHON_VERSION=""
+ PYTHON2_VERSION=""
fi
#
diff --git a/m4/ax_python_devel_v3.m4 b/m4/ax_python_devel_v3.m4
new file mode 100644
index 0000000..e770632
--- /dev/null
+++ b/m4/ax_python_devel_v3.m4
@@ -0,0 +1,325 @@
+# ===========================================================================
+# http://www.nongnu.org/autoconf-archive/ax_python_devel.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_PYTHON_DEVEL([version])
+#
+# DESCRIPTION
+#
+# Note: Defines as a precious variable "PYTHON_VERSION". Don't override it
+# in your configure.ac.
+#
+# This macro checks for Python and tries to get the include path to
+# 'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS)
+# output variables. It also exports $(PYTHON_EXTRA_LIBS) and
+# $(PYTHON_EXTRA_LDFLAGS) for embedding Python in your code.
+#
+# You can search for some particular version of Python by passing a
+# parameter to this macro, for example ">= '2.3.1'", or "== '2.4'". Please
+# note that you *have* to pass also an operator along with the version to
+# match, and pay special attention to the single quotes surrounding the
+# version number. Don't use "PYTHON_VERSION" for this: that environment
+# variable is declared as precious and thus reserved for the end-user.
+#
+# This macro should work for all versions of Python >= 2.1.0. As an end
+# user, you can disable the check for the python version by setting the
+# PYTHON_NOVERSIONCHECK environment variable to something else than the
+# empty string.
+#
+# If you need to use this macro for an older Python version, please
+# contact the authors. We're always open for feedback.
+#
+# LICENSE
+#
+# Copyright (c) 2009 Sebastian Huber
+# Copyright (c) 2009 Alan W. Irwin
+# Copyright (c) 2009 Rafael Laboissiere
+# Copyright (c) 2009 Andrew Collier
+# Copyright (c) 2009 Matteo Settenvini
+# Copyright (c) 2009 Horst Knorr
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see .
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 3
+
+AU_ALIAS([AC_PYTHON_DEVEL_V3], [AX_PYTHON_DEVEL_V3])
+AC_DEFUN([AX_PYTHON_DEVEL_V3],[
+ #
+ # Allow the use of a (user set) custom python version
+ #
+ AC_ARG_VAR([PYTHON2_VERSION],[The installed Python
+ version to use, for example '2.3'. This string
+ will be appended to the Python interpreter
+ canonical name.])
+
+ AC_PATH_PROG([PYTHON3],[python[$PYTHON3_VERSION]])
+ if test -z "$PYTHON3"; then
+ AC_MSG_ERROR([Cannot find python$PYTHON3_VERSION in your system path])
+ PYTHON3_VERSION=""
+ fi
+
+ #
+ # Check for a version of Python >= 2.5.0
+ #
+ AC_MSG_CHECKING([for a version of Python >= '2.5.0'])
+ ac_supports_python_ver=`$PYTHON3 -c "import sys; \
+ ver = sys.version.split ()[[0]]; \
+ print (ver >= '2.5.0')"`
+ if test "$ac_supports_python_ver" != "True"; then
+ if test -z "$PYTHON3_NOVERSIONCHECK"; then
+ AC_MSG_RESULT([no])
+ AC_MSG_FAILURE([
+This version of the AC@&t@_PYTHON_DEVEL macro
+doesn't work properly with versions of Python before
+2.1.0. You may need to re-run configure, setting the
+variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG,
+PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
+Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
+to something else than an empty string.
+])
+ else
+ AC_MSG_RESULT([skip at user request])
+ fi
+ else
+ AC_MSG_RESULT([yes])
+ fi
+
+ #
+ # if the macro parameter ``version'' is set, honour it
+ #
+ if test -n "$1"; then
+ AC_MSG_CHECKING([for a version of Python $1])
+ ac_supports_python_ver=`$PYTHON3 -c "import sys; \
+ ver = sys.version.split()[[0]]; \
+ print (ver >= '$1')"`
+ if test "$ac_supports_python_ver" = "True"; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ AC_MSG_ERROR([this package requires Python $1.
+If you have it installed, but it isn't the default Python
+interpreter in your system path, please pass the PYTHON_VERSION
+variable to configure. See ``configure --help'' for reference.
+])
+ PYTHON3_VERSION=""
+ fi
+ fi
+
+ #
+ # Check if you have distutils, else fail
+ #
+ AC_MSG_CHECKING([for the distutils Python package])
+ ac_distutils_result=`$PYTHON3 -c "import distutils" 2>&1`
+ if test -z "$ac_distutils_result"; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ AC_MSG_ERROR([cannot import Python module "distutils".
+Please check your Python installation. The error was:
+$ac_distutils_result])
+ PYTHON3_VERSION=""
+ fi
+
+ #
+ # Check for Python include path
+ #
+ AC_MSG_CHECKING([for Python include path])
+ if test -z "$PYTHON3_CPPFLAGS"; then
+ python_path=`$PYTHON3 -c "import distutils.sysconfig; \
+ print (distutils.sysconfig.get_python_inc ());"`
+ if test -n "${python_path}"; then
+ python_path="-I$python_path"
+ fi
+ PYTHON3_CPPFLAGS=$python_path
+ fi
+ AC_MSG_RESULT([$PYTHON3_CPPFLAGS])
+ AC_SUBST([PYTHON3_CPPFLAGS])
+
+ #
+ # Check for Python library path
+ #
+ AC_MSG_CHECKING([for Python library path])
+ if test -z "$PYTHON3_LDFLAGS"; then
+ # (makes two attempts to ensure we've got a version number
+ # from the interpreter)
+ ac_python_version=`cat<]],
+ [[Py_Initialize();]])
+ ],[pythonexists=yes],[pythonexists=no])
+ AC_LANG_POP([C])
+ # turn back to default flags
+ CPPFLAGS="$ac_save_CPPFLAGS"
+ LIBS="$ac_save_LIBS"
+
+ AC_MSG_RESULT([$pythonexists])
+
+ if test ! "x$pythonexists" = "xyes"; then
+ AC_MSG_FAILURE([
+ Could not link test program to Python. Maybe the main Python library has been
+ installed in some non-standard library path. If so, pass it to configure,
+ via the LDFLAGS environment variable.
+ Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib"
+ ============================================================================
+ ERROR!
+ You probably have to install the development version of the Python package
+ for your distribution. The exact name of this package varies among them.
+ ============================================================================
+ ])
+ PYTHON3_VERSION=""
+ fi
+
+ #
+ # all done!
+ #
+])
diff --git a/proto/IBus.proto b/proto/IBus.proto
new file mode 100644
index 0000000..05a16e1
--- /dev/null
+++ b/proto/IBus.proto
@@ -0,0 +1,61 @@
+syntax = "proto3";
+
+package IBus;
+
+enum MessageType {
+ MSG_UNDEF = 0;
+ MSG_INIT = 1;
+ MSG_ACK = 2;
+ MSG_EOT = 3;
+ MSG_STATUS = 4;
+ MSG_RESUME = 5;
+ MSG_NAK = 6;
+}
+
+enum StatusType {
+ STATUS_UNDEF = 0;
+ STATUS_OK = 1;
+ STATUS_NOT_FOUND = 2;
+}
+
+enum ClientType {
+ CLIENT_UNDEF = 0;
+ CLIENT_DUMB = 1;
+}
+
+message Type {
+ MessageType msgType = 1; // message type
+ string id = 2; // client identifier
+}
+
+// Initial message
+message InitMsg {
+ MessageType msgType = 1; // msgType=MSG_INIT
+ string id = 2; // client identifier
+ ClientType clientType = 3; // client type
+ uint64 ts = 4; // start time with historical=True, ts=0 means "everything"
+ bool live = 5; // goes live after historical (or immediately)
+ bool historical = 6; // request historical, makes startTime meaningful
+ bool reset = 7; // start afresh, deleting previous client information if any
+}
+
+// Packet acknowledged message
+message AckMsg {
+ MessageType msgType = 1; // msgType=MSG_ACK
+ string id = 2; // client identifier
+ uint64 ts = 3; // represents the acknowledged timestamp
+}
+
+// End-of-transmission message
+message EotMsg {
+ MessageType msgType = 1; // msgType=MSG_EOT
+ string id = 2; // client identifier
+}
+
+// Status message
+message StatusMsg {
+ MessageType msgType = 1; // msgType=MSG_STATUS
+ string id = 2; // client identifier
+ StatusType status = 3; // status
+}
+
diff --git a/proto/OBus.proto b/proto/OBus.proto
new file mode 100644
index 0000000..f93e3c6
--- /dev/null
+++ b/proto/OBus.proto
@@ -0,0 +1,215 @@
+syntax="proto3";
+
+package OBus;
+
+option go_package = ".;service";
+option java_package = "com.ses.grpc.obus";
+
+// Not implemented.
+service FleetTMControlService {
+ rpc LoadReferenceLimits (Satellite) returns (Empty){}
+ rpc SelectOverlay (Overlay) returns (Empty){}
+ rpc SubmitLimitUpdate (LimitUpdate) returns (Empty){}
+}
+
+// FleetTMService provides (streaming) functions to retrieve telemetry incl. limit information.
+service FleetTMService {
+ // Waits for an update and returns the sample of the requested mnemonic or pid.
+ // Set requestCurrentValue to True in the request to return the current value instead.
+ rpc GetTelemetrySample (TelemetrySampleRequest) returns (TelemetrySample){}
+ // Streams sample updates of the subscribed mnemonics or pids.
+ // Set requestCurrentValue to True in the request to return the current values at the beginning.
+ // During runtime, the clients must keep the subscription thread running and update subscriptions as necessary.
+ rpc GetTelemetrySamples (stream TelemetryStreamRequest) returns (stream TelemetrySamples){}
+ // Returns the current value table (CVT) of all known samples.
+ rpc GetTelemetryCvt (TelemetryCvtRequest) returns (TelemetrySamples){}
+
+ // Returns the current value table (CVT) of all known samples with limitVal > INFO.
+ rpc GetLimitCvt (TelemetryCvtRequest) returns (TelemetrySamples){}
+ // Streams sample updates where limit information is changing.
+ rpc GetLimitChanges (LimitStreamRequest) returns (stream TelemetrySamples){}
+
+ // Not implemented.
+ rpc GetLimitDefinition (TelemetrySampleRequest) returns (LimitDefinition){}
+ rpc GetLimitDefinitions (stream TelemetryStreamRequest) returns (stream LimitDefinitions){}
+
+ // Returns the status of available TM streams.
+ // A stream is flagged as stalled after 5 seconds of inactivity.
+ rpc GetTelemetryStatus(TelemetryStatusRequest) returns (TelemetryStatus){}
+}
+
+enum STATEV {
+ VALID = 0;
+ INVALID = 1;
+ CRC_ERROR = 2;
+ INVALID_AND_CRC_ERROR = 3;
+ EXPIRED = 4;
+ INVALID_AND_EXPIRED = 5;
+ CRC_ERROR_AND_EXPIRED = 6;
+ INVALID_AND_CRC_ERROR_AND_EXPIRED = 7;
+}
+
+enum TM_TYPE {
+ UNKNOWN = 0;
+ DOUBLE = 1;
+ LONG = 2;
+ STRING = 3;
+ UNSIGNED_LONG = 4;
+}
+
+enum ERROR_CODES {
+ NONE = 0;
+ NOT_FOUND = 1;
+}
+
+enum LIMIT {
+ NORMAL = 0;
+ INFO = 1;
+ WARNING = 2;
+ HAZARDOUS = 3;
+ CRITICAL = 4;
+ OOR = 5;
+}
+
+message TelemetrySampleRequest {
+ string satelliteName = 1; // Mandatory
+ string seatName = 2; // Leave empty for real S/C
+ string mnemonic = 3; // Mandatory if pid is not set
+ bool requestCurrentValue = 4; // Default: False
+ uint32 pid = 5; // Mandatory if mnemonic is not set
+}
+
+message TelemetryStreamRequest {
+ string satelliteName = 1; // Mandatory
+ string seatName = 2; // Leave empty for real S/C
+ // (subscribeMnemonics /\ unsubscribeMnemonics != {}) => (subscribePids /\ unsubscribePids == {})
+ repeated string subscribeMnemonics = 3;
+ repeated string unsubscribeMnemonics = 4;
+ bool requestCurrentValue = 5; // Default: False
+ // (subscribePids /\ unsubscribePids != {}) => (subscribeMnemonics /\ unsubscribeMnemonics == {})
+ repeated uint32 subscribePids = 6;
+ repeated uint32 unsubscribePids = 7;
+}
+
+message TelemetryCvtRequest {
+ string satelliteName = 1; // Mandatory
+ string seatName = 2; // Leave empty for real S/C
+}
+
+message LimitStreamRequest {
+ string satelliteName = 1; // Mandatory
+ string seatName = 2; // Leave empty for real S/C
+}
+
+message TelemetryStatusRequest {
+}
+
+message TelemetrySamples {
+ repeated TelemetrySample samples = 1;
+}
+
+message AnalogLimit {
+ uint32 limitSet = 1;
+ uint32 hysteresis = 2;
+ double low = 3;
+ double high = 4;
+ LIMIT level = 5;
+ string conditionName = 6;
+ string conditionAlgo = 7;
+ int64 version = 8;
+}
+
+message StatusLimit {
+ uint32 limitSet = 1;
+ uint32 hysteresis = 2;
+ int64 limitVal = 3;
+ LIMIT level = 4;
+ string conditionName = 5;
+ string conditionAlgo = 6;
+ int64 version = 7;
+}
+
+message LimitDefinition {
+ repeated string mnemonic = 1;
+ map entries = 2;
+}
+
+message LimitDefinitions {
+ repeated LimitDefinition definitions = 1;
+}
+
+message LimitDefinitionEntry {
+ uint64 limitTS = 1;
+ string overlayName = 2;
+
+ oneof LimitValues {
+ AnalogLimit analogLimit = 3;
+ StatusLimit statusLimit = 4;
+ }
+}
+
+message TelemetrySample {
+ repeated string mnemonic = 1;
+ uint64 onboardTS = 2;
+ uint64 groundTS = 3;
+ double engV = 4;
+ int64 rawV = 5;
+ string calV = 6;
+ STATEV stateV = 7;
+ int32 strmID = 8;
+ int32 pktID = 9;
+ ERROR_CODES error = 10;
+ TM_TYPE tmType = 11;
+ oneof LimitValues {
+ AnalogLimit analogLimit = 12;
+ StatusLimit statusLimit = 13;
+ }
+ uint32 pid = 14;
+}
+
+message Empty {
+}
+
+message Overlay {
+ string satelliteName = 1;
+ string overlayName = 2;
+}
+
+message Satellite {
+ string satelliteName = 1;
+ string seatName = 2;
+}
+
+message LimitUpdate {
+ message AnalogLimit {
+ }
+ message StatusLimit {
+ }
+ string satelliteName = 1;
+ string mnemonic = 2;
+ repeated AnalogLimit updatedAnalogLimit = 3;
+ repeated StatusLimit updatedStatusLimit = 4;
+}
+
+message Reply {
+ enum RETURN_CODE {
+ SUCCESS = 0;
+ ERROR = 1;
+ }
+ RETURN_CODE errorCode = 1;
+}
+
+message TelemetryStreamInfo {
+ enum STREAM_STATUS {
+ NORMAL = 0;
+ STALLED = 1; // No updates within 5 seconds
+ }
+ string satelliteName = 1;
+ string seatName = 2;
+ STREAM_STATUS status = 3;
+ uint64 time = 4; // Last known reception time
+}
+
+message TelemetryStatus {
+ repeated TelemetryStreamInfo info = 1;
+}
diff --git a/proto/SpacecraftInfo.proto b/proto/SpacecraftInfo.proto
new file mode 100644
index 0000000..1af4727
--- /dev/null
+++ b/proto/SpacecraftInfo.proto
@@ -0,0 +1,8 @@
+syntax = "proto3";
+
+message SpacecraftInfo {
+ uint32 msgType = 1;
+ uint32 scID = 2;
+ uint64 period = 3; // time between two frames at highest speed (nanoseconds)
+ uint32 totalFrames = 4; // number of minor frames in a major frame
+}
diff --git a/proto/TelemetryFrame.proto b/proto/TelemetryFrame.proto
new file mode 100644
index 0000000..fd365a0
--- /dev/null
+++ b/proto/TelemetryFrame.proto
@@ -0,0 +1,57 @@
+syntax = "proto3";
+
+message TelemetryPacket {
+ uint32 vcID = 1;
+ uint32 apID = 2;
+ uint32 sequenceCounter = 3;
+ uint32 length = 4;
+ bool pecfValid = 5;
+ bool pusHeader = 6;
+ uint32 pusService = 7;
+ uint32 pusSubservice = 8;
+ uint32 destination = 9;
+ uint32 subCounter = 10;
+ uint64 onboardTS = 11;
+ bytes rawPacket = 100;
+}
+
+message TelemetryPoint {
+ uint32 pID = 1;
+ uint64 onboardTS = 2;
+ double engV = 3;
+ int64 rawV = 4;
+ string calV = 5;
+
+ enum STATEV {
+ VALID = 0;
+ INVALID = 1;
+ CRC_ERROR = 2;
+ INVALID_AND_CRC_ERROR = 3;
+ EXPIRED = 4;
+ INVALID_AND_EXPIRED = 5;
+ CRC_ERROR_AND_EXPIRED = 6;
+ INVALID_AND_CRC_ERROR_AND_EXPIRED = 7;
+ }
+
+ STATEV stateV = 6;
+ int32 pktID = 7;
+}
+
+message TelemetryFrame {
+ uint32 msgType = 1;
+ uint32 scID = 2;
+
+ enum STREAMID {
+ STREAM1 = 0;
+ STREAM2 = 1;
+ }
+
+ STREAMID streamID = 3;
+ uint32 frameCounter = 4;
+ uint64 groundTS = 5;
+ uint32 familyID = 6;
+
+ repeated bytes rawFrame = 98;
+ repeated TelemetryPacket packet = 99;
+ repeated TelemetryPoint point = 100;
+}
diff --git a/proto/TelemetryFrameLt.proto b/proto/TelemetryFrameLt.proto
new file mode 100644
index 0000000..10249be
--- /dev/null
+++ b/proto/TelemetryFrameLt.proto
@@ -0,0 +1,16 @@
+syntax = "proto3";
+
+message TelemetryFrame {
+ uint32 msgType = 1;
+ uint32 scID = 2;
+
+ enum STREAMID {
+ STREAM1 = 0;
+ STREAM2 = 1;
+ }
+
+ STREAMID streamID = 3;
+ uint32 frameCounter = 4;
+ uint64 groundTS = 5;
+ uint32 familyID = 6;
+}
diff --git a/proto/alerts.proto b/proto/alerts.proto
new file mode 100644
index 0000000..42d66ac
--- /dev/null
+++ b/proto/alerts.proto
@@ -0,0 +1,31 @@
+syntax = "proto3";
+
+import "header.proto";
+
+package Alerts;
+
+enum SeverityType {
+ SEV_NORMAL = 0;
+ SEV_INFO = 1;
+ SEV_WARNING = 2;
+ SEV_HAZARDOUS = 3;
+ SEV_CRITICAL = 4;
+};
+
+message Alert {
+ string machineName = 1; // short name (lowercase) of the machine (p1anal01, p1cntl, opsb-ses10tec1, etc.)
+ uint64 eventTS = 2; // timestamp of the event, represents the number of Nano-seconds since Unix epoch
+ string appName = 3; // identifier of the application that generated the message
+ SeverityType severity = 4; // severity of the alert (refer to SeverityType definition)
+ string label = 5; // sentence to describe the alert, one line (no linefeed)
+ string eventData = 6; // additional data as per application defined pattern (no free text, strict template to be published)
+};
+
+message Item {
+ Messages.Header header = 1;
+
+ oneof these {
+ Alert alert = 8;
+ };
+};
+
diff --git a/proto/header.proto b/proto/header.proto
new file mode 100644
index 0000000..873a3dd
--- /dev/null
+++ b/proto/header.proto
@@ -0,0 +1,12 @@
+syntax = "proto3";
+
+package Messages;
+
+message Header {
+ string topic = 1; // topic identifier
+ uint64 publisherID = 2; // unique identifier of the publisher, 0 if not publishing
+ uint32 scID = 3; // satellite identifier as per SATDB
+ uint32 familyID = 4; // family identifier as per SATDB
+ string key = 5; // key
+};
+
diff --git a/proto/limits.proto b/proto/limits.proto
new file mode 100644
index 0000000..895cc7f
--- /dev/null
+++ b/proto/limits.proto
@@ -0,0 +1,28 @@
+syntax = "proto3";
+
+package Limits;
+
+import "header.proto";
+
+message DefinitionUpdate {
+ string url = 1; // URL of the new overlay or reference database
+ string filename = 2; // filename, e.g. main
+ uint32 version = 3; // version number
+ uint32 scID = 4; // SCID as per SATDB
+ uint64 ts = 5; // update timestamp
+};
+
+message Fileset {
+ uint64 ts = 1; // update timestamp
+ repeated string urls = 2; // Ordered list of URLs of the databases
+};
+
+message Item {
+ Messages.Header header = 1;
+
+ oneof these {
+ DefinitionUpdate limit_definition_update = 6;
+ Fileset fileset = 7;
+ };
+};
+
diff --git a/proto/messages.proto b/proto/messages.proto
new file mode 100644
index 0000000..b22af4c
--- /dev/null
+++ b/proto/messages.proto
@@ -0,0 +1,24 @@
+syntax = "proto3";
+
+import "header.proto";
+import "alerts.proto";
+import "limits.proto";
+import "msgbus.proto";
+
+package Messages;
+
+message Item {
+ Header header = 1;
+
+ oneof these {
+ MsgBus.CreateNewTopic newtopic = 2;
+ MsgBus.RequestValues request_values = 3;
+ MsgBus.KeyList keylist = 4;
+ MsgBus.Status status = 5;
+ Limits.DefinitionUpdate limit_definition_update = 6;
+ Limits.Fileset fileset = 7;
+ Alerts.Alert alert = 8;
+ MsgBus.RequestType request = 9;
+ };
+};
+
diff --git a/proto/msgbus.proto b/proto/msgbus.proto
new file mode 100644
index 0000000..70e4fb7
--- /dev/null
+++ b/proto/msgbus.proto
@@ -0,0 +1,47 @@
+syntax = "proto3";
+
+import "header.proto";
+
+package MsgBus;
+
+enum StatusType {
+ STATUS_UNDEF = 0; // DO NOT USE
+ STATUS_TOPIC_NOT_FOUND = 2;
+ STATUS_KEY_NOT_FOUND = 3;
+ STATUS_EOT = 4;
+};
+
+enum RequestType {
+ REQ_KEYLIST = 0;
+}
+
+message KeyList {
+ repeated string keys = 1; // key list
+};
+
+message Status {
+ StatusType status = 1;
+ string info = 2;
+};
+
+// Topic creation
+message CreateNewTopic {
+ uint32 queueSize = 1; // retention size (1 for last value only, more for history)
+};
+
+// Request value(s) from a topic
+message RequestValues {
+ repeated string keys = 1; // keys
+};
+
+message Item {
+ Messages.Header header = 1;
+
+ oneof these {
+ CreateNewTopic newtopic = 2;
+ RequestValues request_values = 3;
+ KeyList keylist = 4;
+ Status status = 5;
+ RequestType request = 9;
+ };
+};
diff --git a/proto/tmt.proto b/proto/tmt.proto
new file mode 100644
index 0000000..a4bdb68
--- /dev/null
+++ b/proto/tmt.proto
@@ -0,0 +1,139 @@
+syntax = "proto3";
+
+package tmtdata;
+
+option java_package = "com.ses.tmt.data.codec.protoc";
+option java_outer_classname = "TmTProtocCodec";
+
+enum MessageType {
+ UNDEF_TYPE = 0;
+ REQ = 1;
+ DATA = 2;
+ END = 3;
+ HBEAT = 4;
+ JOIN = 5;
+ PROCESSING_DONE = 6;
+ RECONNECT = 7;
+}
+
+enum STATEV {
+ VALID = 0;
+ INVALID = 1;
+ CRC_ERROR = 2;
+ INVALID_AND_CRC_ERROR = 3;
+ EXPIRED = 4;
+ INVALID_AND_EXPIRED = 5;
+ CRC_ERROR_AND_EXPIRED = 6;
+ INVALID_AND_CRC_ERROR_AND_EXPIRED = 7;
+}
+
+enum ErrorCode {
+ UNDEF_ERROR = 0;
+ NO_ERROR = 1;
+ UNKNOWN_SAT = 2;
+ UNKNOWN_SEAT = 3;
+ MAX_PIDS_EXCEEDED = 4;
+ INVALID_PID = 5;
+ START_AFTER_END = 6;
+ START_AFTER_NOW = 7;
+ WRONG_LEVELID = 8;
+ INVALID_PROTOCOL = 9;
+ SERVER_ERROR = 10;
+ HBEAT_TIMEOUT = 11;
+ BAD_REQUEST = 12;
+ CANCELED = 13;
+ REQUEST_EXPIRED = 14;
+ UNKNOWN_SAT_DRIVER_MAPPING = 15;
+}
+
+enum ReqCode {
+ NO_REQ_CODE = 0;
+ NO_UPDATE_VALUE = 1;
+ INITIAL_VALUES = 2;
+ INITIAL_VALUES_VALID = 3;
+}
+
+enum LIMIT {
+ NORMAL = 0;
+ INFO = 1;
+ WARNING = 2;
+ HAZARDOUS = 3;
+ CRITICAL = 4;
+ OOR = 5;
+}
+
+message Header {
+ MessageType msgType = 1;
+}
+
+message ReadyWorker {
+ string workerName = 1;
+ string workerHost = 2;
+ string workerState = 3;
+ string workerData = 4;
+ string workerRequest = 5;
+ string workerHb = 6;
+}
+
+message ProcessingDone {
+ string workerName = 1;
+ string clientId = 2;
+}
+
+message HeartBeat {
+ string workerName = 1;
+ uint32 hbCount = 2;
+ float cpuLoad = 3;
+}
+
+message HisRequest {
+ string satName = 1;
+ string seatName = 2;
+ ReqCode reqCode = 3;
+ repeated uint32 pids = 4;
+ int64 startTime = 5;
+ int64 endTime = 6;
+ int32 level = 7;
+ bool withOol = 8;
+ bool withRaw = 9;
+}
+
+message End {
+ ErrorCode errorCode = 1;
+}
+
+message Ool {
+ LIMIT level = 1;
+ uint32 limitSet = 2;
+}
+
+message TmSample {
+ int64 rawV = 1;
+ double engV = 2;
+ Ool ool = 3;
+}
+
+message TmStats {
+ double mean = 1;
+ double min = 2;
+ double max = 3;
+}
+
+message TmData {
+ uint64 time = 1;
+ uint32 pid = 2;
+ STATEV stateV = 3;
+ oneof data {
+ TmSample tmSample = 4;
+ TmStats tmStats = 5;
+ }
+}
+
+message TmDataSet {
+ repeated TmData tmData = 1;
+}
+
+message TmDataSetPacket {
+ repeated TmDataSet tmDataSet = 1;
+}
+
diff --git a/protos/SPELLDriver.proto b/protos/SPELLDriver.proto
new file mode 100644
index 0000000..7b3d2f9
--- /dev/null
+++ b/protos/SPELLDriver.proto
@@ -0,0 +1,566 @@
+syntax = "proto3";
+
+package spell.driver;
+
+import "google/protobuf/empty.proto";
+import "google/protobuf/any.proto";
+import "google/protobuf/wrappers.proto";
+
+option java_multiple_files = true;
+option java_package = "lu.ses.engineering.spell.grpc.driver";
+option java_outer_classname = "SPELLDriverProto";
+option go_package = "driver";
+
+service SPELLDriverInterface {
+ rpc GetDriverInfo (DriverInfo) returns (DriverInfo);
+ rpc Ping (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Close (google.protobuf.Empty) returns (google.protobuf.Empty);
+}
+
+service SPELLDriverInterface_TM {
+ rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty);
+
+ rpc DatabaseLookup (LookupRequest) returns (LookupAnswer);
+ //Load a set of limits definitions for a given parameter, from a given file.
+ //
+ //param: telemetry parameter name
+ //limits: file with limit definitions
+ //config: configuration parameters
+ // returns True/False for Success
+// rpc LoadLimits (google.protobuf.Empty) returns (google.protobuf.BoolValue);
+ //Modify an Out Of Limits definition for a given telemetry parameter
+ //
+ //param: the telemetry parameter name
+ //limits: dictionary containing the limit parameters
+ //config: configuration dictionary with modifiers
+ //
+ //Relevant modifiers are:
+ //
+ //- Select=ACTIVE/ALL/: indicates which definitions should be affected
+ // (all, only the active ones, or the one indicated by
+ // the string)
+ //
+ //Limit parameters dictionary may contain the following:
+ //
+ //LoRed,LoYel,HiRed,HiYel: indicate the hard and soft limit values
+ //
+ //Midpoint,Tolerance: indicate a middle limit point and a tolerance that is
+ // used to calculate the upper and lower limits (M+T, M-T)
+ // Hard and soft limits are considered equal.
+ //
+ //Nominal,Earning,Error,Ignore: the values are lists containing the values
+ // assigned to each category, e.g. Nominal:['ValueA','ValueB']
+ //
+ //Delta: set a step or spike limit
+ rpc SetLimits (LimitSetRequest) returns (google.protobuf.BoolValue);
+ //Obtain an Out Of Limits definition for a given telemetry parameter
+ //
+ //param: the telemetry parameter name
+ //config: configuration dictionary with modifiers
+ //
+ //Relevant modifiers are:
+ //
+ //- Select=ACTIVE/ALL/: indicates which definitions should be considered
+ // (all, only the active ones, or the one indicated by
+ // the string)
+ //
+ //The limit definition to be returned may be one of the following:
+ //
+ //{LoRed,LoYel,HiRed,HiYel}: indicate the hard and soft limit values
+ //
+ //{Nominal,Earning,Error,Ignore}: the values are lists containing the values
+ // assigned to each category, e.g. Nominal:['ValueA','ValueB']
+ //
+ //{Delta}: step or spike limit
+ rpc GetLimits (TmItemValue) returns (LimitSet);
+ rpc IsAlarmed (TmItemValue) returns (google.protobuf.BoolValue);
+ //Inject a ground value for a TM parameter.
+ //
+ //tmItem : instance of TmItemClass with the parameter information
+ //value : contains the required value
+ //config : configuration dictionary with modifiers.
+ // returns True/False for success
+ rpc InjectItem (TmItemValue) returns (google.protobuf.BoolValue);
+ //Acquire the value for a TM parameter.
+ //
+ //tmItem : instance of TmItemClass with the parameter information
+ //config : configuration dictionary with modifiers.
+ //
+ //Relevant modifiers are
+ //
+ //- Wait=True/False: when True, the system shall block the caller until
+ //a new sample of the required parameter arrives to the GCS. If False,
+ //the last recorded value of the parameter shall be returned immediately.
+ //
+ //- ValueFormat=RAW/ENG: if RAW is given, the raw or uncalibrated value
+ //of the parameter shall be given. If ENG is used, the engineering or
+ //calibrated value shall be returned.
+ //
+ //- Timeout=(TIME): maximum amount of time to wait for new samples,
+ //before the parameter is declared as impossible to acquire. It only
+ //makes sense when Wait=True.
+ //
+ //Returned value: a list with the value and True/False indicating the validity
+ //of the parameter
+ rpc RefreshItem (TmItemValue) returns (TmItemValue);
+ rpc RestoreNormalLimits (google.protobuf.Any) returns (google.protobuf.BoolValue);
+ //Instantiate a telemetry parameter (usually taking the information from GCS)
+ //
+ //The item shall be derived from TmItemClass class.
+ //
+ //If not overriden, the adapter class provides a generic TM item structure.
+ rpc CreateTmItem (TmItemDesc) returns (TmItemDesc);
+}
+
+
+message LookupRequest {
+ string name = 1;
+ string type = 2;
+ string source = 3;
+}
+
+message LookupAnswer {
+ google.protobuf.Any lookup = 1;
+}
+
+message LimitSetRequest {
+ TmItemDesc item = 1;
+ LimitSet set = 2;
+}
+
+message LimitSet {
+ google.protobuf.Any limitset = 1;
+}
+
+message TmItemValue {
+ TmItemDesc item = 1;
+ bool validity = 3;
+ google.protobuf.Any engValue = 4;
+ google.protobuf.Any rawValue = 5;
+ string timestamp = 6;
+ google.protobuf.Any config = 7;
+}
+
+message TmItemDesc {
+ string mnemonic = 1;
+ string description = 2;
+ string id = 3;
+}
+
+service SPELLDriverInterface_TC {
+ rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty);
+
+ rpc CreateTcItem (TcItemDesc) returns (TcItemDesc);
+
+ //Inject a block of TC items into the GCS. Blocked items are injected
+ //and transmitted as a single TC frame.
+ //
+ //tcItemList : list of TcItemClass instance with the command information.
+ //config : configuration dictionary
+ rpc SendBlock (CommandList) returns (google.protobuf.BoolValue);
+ //Inject a group of TC items into the GCS.
+ //
+ //tcItemList : list of TcItemClass instance with the command information.
+ //config : configuration dictionary
+ rpc SendList (CommandList) returns (google.protobuf.BoolValue);
+ //Inject a TC item into the GCS.
+ //
+ //tcItem : TcItemClass instance with the command information.
+ //config : configuration dictionary
+ rpc SendCommand (CommandDesc) returns (google.protobuf.BoolValue);
+
+// rpc CheckCriticalCommands (google.protobuf.Empty) returns (google.protobuf.Empty);
+
+}
+
+message CommandList {
+ repeated CommandDesc commands = 1;
+ google.protobuf.Any config = 2;
+}
+
+message TcItemDesc {
+ string mnemonic = 1;
+ string description = 2;
+ string id = 3;
+}
+
+message CommandDesc {
+ TcItemDesc command = 1;
+ google.protobuf.Any args = 2;
+ google.protobuf.Any config = 3;
+}
+
+service SPELLDriverInterface_EV {
+ rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty);
+ // Invoked by the system in order to inject an event into the GCS.
+ //
+ // message: string containing the event message
+ // config: dictionary containing the event parameters:
+ // - Severity modifier (INFORMATION/WARNING/ERROR/FATAL)
+ // - Scope (SCOPE_PROC,SCOPE_SYS,SCOPE_CFG)
+ rpc RaiseEvent (Event) returns (google.protobuf.Empty);
+ //NOT USED AT THE MOMENT!
+ rpc RegisterForEvents (google.protobuf.Empty) returns (stream google.protobuf.Empty);
+ //NOT USED AT THE MOMENT!
+ rpc UnRegisterForEvents (google.protobuf.Empty) returns (google.protobuf.Empty);
+ //NOT USED AT THE MOMENT!
+ rpc PullEvents (google.protobuf.Empty) returns (google.protobuf.Empty);
+}
+
+message Event {
+ string message = 1;
+ google.protobuf.Any config = 2;
+}
+
+service SPELLDriverInterface_PCS {
+ rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty);
+
+ rpc CreatePtcItem (PtcItemDesc) returns (PtcItemDesc);
+
+ rpc PCS_GetStatus (google.protobuf.Any) returns (google.protobuf.Any);
+ rpc PCS_IsArqEnabled (google.protobuf.Any) returns (google.protobuf.BoolValue);
+ rpc PCS_IsVerifyModeEnabled (google.protobuf.Any) returns (google.protobuf.BoolValue);
+ rpc PCS_ReadyToCommand (google.protobuf.Any) returns (google.protobuf.StringValue);
+ rpc PCS_AbortPtc (google.protobuf.Any) returns (google.protobuf.BoolValue);
+
+ rpc SendPtcCommand (PtcDesc) returns (PtcResult);
+ rpc SendPtcList (PtcList) returns (PtcResult);
+ rpc PCS_Control (PtcDesc) returns (PtcResult);
+
+}
+message PtcItemDesc {
+ string mnemonic = 1;
+ string description = 2;
+ string id = 3;
+}
+message PtcList {
+ repeated PtcDesc commands = 1;
+ google.protobuf.Any config = 2;
+}
+
+message PtcDesc {
+ PtcItemDesc command = 1;
+ google.protobuf.Any args = 2;
+ google.protobuf.Any config = 3;
+}
+
+message PtcResult {
+ repeated int64 code = 1;
+ repeated bool success = 2;
+ repeated string stage = 3;
+ repeated string data = 4;
+ repeated string error = 5;
+}
+
+service SPELLDriverInterface_MEM {
+ rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty);
+
+ rpc GenerateReport (MemoryReportRequest) returns (google.protobuf.BoolValue);
+ rpc CompareImages (CompareMemoryReportRequest) returns (google.protobuf.BoolValue);
+ rpc CreateGoldenImage (GoldenImageRequest) returns (google.protobuf.BoolValue);
+ rpc MemoryLookup (MemoryLookupRequest) returns (google.protobuf.Any);
+ rpc DataObjectLookup (DataObjectLookupRequest) returns (google.protobuf.Any);
+ rpc DataItemLookup (DataItemLookupRequest) returns (google.protobuf.Any);
+}
+
+message MemoryReportRequest {
+ string image = 1;
+ string report_type = 2;
+ string begin = 3;
+ string end = 4;
+ string source = 5;
+ google.protobuf.Any config = 6;
+}
+
+message CompareMemoryReportRequest {
+ string image1 = 1;
+ string image2 = 2;
+ string report_type = 3;
+ string begin = 4;
+ string end = 5;
+ string source = 6;
+ google.protobuf.Any config = 7;
+}
+
+message GoldenImageRequest {
+ string scp = 1;
+ string filename = 2;
+ google.protobuf.Any config = 3;
+}
+
+message MemoryLookupRequest {
+ string name = 1;
+ string address = 2;
+ string image = 3;
+ string report_type = 4;
+ string source = 5;
+ google.protobuf.Any config = 6;
+}
+
+message DataObjectLookupRequest {
+ string name = 1;
+ string type = 2;
+ google.protobuf.Any config = 3;
+}
+
+message DataItemLookupRequest {
+ string name = 1;
+ string type = 2;
+ string source = 3;
+ string valformat = 4;
+ google.protobuf.Any config = 5;
+}
+
+service SPELLDriverInterface_RSC {
+ rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty);
+
+ // Enable or disable a GCS link (TM, TC or others)
+ //
+ // name: link identifier
+ // enable: True/False, indicates if the link needs to be enabled or disabled
+ // config: configuration modifiers
+ rpc SetLink (LinkRequest) returns (google.protobuf.BoolValue);
+ // Check if a GCS link (TM, TC or others) is enabled or disabled
+ //
+ // name: link identifier
+ // config: configuration modifiers
+ rpc CheckLink (LinkRequest) returns (google.protobuf.BoolValue);
+ // Assign the value of one resource or configuration parameter in the GCS
+ //
+ // name: resource identifier
+ // value: resource value
+ // config: configuration modifiers
+ rpc SetResource (ResourceRequest) returns (google.protobuf.BoolValue);
+ // Acquire the value of one resource or configuration parameter in the GCS
+ //
+ // name: resource identifier
+ // config: configuration modifiers
+ rpc GetResource (ResourceRequest) returns (ResourceRequest);
+ // Acquire the name-value map of all resource or configuration parameters
+ // in the GCS
+ //
+ // name: resource identifier
+ // config: configuration modifiers
+ rpc GetResources (ResourcesRequest) returns (ResourcesRequest);
+ // Acquire the current status of one resource or configuration parameter
+ // in the GCS
+ //
+ // name: resource identifier
+ // config: configuration modifiers
+ rpc GetResourceStatus (ResourceRequest) returns (ResourceRequest);
+ // Check if the current value of one resource or configuration parameter
+ // in the GCS is correct or incorrect
+ //
+ // name: resource identifier
+ // config: configuration modifiers
+ rpc IsResourceOK (ResourceRequest) returns (google.protobuf.BoolValue);
+}
+
+message LinkRequest {
+ string name = 1;
+ bool status = 2;
+ google.protobuf.Any config = 3;
+}
+
+message ResourceRequest {
+ string name = 1;
+ google.protobuf.Any value = 2;
+ google.protobuf.Any config = 3;
+}
+
+message ResourcesRequest {
+ google.protobuf.Any value = 2;
+ google.protobuf.Any config = 3;
+}
+
+service SPELLDriverInterface_TASK {
+ rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty);
+ // Invoked by the system in order to stop a GCS task.
+ //
+ // name: string containing the task name
+ // config: configuration dictionary with modifiers.
+ rpc StartTask (Task) returns (google.protobuf.BoolValue);
+ // Invoked by the system in order to stop a GCS task.
+ //
+ // name: string containing the task name
+ // config: configuration dictionary with modifiers.
+ rpc StopTask (Task) returns (google.protobuf.BoolValue);
+ // Invoked by the system in order to check the status of a GCS task.
+ //
+ // name: string containing the task name
+ // config: configuration dictionary with modifiers.
+ rpc CheckTask (Task) returns (google.protobuf.Int32Value);
+ // Invoked by the system in order to open a telemetry display on the GCS
+ //
+ // displayName: name or identifier of the display
+ // config: configuration dictionary with modifiers.
+ //
+ // Relevant modifiers are:
+ //
+ // Host: the machine name where the display should be open.
+ rpc OpenDisplay (Display) returns (google.protobuf.Empty);
+ // Invoked by the system in order to print a telemetry display from the GCS
+ //
+ // displayName: name or identifier of the display
+ // config: configuration dictionary with modifiers.
+ //
+ // Relevant modifiers are:
+ //
+ // Printer: the printer name
+ // Format: PS (postcript) or VECTOR (ASCII text, for alphanumeric displays only)
+ rpc PrintDisplay (Display) returns (google.protobuf.Empty);
+ // Invoked by the system in order to close a telemetry display on the GCS
+ //
+ // displayName: name or identifier of the display
+ // config: configuration dictionary with modifiers.
+ //
+ // Relevant modifiers are:
+ //
+ // Host: the machine name where the display should be closed.
+ rpc CloseDisplay (Display) returns (google.protobuf.Empty);
+}
+
+message Task {
+ string name = 1;
+ google.protobuf.Any args = 2;
+ google.protobuf.Any config = 3;
+}
+
+message Display {
+ string name = 1;
+ google.protobuf.Any config = 2;
+}
+
+service SPELLDriverInterface_RNG {
+ rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty);
+
+ rpc EnableRanging (Ranging) returns (google.protobuf.BoolValue);
+ rpc DisableRanging (Ranging) returns (google.protobuf.BoolValue);
+ rpc AbortRanging (Ranging) returns (google.protobuf.BoolValue);
+ rpc StartRanging (Ranging) returns (google.protobuf.BoolValue);
+ rpc StartCalibration (Ranging) returns (google.protobuf.BoolValue);
+
+ rpc GetBasebandConfig (BaseBandConfig) returns (BaseBandConfig);
+ rpc SetBasebandConfig (BaseBandConfig) returns (google.protobuf.BoolValue);
+
+ rpc GetAntennaNames (google.protobuf.Any) returns (Names);
+ rpc GetRangingPaths (google.protobuf.Any) returns (Names);
+ rpc GetBasebandNames (google.protobuf.Any) returns (Names);
+ rpc GetRangingStatus (google.protobuf.Any) returns (google.protobuf.StringValue);
+ rpc UpdateCortexConf (google.protobuf.Any) returns (google.protobuf.BoolValue);
+}
+
+message Ranging {
+ string bbe = 1;
+ string antenna = 2;
+ google.protobuf.Any config = 3;
+}
+
+message BaseBandConfig {
+ string bbe = 1;
+ string param = 2;
+ string value = 4;
+ google.protobuf.Any config = 3;
+}
+
+message Names {
+ repeated string names = 1;
+}
+
+service SPELLDriverInterface_USER {
+ rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty);
+ // Login the given user in the GCS system.
+ //
+ // username: user name
+ // password: the user password
+ // config: configuration dictionary with modifiers.
+ rpc Login (LoginCred) returns (google.protobuf.BoolValue);
+ // Logout the given user from the GCS system.
+ //
+ // username: user name
+ // config: configuration dictionary with modifiers.
+ rpc Logout (LoginCred) returns (google.protobuf.BoolValue);
+ // Check if the given user is logged in the GCS system.
+ //
+ // username: user name
+ // config: configuration dictionary with modifiers.
+ rpc IsLoggedIn (LoginCred) returns (google.protobuf.BoolValue);
+}
+
+message LoginCred {
+ string username = 1;
+ string password = 2;
+ google.protobuf.Any config = 3;
+}
+
+service SPELLDriverInterface_TIME {
+ rpc Setup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Cleanup (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Interrupt (google.protobuf.Empty) returns (google.protobuf.Empty);
+ // Obtain the current UTC time according to the GCS time. If the present
+ // example is not change, the interface provices the current system local
+ // time.
+ //
+ // config: SPELL configuration dictionary.
+ rpc GetUTC (google.protobuf.Any) returns (Time);
+}
+
+message Interfaces {
+ // Dummy message just for the namespace
+ enum DriverInterface {
+ TM = 0;
+ TC = 1;
+ EV = 2;
+ PCS = 3;
+ MEM = 4;
+ RSC = 5;
+ TASK = 6;
+ RNG = 7;
+ USER = 8;
+ CONFIG = 9;
+ TIME = 10;
+ }
+}
+
+message DriverInfo {
+ string host = 1;
+ uint32 port = 2;
+ string driverName = 3;
+ repeated Interfaces.DriverInterface interfaces = 4;
+}
+
+message List {
+ repeated google.protobuf.Any entries = 1;
+}
+
+message Dict {
+ repeated DictEntry entries = 1;
+}
+
+message Time {
+ string timeMsg = 1;
+}
+
+message DictEntry {
+ google.protobuf.Any key = 1;
+ google.protobuf.Any value = 2;
+}
diff --git a/protos/SPELLExecutor.proto b/protos/SPELLExecutor.proto
new file mode 100644
index 0000000..63db07b
--- /dev/null
+++ b/protos/SPELLExecutor.proto
@@ -0,0 +1,25 @@
+syntax = "proto3";
+
+package spell.core;
+
+import "SPELLDriver.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/wrappers.proto";
+
+option java_multiple_files = true;
+option java_package = "lu.ses.engineering.spell.grpc.executor";
+option java_outer_classname = "SPELLExecutorProto";
+option go_package = "driver";
+
+service SPELLExecutor {
+ rpc DriverLogin(driver.DriverInfo) returns (ExecutorCapability);
+
+ rpc Ping (google.protobuf.Empty) returns (google.protobuf.Empty);
+ rpc Close (google.protobuf.Empty) returns (google.protobuf.Empty);
+}
+
+message ExecutorCapability {
+ bool providesSpellAccess = 1;
+ bool providesControlAccess = 2;
+ bool providesMonitorAccess = 3;
+}
diff --git a/protos/SPELLService.proto b/protos/SPELLService.proto
new file mode 100644
index 0000000..012a7fd
--- /dev/null
+++ b/protos/SPELLService.proto
@@ -0,0 +1,16 @@
+syntax = "proto3";
+
+package spell.service;
+
+import "google/protobuf/empty.proto";
+import "google/protobuf/any.proto";
+import "google/protobuf/wrappers.proto";
+
+option java_multiple_files = true;
+option java_package = "lu.ses.engineering.spell.service";
+option java_outer_classname = "SPELLServiceProto";
+option go_package = "service";
+
+service SPELLServiceRegistry {
+
+}
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 4242a27..f020941 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -1,29 +1,36 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
-include ${top_srcdir}/common.mk
+SRC=${srcdir}/src
+DST=${exec_prefix}/bin
-SUBDIRS=linux
+install-exec-hook:
+ mkdir -p ${exec_prefix}/bin
+ cp -u ${SRC}/setup-environment.sh ${DST}
+ cp -u ${SRC}/SPELL-Driver ${DST}
+ cp -u ${SRC}/SPELL-Server ${DST}
+ cp -u ${SRC}/SPELL-Server-Docker ${DST}
+ cp -u ${SRC}/Kill-Server ${DST}
+ cp -u ${SRC}/Shell ${DST}
+if WITH_PACE
+ cp -u ${SRC}/PACE-Server ${DST}
+ cp -u ${SRC}/Kill-PACE ${DST}
+endif
diff --git a/scripts/src/Kill-PACE b/scripts/src/Kill-PACE
new file mode 100644
index 0000000..12b0903
--- /dev/null
+++ b/scripts/src/Kill-PACE
@@ -0,0 +1,74 @@
+#!/bin/bash
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
+
+function terminate_gracefully() {
+ PID=$1
+ TRIES=10
+ echo "Terminating process $PID"
+ # terminate
+ kill $PID > /dev/null 2>&1
+ for i in $(seq 1 $TRIES); do
+ sleep 1
+ if ps -p $PID > /dev/null; then
+ echo "Process $PID is still running (attempt #$i out of $TRIES)"
+ else
+ echo "Process $PID exited gracefully"
+ break
+ fi
+ done
+ # kill it
+ if ps -p $PID > /dev/null; then
+ echo "Could not terminate process $PID gracefully, killing it"
+ kill -9 $PID > /dev/null 2>&1
+ fi
+}
+
+# Satellite
+SATELLITE=$1
+[ -z $SATELLITE ] && echo "Must provide the spacecraft: $0 " && exit 1
+
+# SPELL home
+if [ -z $SPELL_HOME ]; then
+ export SPELL_HOME=/home/spell/SPELL
+fi
+[ ! -d $SPELL_HOME ] && echo "ERROR: cannot find SPELL home directory: $SPELL_HOME" && exit 1
+
+# Set the server configuration file to be used
+if [ -z $SPELL_CONFIG ]; then
+ SPELL_CONFIG=/home/spell/SPELL_CONFIG
+fi
+CFG_FILE=$SPELL_CONFIG/server/server_$SATELLITE.xml
+[ ! -f $CFG_FILE ] && echo "ERROR: cannot find configuration file: $CFG_FILE" && exit 1
+
+echo "Terminating all PACE processes started with config ${CFG_FILE}"
+
+PROCESSES="PACE"
+for P in $PROCESSES; do
+ PIDS=(`pgrep -u $USER -f "$P .*-c ${CFG_FILE}.*"`)
+ if [ ${#PIDS[@]} == 0 ]; then
+ continue
+ fi
+ echo "Terminating ${#PIDS[@]} $P instance(s)"
+ for PID in ${PIDS[@]}; do
+ terminate_gracefully $PID
+ done
+done
diff --git a/scripts/src/Kill-Server b/scripts/src/Kill-Server
new file mode 100644
index 0000000..010095d
--- /dev/null
+++ b/scripts/src/Kill-Server
@@ -0,0 +1,77 @@
+#!/bin/bash
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
+
+function terminate_gracefully() {
+ PID=$1
+ TRIES=10
+ echo "Terminating process $PID"
+ # terminate
+ kill $PID > /dev/null 2>&1
+ for i in $(seq 1 $TRIES); do
+ sleep 1
+ if ps -p $PID > /dev/null; then
+ echo "Process $PID is still running (attempt #$i out of $TRIES)"
+ else
+ echo "Process $PID exited gracefully"
+ break
+ fi
+ done
+ # kill it
+ if ps -p $PID > /dev/null; then
+ echo "Could not terminate process $PID gracefully, killing it"
+ kill -9 $PID > /dev/null 2>&1
+ fi
+}
+
+# Satellite
+SATELLITE=$1
+[ -z $SATELLITE ] && echo "Must provide the spacecraft: $0 " && exit 1
+
+# SPELL home
+if [ -z $SPELL_HOME ]; then
+ export SPELL_HOME=/home/spell/SPELL
+fi
+[ ! -d $SPELL_HOME ] && echo "ERROR: cannot find SPELL home directory: $SPELL_HOME" && exit 1
+
+# Set the server configuration file to be used
+if [ -z $SPELL_CONFIG ]; then
+ SPELL_CONFIG=/home/spell/SPELL_CONFIG
+fi
+CFG_FILE=$SPELL_CONFIG/server/server_$SATELLITE.xml
+[ ! -f $CFG_FILE ] && echo "ERROR: cannot find configuration file: $CFG_FILE" && exit 1
+
+echo "Terminating SPELL processes started with config ${CFG_FILE}"
+
+PROCESSES="SPELL-Executor SPELL-ExecutorCmd SPELL-Shell SPELL-Executor_v3 SPELL-ExecutorCmd_v3 SPELL-Shell_v3 SPELL-Context SPELL-Listener"
+if [[ "$2" != "skipservice" ]]; then
+ PROCESSES="SPELL-Service $PROCESSES"
+fi
+for P in $PROCESSES; do
+ PIDS=(`pgrep -u $USER -f "$P .*-c ${CFG_FILE}.*"`)
+ if [ ${#PIDS[@]} == 0 ]; then
+ continue
+ fi
+ echo "Terminating ${#PIDS[@]} $P instance(s)"
+ for PID in ${PIDS[@]}; do
+ terminate_gracefully $PID
+ done
+done
diff --git a/scripts/src/PACE-Server b/scripts/src/PACE-Server
new file mode 100644
index 0000000..4d1c25b
--- /dev/null
+++ b/scripts/src/PACE-Server
@@ -0,0 +1,70 @@
+#!/bin/bash
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
+
+#===============================================================================
+# Setup main environment variables
+#===============================================================================
+
+# Satellite
+SATELLITE=$1
+[ -z $SATELLITE ] && echo "Must provide the spacecraft: $0 " && exit 1
+
+# Set SPELL home
+if [ -z $SPELL_HOME ]; then
+ export SPELL_HOME=/home/spell/SPELL
+fi
+[ ! -d $SPELL_HOME ] && echo "ERROR: cannot find SPELL home directory: $SPELL_HOME" && exit 1
+
+#===============================================================================
+# Setup environment
+#===============================================================================
+SETUP_SCRIPT=$SPELL_HOME/bin/setup-environment.sh
+[ ! -f $SETUP_SCRIPT ] && echo "ERROR: cannot find environment setup script: $SETUP_SCRIPT" && exit 1
+! source $SETUP_SCRIPT && echo "ERROR: SPELL environment setup failed" && exit 1
+
+#===============================================================================
+# Launcher configuration
+#===============================================================================
+APP_PATH=$SPELL_HOME/bin/PACE
+CFG_PATH=$SPELL_CONFIG/server/server_$SATELLITE.xml
+[ ! -f $CFG_PATH ] && echo "ERROR: could not find configuration file: $CFG_PATH" && exit 1
+[ ! -f $APP_PATH ] && echo "ERROR: could not find application: $APP_PATH" && exit 1
+
+#===============================================================================
+# Pre-execution cleanup
+#===============================================================================
+echo "Cleanup of previous PACE instances"
+$SPELL_HOME/bin/Kill-PACE $SATELLITE
+
+#===============================================================================
+# Execute application
+#===============================================================================
+VERSION=$($APP_PATH -version)
+echo "Starting $VERSION server for $SATELLITE"
+if [[ ( "$USER" == "hifly_admin" ) && ( -f $BIN_DIR/APPLInotify ) ]]
+then
+ echo "Notifying hifly..."
+ $BIN_DIR/APPLInotify start $$
+ exec $APP_PATH -c $CFG_PATH -n $SATELLITE && $BIN_DIR/APPLInotify stop $$
+else
+ nohup $APP_PATH -c $CFG_PATH -n $SATELLITE >> $SPELL_LOG/pace_$SATELLITE.log 2>&1 &
+fi
diff --git a/scripts/src/SPELL-Compile b/scripts/src/SPELL-Compile
new file mode 100644
index 0000000..ad18786
--- /dev/null
+++ b/scripts/src/SPELL-Compile
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
+
+import py_compile, sys
+
+if len(sys.argv) not in [2, 3]:
+ print("please provide an input file and optionally an output file")
+ sys.exit(1)
+
+outFile = '/tmp/ignore.py'
+if len(sys.argv) == 3:
+ outFile = sys.argv[2]
+
+try:
+ py_compile.compile(sys.argv[1], cfile=outFile, doraise=True)
+except Exception as e:
+ sys.stderr.write('### Python compile error:\n' + str(e) + '\n')
+ raise
diff --git a/scripts/src/SPELL-Disassemble b/scripts/src/SPELL-Disassemble
new file mode 100644
index 0000000..38fccf4
--- /dev/null
+++ b/scripts/src/SPELL-Disassemble
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
+
+import dis, marshal, struct, sys, time, types, os
+
+def show_file(fname):
+ if os.path.exists(fname):
+ f = open(fname, "rb")
+ magic = f.read(4)
+ moddate = f.read(4)
+ modtime = time.asctime(time.localtime(struct.unpack('L', moddate)[0]))
+ print("magic %s" % (magic.encode('hex')))
+ print("moddate %s (%s)" % (moddate.encode('hex'), modtime))
+ code = marshal.load(f)
+ code_tree(code)
+ show_code(code)
+
+def show_code(code, indent=''):
+ print("%scode" % indent)
+ indent += ' '
+ print("%sargcount %d" % (indent, code.co_argcount))
+ print("%snlocals %d" % (indent, code.co_nlocals))
+ print("%sstacksize %d" % (indent, code.co_stacksize))
+ print("%sflags %04x" % (indent, code.co_flags))
+ show_hex("code", code.co_code, indent=indent)
+ dis.disassemble(code)
+ print("%sconsts" % indent)
+ for const in code.co_consts:
+ if type(const) == types.CodeType:
+ show_code(const, indent+' ')
+ else:
+ print(" %s%r" % (indent, const))
+ print("%snames %r" % (indent, code.co_names))
+ print("%svarnames %r" % (indent, code.co_varnames))
+ print("%sfreevars %r" % (indent, code.co_freevars))
+ print("%scellvars %r" % (indent, code.co_cellvars))
+ print("%sfilename %r" % (indent, code.co_filename))
+ print("%sname %r" % (indent, code.co_name))
+ print("%sfirstlineno %d" % (indent, code.co_firstlineno))
+ show_hex("lnotab", code.co_lnotab, indent=indent)
+ show_table(code.co_lnotab,indent=indent)
+
+def code_tree(code, indent=''):
+ print("%scode object: %s" % (indent,code))
+ for const in code.co_consts:
+ if type(const) == types.CodeType:
+ code_tree(const, indent+' ')
+
+def show_table( lnotab, indent ):
+ lnotab = lnotab.encode('hex')
+ if len(lnotab) < 32:
+ print(indent, end=' ')
+ for idx in range(0,len(lnotab),4):
+ offset = int(lnotab[idx:idx+2], 16)
+ sline = int(lnotab[idx+2:idx+4], 16)
+ print("(%s,%s) " % (offset,sline), end=' ')
+ print()
+ else:
+ for i in range(0, len(lnotab), 32):
+ line = lnotab[i:i+32]
+ print(indent, end=' ')
+ for idx in range(0,len(line),4):
+ offset = int(lnotab[idx:idx+2], 16)
+ sline = int(lnotab[idx+2:idx+4], 16)
+ print("(%s,%s) " % (offset,sline), end=' ')
+ print()
+
+def show_hex(label, h, indent):
+ h = h.encode('hex')
+ if len(h) < 60:
+ print("%s%s %s" % (indent, label, h))
+ else:
+ print("%s%s" % (indent, label))
+ for i in range(0, len(h), 60):
+ print("%s %s" % (indent, h[i:i+60]))
+
+if len(sys.argv) != 2:
+ print("please provide an input file")
+ sys.exit(1)
+
+show_file(sys.argv[1])
diff --git a/scripts/src/SPELL-Driver b/scripts/src/SPELL-Driver
new file mode 100644
index 0000000..555b3d3
--- /dev/null
+++ b/scripts/src/SPELL-Driver
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+
+# Prototype for a standalone driver execution with an gRPC interface
+# Author: Raimondas Sasnauskas
+# Date: 2018-03-09
+
+import os, sys
+import argparse
+
+# parse command line arguments
+parser = argparse.ArgumentParser()
+parser.add_argument("context", type=str, help="context name")
+group = parser.add_argument_group()
+group.add_argument("--host", type=str, help="executor service host")
+group.add_argument("--port", type=int, help="executor service port")
+group.add_argument("--debug", dest='debug', action='store_true')
+parser.set_defaults(debug=False)
+args = parser.parse_args()
+
+if (args.host and not args.port) or (not args.host and args.port):
+ parser.error("both executor host and port must be specified")
+
+# check necessary environment variables
+for e in ["SPELL_HOME", "SPELL_CONFIG", "SPELL_COTS"]:
+ if os.getenv(e):
+ continue
+ parser.error("%s environment variable not set" % e)
+
+# check if the config file exists
+SPELL_HOME = os.getenv("SPELL_HOME")
+SPELL_CONFIG = os.getenv("SPELL_CONFIG")
+config = SPELL_CONFIG + os.sep + "server" + os.sep + "server_" + args.context + ".xml"
+if not os.path.isfile(config):
+ parser.error("Configuration file does not exist: " + config)
+
+# Extend PYTHONPATH
+sys.path.append(SPELL_HOME + os.sep + "spell")
+sys.path.append(SPELL_HOME + os.sep + "spell" + os.sep + "spell" + os.sep + "stubs")
+sys.path.append(SPELL_HOME + os.sep + "lib")
+sys.path.append(SPELL_HOME + os.sep + "drivers" + os.sep + "service")
+
+# always load grpc imports first
+import driverserver
+from exec_client import *
+from cif_client import *
+
+from spell.utils.log import LOG
+# set the log file
+if not args.debug:
+ LOG.setLogFile('SPELL-Driver-%s' % args.context)
+ LOG.setShowLog(False)
+
+# spell imports
+from spell.config.reader import Config
+from spell.lib.drivermgr import DriverManager
+from spell.lib.registry import REGISTRY
+
+def run():
+ # load config file
+ Config.instance().load(config)
+
+ # load the driver
+ mgr = DriverManager.instance()
+ mgr.setup(args.context, skipSetup=True)
+ # always setup config interface
+ REGISTRY['CONFIG'].setup(mgr.contextConfig, mgr.driverConfig)
+
+ # start gRPC server
+ driverserver.serve(args.host, args.port)
+
+ # cleanup the driver
+ mgr.cleanup(True, True)
+
+if __name__ == "__main__":
+ run()
diff --git a/scripts/src/SPELL-Server b/scripts/src/SPELL-Server
new file mode 100644
index 0000000..4af2a50
--- /dev/null
+++ b/scripts/src/SPELL-Server
@@ -0,0 +1,69 @@
+#!/bin/bash
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
+
+#===============================================================================
+# Setup main environment variables
+#===============================================================================
+
+# Satellite
+SATELLITE=$1
+[ -z $SATELLITE ] && echo "Must provide the spacecraft: $0 " && exit 1
+
+# Set SPELL home
+if [ -z $SPELL_HOME ]; then
+ export SPELL_HOME=/home/spell/SPELL
+fi
+[ ! -d $SPELL_HOME ] && echo "ERROR: cannot find SPELL home directory: $SPELL_HOME" && exit 1
+
+#===============================================================================
+# Setup environment
+#===============================================================================
+SETUP_SCRIPT=$SPELL_HOME/bin/setup-environment.sh
+[ ! -f $SETUP_SCRIPT ] && echo "ERROR: cannot find environment setup script: $SETUP_SCRIPT" && exit 1
+! source $SETUP_SCRIPT && echo "ERROR: SPELL environment setup failed" && exit 1
+
+#===============================================================================
+# Launcher configuration
+#===============================================================================
+APP_PATH=$SPELL_HOME/bin/SPELL-Listener
+CFG_PATH=$SPELL_CONFIG/server/server_$SATELLITE.xml
+[ ! -f $CFG_PATH ] && echo "ERROR: could not find configuration file: $CFG_PATH" && exit 1
+[ ! -f $APP_PATH ] && echo "ERROR: could not find application: $APP_PATH" && exit 1
+
+#===============================================================================
+# Pre-execution cleanup
+#===============================================================================
+echo "Cleanup of previous server instances except of running SPELL services"
+$SPELL_HOME/bin/Kill-Server $SATELLITE skipservice
+
+#===============================================================================
+# Execute application
+#===============================================================================
+echo "Starting SPELL server for $SATELLITE"
+if [[ ( "$USER" == "hifly_admin" ) && ( -f $BIN_DIR/APPLInotify ) ]]
+then
+ echo "Notifying hifly..."
+ $BIN_DIR/APPLInotify start $$
+ exec $APP_PATH -c $CFG_PATH && $BIN_DIR/APPLInotify stop $$
+else
+ nohup $APP_PATH -c $CFG_PATH >> $SPELL_LOG/server_$SATELLITE.log 2>&1 &
+fi
diff --git a/scripts/src/SPELL-Server-Docker b/scripts/src/SPELL-Server-Docker
new file mode 100644
index 0000000..0f1d087
--- /dev/null
+++ b/scripts/src/SPELL-Server-Docker
@@ -0,0 +1,80 @@
+#!/bin/bash
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
+
+#===============================================================================
+# Setup main environment variables
+#===============================================================================
+
+# Satellite
+SATELLITE=$1
+[ -z $SATELLITE ] && echo "Must provide the spacecraft: $0 " && exit 1
+
+# Set SPELL home
+if [ -z $SPELL_HOME ]; then
+ export SPELL_HOME=/home/spell/SPELL
+fi
+[ ! -d $SPELL_HOME ] && echo "ERROR: cannot find SPELL home directory: $SPELL_HOME" && exit 1
+
+#===============================================================================
+# Setup environment
+#===============================================================================
+SETUP_SCRIPT=$SPELL_HOME/bin/setup-environment.sh
+[ ! -f $SETUP_SCRIPT ] && echo "ERROR: cannot find environment setup script: $SETUP_SCRIPT" && exit 1
+! source $SETUP_SCRIPT && echo "ERROR: SPELL environment setup failed" && exit 1
+
+#===============================================================================
+# Launcher configuration
+#===============================================================================
+APP_PATH=$SPELL_HOME/bin/SPELL-Listener
+CFG_PATH=$SPELL_CONFIG/server/server_$SATELLITE.xml
+[ ! -f $CFG_PATH ] && echo "ERROR: could not find configuration file: $CFG_PATH" && exit 1
+[ ! -f $APP_PATH ] && echo "ERROR: could not find application: $APP_PATH" && exit 1
+
+#===============================================================================
+# Pre-execution cleanup
+#===============================================================================
+echo "Cleanup of previous server instances except of running SPELL services"
+$SPELL_HOME/bin/Kill-Server $SATELLITE skipservice
+
+#==============================================================================
+# SPELL COTS
+#==============================================================================
+
+export PATH=$SPELL_COTS/bin:$PATH
+export LD_LIBRARY_PATH=$SPELL_COTS/lib:$SPELL_HOME/lib:$SPELL_DRIVER/lib:$LD_LIBRARY_PATH
+export BACKWARD_CXX_SOURCE_PREFIXES=/home/spell/src/lib/SPELL_CFG/src
+
+
+#===============================================================================
+# Execute application
+#===============================================================================
+echo "Starting SPELL server for $SATELLITE"
+if [[ ( -f $BIN_DIR/APPLInotify ) ]]
+then
+ echo "Notifying hifly..."
+ $BIN_DIR/APPLInotify start $$
+ $APP_PATH -c $CFG_PATH && $BIN_DIR/APPLInotify stop $$
+else
+ $APP_PATH -c $CFG_PATH 2>&1 | tee -a $SPELL_LOG/server_$SATELLITE.log
+fi
+
+#tail -f $SPELL_LOG/server_$SATELLITE.log
\ No newline at end of file
diff --git a/scripts/src/Shell b/scripts/src/Shell
new file mode 100644
index 0000000..0b88a15
--- /dev/null
+++ b/scripts/src/Shell
@@ -0,0 +1,40 @@
+#!/bin/bash
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
+
+#===============================================================================
+# Setup main environment variables
+#===============================================================================
+
+# SPELL home
+if [ -z $SPELL_HOME ]; then
+ export SPELL_HOME=/home/spell/SPELL
+fi
+[ ! -d $SPELL_HOME ] && echo "ERROR: cannot find SPELL home directory: $SPELL_HOME" && exit 1
+
+#===============================================================================
+# Setup environment
+#===============================================================================
+SETUP_SCRIPT=$SPELL_HOME/bin/setup-environment.sh
+[ ! -f $SETUP_SCRIPT ] && echo "ERROR: cannot find SPELL environment setup script: $SETUP_SCRIPT" && exit 1
+! source $SETUP_SCRIPT && echo "ERROR: SPELL environment setup failed" && exit 1
+
+$SPELL_HOME/bin/SPELL-Shell $@
diff --git a/scripts/src/generate-release-nfo.sh b/scripts/src/generate-release-nfo.sh
new file mode 100644
index 0000000..85c18f4
--- /dev/null
+++ b/scripts/src/generate-release-nfo.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
+
+if [ -f "/etc/centos-release" ]; then
+ PLATFORM=$(cat /etc/centos-release)
+elif [ `which lsb_release` ]; then
+ PLATFORM=$(lsb_release -a | grep Description | cut -d: -f2 | tr -d '\t')
+elif [ -f "/etc/lsb_release" ]; then
+ PLATFORM=$(cat /etc/lsb-release | grep -Po '.*DISTRIB_DESCRIPTION="\K([^"]*)')
+else
+ PLATFORM="Unknown"
+fi
+
+if [ -z "${VERSION_TAG}" ]; then
+ REVISION=$(git describe --tags --always --long 2> /dev/null)
+else
+ REVISION="${VERSION_TAG}"
+fi
+
+echo "\
+---------
+CHANGELOG
+---------
+
+$(cat $1 2> /dev/null)
+
+================================================================================
+Generation date : $(date +%Y-%m-%d)
+Revision : $REVISION
+Version : $2
+Build host : $(hostname)
+Build user : $(whoami)
+Platform : $PLATFORM
+Installation path : $3
+GCC : $(gcc --version | head -1)
+Configure log :
+
+$(head -8 config.log)
+================================================================================\
+"
diff --git a/scripts/src/setup-environment.sh b/scripts/src/setup-environment.sh
new file mode 100644
index 0000000..ecf197f
--- /dev/null
+++ b/scripts/src/setup-environment.sh
@@ -0,0 +1,122 @@
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
+
+#==============================================================================
+# HELPER FUNCTIONS
+#==============================================================================
+
+function check_env_variable() {
+ DST=${!1}
+ if [ -z $DST ]; then
+ echo "$1 is not set, defaulting to $2"
+ export $1=$2
+ fi
+ DST=${!1}
+ if [ ! -d $DST ]; then
+ echo "ERROR: cannot find $1 directory: $DST"
+ return 1
+ else
+ return 0
+ fi
+}
+
+#==============================================================================
+# ENVIRONMENT VARIABLES FOR SPELL
+#==============================================================================
+
+echo ">>> SPELL environment setup begin"
+! check_env_variable SPELL_LOG $SPELL_HOME/log && mkdir -p $SPELL_LOG
+
+# check/set environment variables
+! check_env_variable SPELL_HOME /home/spell/SPELL && return 1
+! check_env_variable SPELL_DATA /home/spell/SPELL_PROCS && return 1
+! check_env_variable SPELL_CONFIG /home/spell/SPELL_CONFIG && return 1
+! check_env_variable SPELL_LOG $SPELL_HOME/log && return 1
+! check_env_variable SPELL_COTS /home/spell/spell_cots && return 1
+
+# parse release.nfo
+RELEASENFO=$SPELL_HOME/release.nfo
+[ ! -f $RELEASENFO ] && echo "ERROR: $RELEASENFO not found, check installation" && return 1
+VERSION=`grep ^Version $RELEASENFO | cut -d: -f 2 | tr -d ' '`
+[ -z $VERSION ] && echo "ERROR: $RELEASENFO does not contain SPELL version" && return 1
+
+[ -z "$USER" ] && export USER=spell
+
+echo "*** SPELL version $VERSION"
+echo "*** SPELL_HOME=$SPELL_HOME"
+echo "*** SPELL_DATA=$SPELL_DATA"
+echo "*** SPELL_CONFIG=$SPELL_CONFIG"
+echo "*** SPELL_LOG=$SPELL_LOG"
+echo "*** SPELL_COTS=$SPELL_COTS"
+echo "*** current User: $USER"
+
+#==============================================================================
+# SPELL ulimits
+#==============================================================================
+
+echo "*** Setting ulimits"
+ulimit -c unlimited > /dev/null 2>&1
+ulimit -s unlimited > /dev/null 2>&1
+ulimit -u 30000 > /dev/null 2>&1
+ulimit -a | grep "core file size"
+ulimit -a | grep "stack size"
+ulimit -a | grep "max user processes"
+
+#==============================================================================
+# SPELL COTS
+#==============================================================================
+
+export PATH=$SPELL_COTS/bin:$PATH
+export LD_LIBRARY_PATH=$SPELL_COTS/lib:$SPELL_HOME/lib:$LD_LIBRARY_PATH
+
+#==============================================================================
+# PYTHON CHECKS
+#==============================================================================
+
+PYTHON=`which python`
+[ -z $PYTHON ] && echo "ERROR: no python executable in PATH" && return 1
+
+# is the python version supported?
+PYVERSION=`$PYTHON -V 2>&1 | cut -d' ' -f 2`
+PYREL=`echo $PYVERSION | cut -d'.' -f 1`
+PYMAJOR=`echo $PYVERSION | cut -d'.' -f 2`
+(( $PYREL != 2 )) && echo "ERROR: python > 2.X.Y required" && return 1
+(( $PYMAJOR < 5 )) && echo "ERROR: python > 2.5.Y required" && return 1
+
+echo "*** Using python version $PYVERSION in $PYTHON"
+
+# is the python executable coming from COTS?
+[[ "$(dirname $PYTHON)" != "$SPELL_COTS/bin" ]] \
+ && echo "ERROR: python executable must be in COTS, check installation" && return 1
+
+# is the python interpreter shared library matching?
+EXC=$SPELL_HOME/bin/SPELL-Executor
+[ ! -f $EXC ] && echo "ERROR: SPELL-Executor not found $SPELL_HOME/bin, check installation" && return 1
+EXPECTED=`readelf -d $EXC | grep ".*NEEDED.*Shared.*libpython.*" | cut -d[ -f 2 | cut -d] -f1`
+AVAILABLE=`readelf -d $PYTHON | grep ".*NEEDED.*Shared.*libpython.*" | cut -d[ -f 2 | cut -d] -f1`
+[[ "$EXPECTED" != "$AVAILABLE" ]] \
+ && echo "ERROR: shared library mismatch, SPELL was compiled with $EXPECTED, got $AVAILABLE" && return 1
+
+# print python path for validation
+$PYTHON -c "import sys; print sys.path"
+
+echo ">>> SPELL environment setup and validation done"
+echo
diff --git a/scripts/src/version.sh b/scripts/src/version.sh
new file mode 100644
index 0000000..67771d1
--- /dev/null
+++ b/scripts/src/version.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
+
+if [ -z "${VERSION_TAG}" ]; then
+ REVISION=$(git describe --tags --always --long 2> /dev/null)
+else
+ REVISION="${VERSION_TAG}"
+fi
+
+echo -ne "$REVISION"
diff --git a/src/Makefile.am b/src/Makefile.am
index a4004d5..bde773d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,52 +1,23 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2012 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
-AUTOMAKE_OPTIONS = foreign
-SUBDIRS=spell
-
-if WITH_EXECUTOR
-SUBDIRS += executor
-endif
-
-if WITH_EXECUTOR_CMD
-SUBDIRS += executorcmd
-endif
-
-if WITH_SHELL
-SUBDIRS += shell
-endif
-
-if WITH_LISTENER
-SUBDIRS += listener
-endif
-
-if WITH_CONTEXT
-SUBDIRS += context
-endif
-
-if WITH_GUI
-SUBDIRS += spel-gui
-endif
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
+SUBDIRS = context executor executorcmd listener service shell ping spell
+
\ No newline at end of file
diff --git a/src/context/Makefile.am b/src/context/Makefile.am
index e2f215c..c10aa73 100644
--- a/src/context/Makefile.am
+++ b/src/context/Makefile.am
@@ -1,50 +1,40 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
-include $(top_srcdir)/common.mk
+include ${top_srcdir}/common.mk
bin_PROGRAMS = SPELL-Context
SPELL_Context_SOURCES = src/SPELLcontextMain.C
-SPELL_Context_LDFLAGS = -lxerces-c -lpthread -lrt -lutil -ldl -lz -lcrypto $(AM_LDFLAGS)
-
-SPELL_Context_LDADD = ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL.la \
- ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC.la \
- ${top_builddir}/lib/SPELL_WS/libSPELL_WS.la \
- ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN.la \
- ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP.la \
- ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG.la \
- ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD.la \
- ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC.la \
- ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF.la \
- ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA.la \
- ${top_builddir}/lib/SPELL_SDB/libSPELL_SDB.la \
- ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS.la \
- ${top_builddir}/lib/SPELL_PRC/libSPELL_PRC.la \
- ${top_builddir}/lib/SPELL_CTX/libSPELL_CTX.la
+SPELL_Context_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+SPELL_Context_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+SPELL_Context_LDADD = ${top_builddir}/lib/SPELL_CTX/libSPELL_CTX_v2.la \
+ ${top_builddir}/lib/SPELL_SDB/libSPELL_SDB_v2.la \
+ ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP_v2.la \
+ ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC_v2.la \
+ ${top_builddir}/lib/SPELL_PRC/libSPELL_PRC_v2.la \
+ ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD_v2.la \
+ ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN_v2.la \
+ ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG_v2.la \
+ ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL_v2.la
diff --git a/src/context/src/SPELLcontextMain.C b/src/context/src/SPELLcontextMain.C
index 7c2b300..c8e7662 100644
--- a/src/context/src/SPELLcontextMain.C
+++ b/src/context/src/SPELLcontextMain.C
@@ -5,7 +5,7 @@
// DESCRIPTION: SPELL context main program
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -33,6 +33,12 @@
#include "SPELL_UTIL/SPELLerror.H"
// Local includes ----------------------------------------------------------
#include "SPELL_CTX/SPELLcontext.H"
+#ifdef WITH_KUBERNETES
+#include
+#endif
+#ifdef WITH_BACKTRACE
+#include
+#endif
// GLOBALS ///////////////////////////////////////////////////////////////////
@@ -45,7 +51,6 @@ static std::string context = "";
// For POST
// STATIC ////////////////////////////////////////////////////////////////////
-
//============================================================================
// Show usage
//============================================================================
@@ -116,6 +121,13 @@ int parseArgs( int argc, char** argv )
//============================================================================
int main( int argc, char** argv )
{
+ #ifdef WITH_KUBERNETES
+ prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
+ #endif
+ #ifdef WITH_BACKTRACE
+ backward::SignalHandling sh;
+ std::cout << "Singal Handlers loaded: " << sh.loaded() << std::endl;
+ #endif
if ( parseArgs(argc,argv) != 0 ) return 1;
// The time identifier is used for unique log file names
diff --git a/src/executor/Makefile.am b/src/executor/Makefile.am
index 1193feb..82ed20b 100644
--- a/src/executor/Makefile.am
+++ b/src/executor/Makefile.am
@@ -1,48 +1,61 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
-
-include $(top_srcdir)/common.mk
-
-bin_PROGRAMS = SPELL-Executor
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
+
+include ${top_srcdir}/common.mk
+
+bin_PROGRAMS = SPELL-Executor SPELL-Executor_v3
+
+SPELL_Executor_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+
+SPELL_Executor_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
SPELL_Executor_SOURCES = src/SPELLexecutorMain.C
-SPELL_Executor_LDFLAGS = -lxerces-c -lpthread -lrt -lutil -ldl -lz -lcrypto $(AM_LDFLAGS)
+SPELL_Executor_LDADD = ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC_v2.la \
+ ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS_v2.la \
+ ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA_v2.la \
+ ${top_builddir}/lib/SPELL_WS/libSPELL_WS_v2.la \
+ ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP_v2.la \
+ ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF_v2.la \
+ ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC_v2.la \
+ ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD_v2.la \
+ ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN_v2.la \
+ ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG_v2.la \
+ ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL_v2.la
+
+SPELL_Executor_v3_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS}
-SPELL_Executor_LDADD = ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL.la \
- ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC.la \
- ${top_builddir}/lib/SPELL_WS/libSPELL_WS.la \
- ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN.la \
- ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP.la \
- ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG.la \
- ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD.la \
- ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC.la \
- ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA.la \
- ${top_builddir}/lib/SPELL_SDB/libSPELL_SDB.la \
- ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS.la \
- ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF.la
+SPELL_Executor_v3_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+SPELL_Executor_v3_SOURCES = src/SPELLexecutorMain.C
+SPELL_Executor_v3_LDADD = ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC_v3.la \
+ ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS_v3.la \
+ ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA_v3.la \
+ ${top_builddir}/lib/SPELL_WS/libSPELL_WS_v3.la \
+ ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP_v3.la \
+ ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF_v3.la \
+ ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC_v3.la \
+ ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD_v3.la \
+ ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN_v3.la \
+ ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG_v3.la \
+ ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL_v3.la
+
\ No newline at end of file
diff --git a/src/executor/src/SPELLexecutorMain.C b/src/executor/src/SPELLexecutorMain.C
index 27bfd0c..e3ad630 100644
--- a/src/executor/src/SPELLexecutorMain.C
+++ b/src/executor/src/SPELLexecutorMain.C
@@ -5,7 +5,7 @@
// DESCRIPTION: SPELL executor main program
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -34,7 +34,12 @@
#include "SPELL_EXC/SPELLinterpreter.H"
#include "SPELL_CIFS/SPELLserverCif.H"
#include "SPELL_UTIL/SPELLpythonHelper.H"
-
+#ifdef WITH_KUBERNETES
+#include
+#endif
+#ifdef WITH_BACKTRACE
+#include
+#endif
// GLOBALS ///////////////////////////////////////////////////////////////////
// Initialization/configuration variables
@@ -48,6 +53,7 @@ static std::string procId = "";
static std::string persis = "";
static std::string timeId = "";
+
// STATIC ////////////////////////////////////////////////////////////////////
//============================================================================
@@ -140,8 +146,15 @@ int parseArgs( int argc, char** argv )
//============================================================================
int main( int argc, char** argv )
{
+ #ifdef WITH_KUBERNETES
+ prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
+ #endif
+ #ifdef WITH_BACKTRACE
+ backward::SignalHandling sh;
+ std::cout << "Singal Handlers loaded: " << sh.loaded() << std::endl;
+ #endif
if ( parseArgs(argc,argv) != 0 ) return 1;
-
+
// Create an instance of the interpreter.
SPELLinterpreter& interp = SPELLinterpreter::instance();
@@ -154,10 +167,6 @@ int main( int argc, char** argv )
// Setup the logging capabilities
SPELLlog::instance().setLogFile("_Executor_" + procId, timeId);
-#ifdef WITH_DEBUG
- LOG_ENABLE
-#endif
-
// Configuration of the interpreter
SPELLinterpreterConfig config;
config.warmstart = (warm == 1); // Enable warm-start and error recovery capabilities
diff --git a/src/executorcmd/Makefile.am b/src/executorcmd/Makefile.am
index 0ff57c2..d53a87d 100644
--- a/src/executorcmd/Makefile.am
+++ b/src/executorcmd/Makefile.am
@@ -1,49 +1,65 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Mar 17, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
-
-include $(top_srcdir)/common.mk
-
-bin_PROGRAMS = SPELL-ExecutorCmd
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
+
+include ${top_srcdir}/common.mk
+
+bin_PROGRAMS = SPELL-ExecutorCmd SPELL-ExecutorCmd_v3
SPELL_ExecutorCmd_SOURCES = src/SPELLexecutorMain.C
-SPELL_ExecutorCmd_LDFLAGS = -lxerces-c -lpthread -lrt -lncurses -lmenu -lutil -ldl -lz -lcrypto $(AM_LDFLAGS)
+SPELL_ExecutorCmd_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+
+SPELL_ExecutorCmd_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} -lmenu
+
+SPELL_ExecutorCmd_LDADD = ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC_v2.la \
+ ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS_v2.la \
+ ${top_builddir}/lib/SPELL_CIFC/libSPELL_CIFC_v2.la \
+ ${top_builddir}/lib/SPELL_SDB/libSPELL_SDB_v2.la \
+ ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA_v2.la \
+ ${top_builddir}/lib/SPELL_WS/libSPELL_WS_v2.la \
+ ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP_v2.la \
+ ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF_v2.la \
+ ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC_v2.la \
+ ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD_v2.la \
+ ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN_v2.la \
+ ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG_v2.la \
+ ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL_v2.la
+
+SPELL_ExecutorCmd_v3_SOURCES = src/SPELLexecutorMain.C
-SPELL_ExecutorCmd_LDADD = ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL.la \
- ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC.la \
- ${top_builddir}/lib/SPELL_WS/libSPELL_WS.la \
- ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN.la \
- ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP.la \
- ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG.la \
- ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD.la \
- ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC.la \
- ${top_builddir}/lib/SPELL_CIFC/libSPELL_CIFC.la \
- ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA.la \
- ${top_builddir}/lib/SPELL_SDB/libSPELL_SDB.la \
- ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS.la \
- ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF.la
+SPELL_ExecutorCmd_v3_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS}
+SPELL_ExecutorCmd_v3_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} -lmenu
+SPELL_ExecutorCmd_v3_LDADD = ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC_v3.la \
+ ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS_v3.la \
+ ${top_builddir}/lib/SPELL_CIFC/libSPELL_CIFC_v3.la \
+ ${top_builddir}/lib/SPELL_SDB/libSPELL_SDB_v3.la \
+ ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA_v3.la \
+ ${top_builddir}/lib/SPELL_WS/libSPELL_WS_v3.la \
+ ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP_v3.la \
+ ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF_v3.la \
+ ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC_v3.la \
+ ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD_v3.la \
+ ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN_v3.la \
+ ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG_v3.la \
+ ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL_v3.la
+
\ No newline at end of file
diff --git a/src/executorcmd/src/SPELLexecutorMain.C b/src/executorcmd/src/SPELLexecutorMain.C
index 705ddda..dff2b56 100644
--- a/src/executorcmd/src/SPELLexecutorMain.C
+++ b/src/executorcmd/src/SPELLexecutorMain.C
@@ -5,7 +5,7 @@
// DESCRIPTION: SPELL command line executor main program
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -35,8 +35,9 @@
#include "SPELL_EXC/SPELLinterpreter.H"
#include "SPELL_CIFC/SPELLstandaloneCif.H"
#include "SPELL_CIFC/SPELLautomaticCif.H"
-
-
+#ifdef WITH_BACKTRACE
+#include
+#endif
// GLOBALS ///////////////////////////////////////////////////////////////////
// Initialization/configuration variables
@@ -54,7 +55,6 @@ static std::string arguments = "";
// STATIC ////////////////////////////////////////////////////////////////////
-
//============================================================================
// Show usage
//============================================================================
@@ -156,6 +156,10 @@ int parseArgs( int argc, char** argv )
//============================================================================
int main( int argc, char** argv )
{
+ #ifdef WITH_BACKTRACE
+ backward::SignalHandling sh;
+ std::cout << "Singal Handlers loaded: " << sh.loaded() << std::endl;
+ #endif
if ( parseArgs(argc,argv) != 0 ) return 1;
// Show the environment configuration
diff --git a/src/listener/Makefile.am b/src/listener/Makefile.am
index 693b505..3d1bca6 100644
--- a/src/listener/Makefile.am
+++ b/src/listener/Makefile.am
@@ -1,43 +1,38 @@
-###################################################################################
-## FILE : Makefile.am
-## DATE : Jul 26, 2011
-## PROJECT : SPELL
-## DESCRIPTION: Automake rules
-## --------------------------------------------------------------------------------
-##
-## Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
-##
-## This file is part of SPELL.
-##
-## SPELL is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## SPELL is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with SPELL. If not, see .
-##
-###################################################################################
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
+AUTOMAKE_OPTIONS = subdir-objects
-include $(top_srcdir)/common.mk
+include ${top_srcdir}/common.mk
bin_PROGRAMS = SPELL-Listener
SPELL_Listener_SOURCES = src/SPELLlistenerMain.C
-SPELL_Listener_LDFLAGS = -lxerces-c -lpthread -lrt -lutil -ldl -lz -lcrypto $(AM_LDFLAGS)
-
-SPELL_Listener_LDADD = \
- ${top_builddir}/lib/SPELL_LST/libSPELL_LST.la \
- ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC.la \
- ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL.la \
- ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN.la \
- ${top_builddir}/lib/SPELL_PRC/libSPELL_PRC.la \
- ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG.la
+SPELL_Listener_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+SPELL_Listener_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG}
+SPELL_Listener_LDADD = ${top_builddir}/lib/SPELL_LST/libSPELL_LST_v2.la \
+ ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC_v2.la \
+ ${top_builddir}/lib/SPELL_PRC/libSPELL_PRC_v2.la \
+ ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN_v2.la \
+ ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG_v2.la \
+ ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL_v2.la
diff --git a/src/listener/src/SPELLlistenerMain.C b/src/listener/src/SPELLlistenerMain.C
index fd2ea41..87aa320 100644
--- a/src/listener/src/SPELLlistenerMain.C
+++ b/src/listener/src/SPELLlistenerMain.C
@@ -5,7 +5,7 @@
// DESCRIPTION: SPELL listener main program
// --------------------------------------------------------------------------------
//
-// Copyright (C) 2008, 2015 SES ENGINEERING, Luxembourg S.A.R.L.
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
//
// This file is part of SPELL.
//
@@ -32,6 +32,12 @@
#include "SPELL_LST/SPELLlistener.H"
// System includes -----------------------------------------------------------
#include
+#ifdef WITH_KUBERNETES
+#include
+#endif
+#ifdef WITH_BACKTRACE
+#include
+#endif
// Local includes ------------------------------------------------------------
// GLOBALS ///////////////////////////////////////////////////////////////////
@@ -116,9 +122,9 @@ int parseArgs( int argc, char** argv )
//============================================================================
void signal_handler(int signum)
{
- if (signum < NumSignals)
+ if ((unsigned)signum < NumSignals)
{
- std::cerr << "[***] Captured signal " << signalList[signum].name << std::endl;
+ std::cerr << "[***] Captured signal " << signum << " "<< signalList[signum].name << std::endl;
}
else
{
@@ -162,6 +168,13 @@ void setupSignals()
//============================================================================
int main( int argc, char** argv )
{
+ #ifdef WITH_KUBERNETES
+ prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
+ #endif
+ #ifdef WITH_BACKTRACE
+ backward::SignalHandling sh;
+ std::cout << "Singal Handlers loaded: " << sh.loaded() << std::endl;
+ #endif
std::string timeId = SPELLutils::fileTimestamp();
SPELLlog::instance().setLogFile("_Listener", timeId);
diff --git a/src/ping/Makefile.am b/src/ping/Makefile.am
new file mode 100644
index 0000000..f3ec786
--- /dev/null
+++ b/src/ping/Makefile.am
@@ -0,0 +1,44 @@
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
+
+include ${top_srcdir}/common.mk
+
+bin_PROGRAMS = SPELL-Ping
+
+SPELL_Ping_SOURCES = src/SPELLPing.C
+
+SPELL_Ping_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+
+SPELL_Ping_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} -lmenu
+
+SPELL_Ping_LDADD = ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC_v2.la \
+ ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS_v2.la \
+ ${top_builddir}/lib/SPELL_CIFC/libSPELL_CIFC_v2.la \
+ ${top_builddir}/lib/SPELL_SDB/libSPELL_SDB_v2.la \
+ ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA_v2.la \
+ ${top_builddir}/lib/SPELL_WS/libSPELL_WS_v2.la \
+ ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP_v2.la \
+ ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF_v2.la \
+ ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC_v2.la \
+ ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD_v2.la \
+ ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN_v2.la \
+ ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG_v2.la \
+ ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL_v2.la
diff --git a/src/ping/src/SPELLPing.C b/src/ping/src/SPELLPing.C
new file mode 100644
index 0000000..6d7cb9e
--- /dev/null
+++ b/src/ping/src/SPELLPing.C
@@ -0,0 +1,133 @@
+// ################################################################################
+// FILE : SPELLPing.C
+// DATE : Mar 18, 2011
+// PROJECT : SPELL
+// DESCRIPTION: SPELL command line executor main program
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+// FILES TO INCLUDE //////////////////////////////////////////////////////////
+// System includes -----------------------------------------------------------
+// Local includes ------------------------------------------------------------
+// Project includes ----------------------------------------------------------
+#include "SPELL_UTIL/SPELLbase.H"
+#include "SPELL_UTIL/SPELLpythonHelper.H"
+#include "SPELL_UTIL/SPELLlog.H"
+#include "SPELL_UTIL/SPELLutils.H"
+#include "SPELL_WRP/SPELLconstants.H"
+#include "SPELL_IPC/SPELLipcClientInterface.H"
+#include "SPELL_IPC/SPELLipc.H"
+#include "SPELL_IPC/SPELLipc_Context.H"
+
+// GLOBALS ///////////////////////////////////////////////////////////////////
+
+// Initialization/configuration variables
+
+static int logging = 0;
+static std::string context = "";
+static std::string configFile = "";
+static int port = 19888;
+
+// STATIC ////////////////////////////////////////////////////////////////////
+
+
+//============================================================================
+// Show usage
+//============================================================================
+void usage( char** argv )
+{
+ std::cerr << "Syntax:" << std::endl;
+ std::cerr << " " << argv[0] << " -p [-d]" << std::endl;
+ std::cerr << std::endl;
+ std::cerr << " - p : context port" << std::endl;
+ std::cerr << " - d : enable debug traces" << std::endl;
+ std::cerr << std::endl;
+}
+
+//============================================================================
+// Parse program arguments
+//============================================================================
+int parseArgs( int argc, char** argv )
+{
+ int code;
+ while( ( code = getopt(argc, argv, "dp:n:c:")) != -1)
+ {
+ switch(code)
+ {
+ case 'd':
+ logging = 1;
+ break;
+ case 'p':
+ port = atoi(optarg);
+ std::cout << "* Port " << port << std::endl;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+//============================================================================
+// MAIN PROGRAM
+//============================================================================
+int main( int argc, char** argv )
+{
+ if ( parseArgs(argc,argv) != 0 ) return 1;
+
+ // Show the environment configuration
+ SPELLutils::showEnvironment();
+ // The time identifier is used to create unique file names
+
+ SPELLipcClientInterface* ipc = new SPELLipcClientInterface("Ping","localhost",port);
+
+ std::cout << "SPELL-Ping ### Connecting to Context" << std::endl;
+ ipc->connect();
+ bool connectSuccessful = ipc->isConnected();
+ std::cout << "SPELL-Ping ### Connection Successful: " << (connectSuccessful ? "yes" : "no") << std::endl;
+ if (connectSuccessful) {
+ SPELLipcMessage* msg = new SPELLipcMessage(ContextMessages::REQ_CURRENT_TIME);
+ msg->setType(MSG_TYPE_REQUEST);
+ msg->setSender("PING");
+ msg->setReceiver("CTX");
+ std::cout << "SPELL-Ping ### Sending Ping." << std::endl;
+ SPELLipcMessage answer = ipc->sendRequest(*msg,5000);
+ std::cout << "SPELL-Ping ### Ping was sent." << std::endl;
+ bool errorFound = answer.hasField(MessageField::FIELD_FATAL);
+
+ std::cout << "SPELL-Ping ### Sending EOC" << std::endl;
+ SPELLipcMessage* eoc = new SPELLipcMessage("EOC");
+ eoc->setType( MSG_TYPE_EOC );
+
+ ipc->sendMessage(*eoc);
+
+ ipc->disconnect();
+ if (errorFound){
+ std::cout << "SPELL-Ping ### Ping not successful." << std::endl;
+ return -2;
+ } else {
+ std::cout << "SPELL-Ping ### Ping successful." << std::endl;
+ return 0;
+ }
+ } else {
+ std::cout << "SPELL-Ping ### Connection failed." << std::endl;
+ return -1;
+ }
+}
diff --git a/src/service/Makefile.am b/src/service/Makefile.am
new file mode 100644
index 0000000..406575d
--- /dev/null
+++ b/src/service/Makefile.am
@@ -0,0 +1,65 @@
+################################################################################
+#
+# Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+#
+# This file is part of SPELL.
+#
+# SPELL is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# SPELL is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with SPELL. If not, see .
+#
+################################################################################
+
+
+include ${top_srcdir}/common.mk
+
+bin_PROGRAMS = SPELL-Service SPELL-Service_v3
+
+SPELL_Service_SOURCES = src/SPELLserviceMain.C
+
+SPELL_Service_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON2_CPPFLAGS}
+
+SPELL_Service_LDFLAGS = ${AM_LDFLAGS} ${PYTHON2_LDFLAGS} ${PYTHON2_EXTRA_LIBS} ${PYTHON2_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} -lmenu
+
+SPELL_Service_LDADD = ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC_v2.la \
+ ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS_v2.la \
+ ${top_builddir}/lib/SPELL_CIFC/libSPELL_CIFC_v2.la \
+ ${top_builddir}/lib/SPELL_SDB/libSPELL_SDB_v2.la \
+ ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA_v2.la \
+ ${top_builddir}/lib/SPELL_WS/libSPELL_WS_v2.la \
+ ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP_v2.la \
+ ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF_v2.la \
+ ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC_v2.la \
+ ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD_v2.la \
+ ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN_v2.la \
+ ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG_v2.la \
+ ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL_v2.la
+
+SPELL_Service_v3_SOURCES = src/SPELLserviceMain.C
+
+SPELL_Service_v3_CPPFLAGS = ${AM_CPPFLAGS} ${PYTHON3_CPPFLAGS}
+
+SPELL_Service_v3_LDFLAGS = ${AM_LDFLAGS} ${PYTHON3_LDFLAGS} ${PYTHON3_EXTRA_LIBS} ${PYTHON3_EXTRA_LDFLAGS} ${RELEASE_LDFLAG} -lmenu
+
+SPELL_Service_v3_LDADD = ${top_builddir}/lib/SPELL_EXC/libSPELL_EXC_v3.la \
+ ${top_builddir}/lib/SPELL_CIFS/libSPELL_CIFS_v3.la \
+ ${top_builddir}/lib/SPELL_CIFC/libSPELL_CIFC_v3.la \
+ ${top_builddir}/lib/SPELL_SDB/libSPELL_SDB_v3.la \
+ ${top_builddir}/lib/SPELL_DTA/libSPELL_DTA_v3.la \
+ ${top_builddir}/lib/SPELL_WS/libSPELL_WS_v3.la \
+ ${top_builddir}/lib/SPELL_WRP/libSPELL_WRP_v3.la \
+ ${top_builddir}/lib/SPELL_CIF/libSPELL_CIF_v3.la \
+ ${top_builddir}/lib/SPELL_IPC/libSPELL_IPC_v3.la \
+ ${top_builddir}/lib/SPELL_PRD/libSPELL_PRD_v3.la \
+ ${top_builddir}/lib/SPELL_SYN/libSPELL_SYN_v3.la \
+ ${top_builddir}/lib/SPELL_CFG/libSPELL_CFG_v3.la \
+ ${top_builddir}/lib/SPELL_UTIL/libSPELL_UTIL_v3.la
diff --git a/src/service/src/SPELLserviceMain.C b/src/service/src/SPELLserviceMain.C
new file mode 100644
index 0000000..7b0cec8
--- /dev/null
+++ b/src/service/src/SPELLserviceMain.C
@@ -0,0 +1,213 @@
+// ################################################################################
+// FILE : SPELLserviceMain.C
+// DATE : Mar 18, 2011
+// PROJECT : SPELL
+// DESCRIPTION: SPELL command line executor main program
+// --------------------------------------------------------------------------------
+//
+// Copyright (C) 2008, 2018 SES ENGINEERING, Luxembourg S.A.R.L.
+//
+// This file is part of SPELL.
+//
+// SPELL is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// SPELL is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with SPELL. If not, see .
+//
+// ################################################################################
+
+// FILES TO INCLUDE //////////////////////////////////////////////////////////
+// System includes -----------------------------------------------------------
+// Local includes ------------------------------------------------------------
+// Project includes ----------------------------------------------------------
+#include "SPELL_UTIL/SPELLbase.H"
+#include "SPELL_UTIL/SPELLpythonHelper.H"
+#include "SPELL_UTIL/SPELLlog.H"
+#include "SPELL_UTIL/SPELLutils.H"
+#include "SPELL_EXC/SPELLserviceInterpreter.H"
+#include "SPELL_CIFS/SPELLserverCif.H"
+#ifdef WITH_KUBERNETES
+#include
+#endif
+#ifdef WITH_BACKTRACE
+#include
+#endif
+// GLOBALS ///////////////////////////////////////////////////////////////////
+
+// Initialization/configuration variables
+static int warm = 0;
+static int recover = 0;
+static int script = 0;
+static int interactive = 0;
+static int logging = 0;
+static int port = 0;
+static std::string context = "";
+static std::string configFile = "";
+static std::string procId = "";
+static std::string persis = "";
+static std::string promptFile = "";
+static std::string arguments = "";
+
+// STATIC ////////////////////////////////////////////////////////////////////
+
+
+//============================================================================
+// Show usage
+//============================================================================
+void usage( char** argv )
+{
+ std::cerr << "Syntax:" << std::endl;
+ std::cerr << " " << argv[0] << " {-p |-f