Author: AaronLWalker Date: 2017-01-27 13:22:20 +0000 (Fri, 27 Jan 2017) New Revision: 30303 Trac url: http://develop.twiki.org/trac/changeset/30303 Added: twiki/trunk/EPAgentPlugin/data/ twiki/trunk/EPAgentPlugin/data/TWiki/ twiki/trunk/EPAgentPlugin/data/TWiki/EPAgentPlugin.txt twiki/trunk/EPAgentPlugin/lib/ twiki/trunk/EPAgentPlugin/lib/TWiki/ twiki/trunk/EPAgentPlugin/lib/TWiki/Plugins/ twiki/trunk/EPAgentPlugin/lib/TWiki/Plugins/EPAgentPlugin.pm twiki/trunk/EPAgentPlugin/working/ twiki/trunk/EPAgentPlugin/working/work_areas/ twiki/trunk/EPAgentPlugin/working/work_areas/EPAgentPlugin/ twiki/trunk/EPAgentPlugin/working/work_areas/EPAgentPlugin/epagent.db Log: Item7770: Initial population of EPAgentPlugin Added: twiki/trunk/EPAgentPlugin/data/TWiki/EPAgentPlugin.txt =================================================================== --- twiki/trunk/EPAgentPlugin/data/TWiki/EPAgentPlugin.txt (rev 0) +++ twiki/trunk/EPAgentPlugin/data/TWiki/EPAgentPlugin.txt 2017-01-27 13:22:20 UTC (rev 30303) @@ -0,0 +1,136 @@ +%META:TOPICINFO{author="AaronWalker" date="1472053624" format="1.1" reprev="1.9" version="1.9"}% +---+!! !DataTablesPlugin +<!-- + Contributions to this plugin are appreciated. Please update the plugin page at + http://twiki.org/cgi-bin/view/Plugins/DataTablesPlugin or provide feedback at + http://twiki.org/cgi-bin/view/Plugins/DataTablesPluginDev. + If you are a TWiki contributor please update the plugin in the SVN repository. +--> +<sticky><div style="float:right; background-color:#EBEEF0; margin:0 0 20px 20px; padding: 0 10px 0 10px;"> +%TOC{title="Page contents"}% +</div></sticky> +%SHORTDESCRIPTION% + +---++ Introduction + +Describe the plugin here + +---++ Syntax Rules + +=%<nop>EXAMPLEVAR{"..."}%= + +| *Parameter* | *Explanation* | *Default* | +| ="..."= | Default parameter. | (none) | +| =format="..."= | Format: ... | ="$name"= | + +---++ REST interfaces +<noautolink> + * updateUserPref + + * updateMS + * _Used by:_ UpdateMilestoneExample + * _Used by:_ WorkflowViewer + + * updateTC + * _Used by:_ AppViewer + + * createWF + * _Used by:_ CreateWorkflow + + * modifyWF + + * leftBar + * _Used by:_ TrackerLeftBar + + * workflowData + * _Used by:_ WorkflowViewer + + * workflowListing + * _Used by:_ WorkflowListing + + * testCaseListing + * _Used by:_ TestCases + + * testCaseData + * _Used by:_ TestCaseViewer + + * appListing + * _Used by:_ Apps + + * appData + * _Used by:_ AppViewer + + * allAppsData + + * readyAppList + * _Used by:_ ReadyAppList + + * viewWFNotes + * _Used by:_ NotesPopup + + * viewAllNotes + + * milestoneData + * _Used by:_ MilestoneViewer + + * manageWFMSInfo + +</noautolink> +---++ Examples + + * =%<nop>EXAMPLEVAR{}%= expands to: %EXAMPLEVAR{}% + * + +---++ Plugin Installation & Configuration + +You do not need to install anything on the browser to use this plugin. These instructions are for the administrator who installs the plugin on the TWiki server. +%TWISTY{ + mode="div" + showlink="Show details %ICONURL{toggleopen}% " + hidelink="Hide details %ICONURL{toggleclose}% " +}% + + * For an __automated installation__, run the [[%SCRIPTURL{configure}%][configure]] script and follow "Find More Extensions" in the in the __Extensions__ section. + * See the [[http://twiki.org/cgi-bin/view/Plugins/BuildContribInstallationSupplement][installation supplement]] on TWiki.org for more information. + + * Or, follow these __manual installation__ steps: + * Download the ZIP file from the Plugins home (see below). + * Unzip ==%TOPIC%.zip== in your twiki installation directory. Content: + | *File:* | *Description:* | + | ==data/TWiki/%TOPIC%.txt== | Plugin topic | + | ==lib/TWiki/Plugins/%TOPIC%.pm== | Plugin Perl module | + * Set the ownership of the extracted directories and files to the webserver user. + * Install the dependencies (if any). + + * Plugin __configuration and testing__: + * Run the [[%SCRIPTURL{configure}%][configure]] script and enable the plugin in the __Plugins__ section. + * Configure additional plugin settings in the __Extensions__ section if needed. + * Test if the installation was successful using the example above. + +%ENDTWISTY% + + * Set DBID = epagent + * #Set DBID = trkoracle + +---++ Plugin Info + + * One line description, is shown in the %SYSTEMWEB%.TextFormattingRules topic: + * Set SHORTDESCRIPTION = one line description here +%TABLE{ tablewidth="100%" columnwidths="170," }% +| Plugin Author: | TWiki:Main.AaronLWalker | +| Copyright: | © 2015 TWiki:Main.AaronLWalker <br /> © 2015 TWiki:TWiki.TWikiContributor | +| License: | GPL ([[http://www.gnu.org/copyleft/gpl.html][GNU General Public License]]) | +| Plugin Version: | 2015-06-23 (V1.000) | +| Change History: | <!-- versions below in reverse order --> | +| 2015-06-23: | Initial version | +| TWiki Dependency: | $TWiki::Plugins::VERSION 1.1 | +| CPAN Dependencies: | none | +| Other Dependencies: | none | +| Perl Version: | 5.005 | +| [[TWiki:Plugins.Benchmark][Plugin Benchmark]]: | %SYSTEMWEB%.GoodStyle nn%, %SYSTEMWEB%.FormattedSearch nn%, %TOPIC% nn% | +| Plugin Home: | http://TWiki.org/cgi-bin/view/Plugins/%TOPIC% | +| Feedback: | http://TWiki.org/cgi-bin/view/Plugins/%TOPIC%Dev | +| Appraisal: | http://TWiki.org/cgi-bin/view/Plugins/%TOPIC%Appraisal | + +__Related Topics:__ %SYSTEMWEB%.TWikiPlugins, %SYSTEMWEB%.DeveloperDocumentationCategory, %SYSTEMWEB%.AdminDocumentationCategory, %SYSTEMWEB%.TWikiPreferences + Added: twiki/trunk/EPAgentPlugin/lib/TWiki/Plugins/EPAgentPlugin.pm =================================================================== --- twiki/trunk/EPAgentPlugin/lib/TWiki/Plugins/EPAgentPlugin.pm (rev 0) +++ twiki/trunk/EPAgentPlugin/lib/TWiki/Plugins/EPAgentPlugin.pm 2017-01-27 13:22:20 UTC (rev 30303) @@ -0,0 +1,1151 @@ +# Module of TWiki Enterprise Collaboration Platform, http://TWiki.org/ +# +# Copyright (C) 2010-2013 Peter Thoeny, peter[at]thoeny.org +# Copyright (C) 2010-2013 TWiki Contributors. All Rights Reserved. +# TWiki Contributors are listed in the AUTHORS file in the root of +# this distribution. NOTE: Please extend that file, not this notice. +# +# 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 2 +# of the License, or (at your option) any later version. For +# more details read LICENSE in the root of this distribution. +# +# 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. +# +# As per the GPL, removal of this notice is prohibited. + +=begin twiki + +This package includes a small Perl module to make it easier to use the +color picker from other TWiki plugins. This module includes the functions: + +=cut + +package TWiki::Plugins::EPAgentPlugin; + +use DBI; +use Data::Dumper; # for debugging +use strict; +use Error qw( :try ); + +require TWiki::Func; # The plugins API + +# ========================================================================== +our $VERSION = '$Rev: 25074 (2013-10-14) $'; +our $RELEASE = '2015-09-03'; +our $SHORTDESCRIPTION = "Introscope EPAgent-like Plugin"; +#our $NO_PREFS_IN_TOPIC = 1; +our $doneHeader; +our $pluginName = 'EPAgentPlugin'; # Name of this Plugin +our $debug = $TWiki::cfg{Plugins}{EPAgentPlugin}{Debug} || 0; + +# ========================================================================== +sub initPlugin { + my( $topic, $web, $user, $installWeb ) = @_; + + $doneHeader = 0; + + TWiki::Func::registerTagHandler('EPAGENTPLUGININFO', \&handlePluginInfo ); + TWiki::Func::registerTagHandler('ORACLEINFO', \&handleOracleInfo ); + TWiki::Func::registerTagHandler('TRACKERENV', \&handleListEnv ); + + TWiki::Func::registerTagHandler('TRACKERERRORCODES', \&handleShowErrorCodes ); + + # Allow a sub to be called from the REST interface + # using the provided alias + TWiki::Func::registerRESTHandler('insertVal', \&restInsertVal ); + TWiki::Func::registerRESTHandler('getEntries', \&restGetEntries ); + TWiki::Func::registerRESTHandler('getMenu', \&restGetMenu ); + + return 1; +} + +# ========================================================================== + +=begin twiki + +---+++ _getConnection + +=cut + +sub _getConnectionNoAutoCommit +{ + my $this_subs_name = (caller(0))[3]; + my $defDB = TWiki::Func::getPreferencesValue("EPAGENTPLUGIN_DBID"); + + unless (exists $TWiki::cfg{Plugins}{EPAgentPlugin}) { + die "$TWiki::cfg{Plugins}{EPAgentPlugin} not defined"; + } + unless (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}) { + die "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases} not defined"; + } + my $rawDb = ""; + my $driverDb = ""; + my $userDb = ""; + my $pwdDb = ""; + my $cString = ""; + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}) { + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{driver}) { + my $rawDriver = $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{driver}; + if ($rawDriver =~/oracle/i) { + $driverDb = "Oracle"; + } elsif ($rawDriver =~/sqlite/i) { + $driverDb = "SQLite"; + } else { + $driverDb = "unknown"; + } + } else { + $driverDb = "unknown"; + } + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{database}) { + $rawDb = "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{database}"; + $rawDb =~ s/\$workarea/TWiki::Func::getWorkArea( $pluginName )/geo; + } else { + $rawDb = "unknown"; + } + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{username}) { + $userDb = "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{username}"; + } else { + $userDb = "unknown"; + } + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{password}) { + $pwdDb = "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{password}"; + } else { + $pwdDb = "unknown"; + } + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{connstring}) { + $cString = "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{connstring}"; + } else { + $cString = "unknown"; + } + } else { + die "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB} not defined"; + } + + my $connString = ""; + if ($driverDb eq "Oracle") { + my $db = DBI->connect('dbi:Oracle:', "$cString", ""); + return $db; + } elsif ($driverDb eq "SQLite") { + $connString = "dbi:SQLite:${rawDb}"; + my $db = DBI->connect($connString, $userDb, $pwdDb, {sqlite_use_immediate_transaction => 1, RaiseError => 1, AutoCommit => 1}); + return $db; + } else { + die "$this_subs_name = no viable database defined"; + } +} + +sub _getConnection +{ + my $this_subs_name = (caller(0))[3]; + my $defDB = TWiki::Func::getPreferencesValue("EPAGENTPLUGIN_DBID"); + + unless (exists $TWiki::cfg{Plugins}{EPAgentPlugin}) { + die "$TWiki::cfg{Plugins}{EPAgentPlugin} not defined"; + } + unless (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}) { + die "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases} not defined"; + } + my $rawDb = ""; + my $driverDb = ""; + my $userDb = ""; + my $pwdDb = ""; + my $cString = ""; + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}) { + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{driver}) { + my $rawDriver = $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{driver}; + if ($rawDriver =~/oracle/i) { + $driverDb = "Oracle"; + } elsif ($rawDriver =~/sqlite/i) { + $driverDb = "SQLite"; + } else { + $driverDb = "unknown"; + } + } else { + $driverDb = "unknown"; + } + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{database}) { + $rawDb = "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{database}"; + $rawDb =~ s/\$workarea/TWiki::Func::getWorkArea( $pluginName )/geo; + } else { + $rawDb = "unknown"; + } + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{username}) { + $userDb = "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{username}"; + } else { + $userDb = "unknown"; + } + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{password}) { + $pwdDb = "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{password}"; + } else { + $pwdDb = "unknown"; + } + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{connstring}) { + $cString = "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{connstring}"; + } else { + $cString = "unknown"; + } + } else { + die "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB} not defined"; + } + + my $connString = ""; + if ($driverDb eq "Oracle") { + my $db = DBI->connect('dbi:Oracle:', "$cString", ""); + return $db; + } elsif ($driverDb eq "SQLite") { + $connString = "dbi:SQLite:${rawDb}"; + my $db = DBI->connect($connString, $userDb, $pwdDb, {sqlite_use_immediate_transaction => 1, RaiseError => 1, AutoCommit => 1}); + return $db; + } else { + die "$this_subs_name = no viable database defined"; + } +} + +# ========================================================================== + +=begin twiki + +---+++ _readTopicText + +=cut + +sub _readTopic +{ + my( $theWeb, $theTopic ) = @_; + my ($mdata, $text) = &TWiki::Func::readTopic( $theWeb, $theTopic ); + # return raw topic text, including meta data + return $text; +} + +sub restGetMenu { +# https://www.jstree.com/ +# $('#using_json_2').jstree({ 'core' : { +# 'data' : [ +# { "id" : "ajson1", "parent" : "#", "text" : "Simple root node" }, +# { "id" : "ajson2", "parent" : "#", "text" : "Root node 2" }, +# { "id" : "ajson3", "parent" : "ajson2", "text" : "Child 1" }, +# { "id" : "ajson4", "parent" : "ajson2", "text" : "Child 2" }, +# ] +# } }); + + my($session, $params, $theTopic, $theWeb) = @_; + + my $query = TWiki::Func::getCgiQuery(); + my $returntext = ""; + my @errorArray = (); + my @outArray = (); + my $success = 1; + my $this_subs_name = (caller(0))[3]; + + # Get database connection + my $db = &_getConnection; + my $numRows = 0; + + # CREATE TABLE nodes ( id INTEGER PRIMARY KEY, parent INTEGER, internal INTEGER, name TEXT) + my $getSelStmt = $db->prepare_cached("SELECT id, parent, internal, name FROM nodes"); + $success &&= $getSelStmt->execute(); + my $all = $getSelStmt->fetchall_arrayref; + #if ($getSelStmt03->rows == 0) { + + my $text = "{\"core\":{\"data\":["; + my $commactr = 0; + foreach my $row (@$all) { + my ($aa, $bb, $cc, $dd) = @$row; + if ($commactr > 0) { + $text .= ","; + } + $commactr++; + if ($bb == 0) { + $bb = "#"; + } + $text .= "{\"id\":\"$aa\",\"parent\":\"$bb\",\"text\":\"$dd\",\"int\":\"$cc\"}"; + } + $text .= "]}}"; + + return $text; +} + + +sub restGetEntries { + my($session, $params, $theTopic, $theWeb) = @_; + + my $query = TWiki::Func::getCgiQuery(); + my $returntext = ""; + my @errorArray = (); + my @outArray = (); + my $success = 1; + my $this_subs_name = (caller(0))[3]; + + # metricType=IntCounter&metricName=RTBI|ActivationSpecs|ODMSTGA_C1M1|wberuntimeear:EventReceiver&metricValue=1 + + my %inhash = (); + my @requiredInput = ('metricName'); + foreach my $parmin (@requiredInput) { + $inhash{$parmin} = $query->param($parmin); + unless( $inhash{$parmin} ) { + push(@errorArray, "$this_subs_name - no $parmin"); + $session->writeWarning("$this_subs_name - no $parmin") if $debug; + } + } + + if (@errorArray) { + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } + + # Do first split + my @argArray = split(/:/, $inhash{'metricName'}); + if (@argArray != 2) { + push(@errorArray, "$this_subs_name - invalid metricName"); + $session->writeWarning("$this_subs_name - invalid metricName") if $debug; + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } + + # clean up name + (my $invlName = $argArray[1]) =~ s/[^a-zA-Z0-9_-]//g; + # remove spaces + $invlName =~ s/^\s+|\s+$//g; + if (length($invlName) == 0) { + push(@errorArray, "$this_subs_name - illegal interval name"); + $session->writeWarning("$this_subs_name - illegal interval name") if $debug; + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } + + # Do second split + my @pathArray = split(/\|/, $argArray[0]); + # Push interval on end of array + push @pathArray, $invlName; + my $parentID = 1; + my $isIntervalEntry = 1; + my @paCopy = @pathArray; + + # Get database connection + my $db = &_getConnection; + my $numRows = 0; + + foreach my $tpathLvl (@pathArray) { + (my $pathLvl = $tpathLvl) =~ s/[^a-zA-Z0-9_-]//g; + if (@paCopy == 1) { + $isIntervalEntry = 0; + } + my $newPID = &_handleDirectoryQuery(\$db, $parentID, $pathLvl, $isIntervalEntry); + if ($newPID =~/x/i) { + # !!!! NOTHING FOUND, SO SHOULD START CREATING + push(@errorArray, "$this_subs_name - entry not found"); + $session->writeWarning("$this_subs_name - entry not found") if $debug; + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } elsif ($newPID =~/f/i) { + # "f" means a mismatch, so fail + push(@errorArray, "$this_subs_name - mismatch type found"); + $session->writeWarning("$this_subs_name - mismatch type found") if $debug; + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } else { + $parentID = $newPID; + shift @paCopy; + } + } +# + #my $db = &_getConnection; + + my $getSelStmt = $db->prepare_cached("SELECT intval, ts FROM entries WHERE loc_id = ?"); + $success &&= $getSelStmt->execute($parentID); + my $all = $getSelStmt->fetchall_arrayref; + #if ($getSelStmt03->rows == 0) { + + my $text = "{\"notes\":["; + my $commactr = 0; + foreach my $row (@$all) { + my ($val, $date) = @$row; + if ($commactr > 0) { + $text .= ","; + } + $commactr++; + $text .= "{\"val\":\"$val\",\"ts\":\"$date\"}"; + } + + $text .= "]}"; + + return $text; +} + +=begin twiki + +---+++ handlePluginInfo + +=cut + +sub handlePluginInfo { + my ( $session, $params ) = @_; + my %options = %$params; + + my $text .= ""; + + my $db = &_getConnection; + + # Create a new statement handle to fetch table information + my $tabsth = $db->table_info(); + + my $ver = $db->{sqlite_version}; + #my $sth = $db->prepare("SELECT SQLITE_VERSION()"); + #$sth->execute(); + + #my $ver = $sth->fetch(); + + ### Print the header + $text .= " * DBI VERSION: $DBI::VERSION\n"; + $text .= " * DBD::SQLite VERSION: $DBD::SQLite::VERSION\n"; + $text .= "\n"; + $text .= "| *DB Version* | "; + #$text .= @$ver; + $text .= $ver; + $text .= " |\n\n"; + $text .= "| *Qualifier* | *Owner* | *Table Name* | *Type* | *Remarks* |\n"; + + ### Iterate through all the tables... + while ( my ( $qual, $owner, $name, $type, $remarks ) = + $tabsth->fetchrow_array() ) { + ### Tidy up NULL fields + foreach ($qual, $owner, $name, $type, $remarks) { + $_ = "N/A" unless defined $_; + } + ### Print out the table metadata... + $text .= "| $qual| $owner| $name | $type | $remarks |\n"; + } + + return $text; +} + +sub handleOracleInfo { + #use DBD::Oracle; + my ( $session, $params ) = @_; + my %options = %$params; + + my $text .= ""; + + #my $sth = $db->prepare("SELECT SQLITE_VERSION()"); + #$sth->execute(); + + #my $ver = $sth->fetch(); + + ### Print the header + $text .= " * DBI VERSION: $DBI::VERSION\n"; + #$text .= " * DBD::SQLite VERSION: $DBD::SQLite::VERSION\n"; + $text .= " * DBD::Oracle VERSION: $DBD::Oracle::VERSION\n"; + $text .= "\n"; + $text .= "| *DB Version* | "; + return $text; +} + +# ========================================================================== + +=begin twiki + +---+++ restTrackerReset + +=cut + +sub restTrackerReset { + my($session, $params, $theTopic, $theWeb) = @_; + + my $query = TWiki::Func::getCgiQuery(); + my $returntext = ""; + my $grouplist = $TWiki::cfg{Plugins}{EPAgentPlugin}{TrackerResetGroups} || ""; + my @groups = split(',', $grouplist ); + my $haveaccess = 0; + my @errorArray = (); + my @outArray = (); + my $user = $session->{user}; + my $this_subs_name = (caller(0))[3]; + + foreach my $group (@groups) { + if( TWiki::Func::isGroupMember($group)) { + $haveaccess = 1; + last; + } + } + + unless ($haveaccess) { + push(@errorArray, "$this_subs_name - must be member of one of groups in {Plugins}{EPAgentPlugin}{TrackerResetGroups}"); + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } + + my %inhash = (); + my @requiredInput = ('type'); + foreach my $parmin (@requiredInput) { + $inhash{$parmin} = $query->param($parmin); + unless( $inhash{$parmin} ) { + push(@errorArray, "$this_subs_name - no $parmin"); + $session->writeWarning("$this_subs_name - no $parmin") if $debug; + } + } + + if (@errorArray) { + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } + + if (($inhash{'type'} ne "sim") && ($inhash{'type'} ne "real")) { + push(@errorArray, "$this_subs_name - no valid value for 'type' passed"); + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } + + my $db = &_getConnection; + + my $numRows = 0; + + if ($inhash{'type'} eq "sim") { + # FOR SIMULATION + # DO TESTCASES TOO? + $numRows = $db->do("UPDATE milestones SET state = initstate"); + push(@outArray, "$this_subs_name - UPDATE milestones SET state = initstate: $numRows updated"); + $numRows = $db->do("UPDATE workflow SET state = initstate"); + push(@outArray, "$this_subs_name - UPDATE workflow SET state = initstate: $numRows updated"); + $numRows = $db->do("UPDATE apps SET state = initstate"); + push(@outArray, "$this_subs_name - UPDATE apps SET state = initstate: $numRows updated"); + $numRows = $db->do("UPDATE testcase SET state = initstate"); + push(@outArray, "$this_subs_name - UPDATE testcase SET state = initstate: $numRows updated"); + } else { + # FOR REAL DR + $numRows = $db->do("UPDATE milestones SET state = 'WAITING'"); + push(@outArray, "$this_subs_name - UPDATE milestones SET state = 'WAITING' $numRows updated"); + $numRows = $db->do("UPDATE workflow SET state = 'WAITING'"); + push(@outArray, "$this_subs_name - UPDATE workflow SET state = 'WAITING' $numRows updated"); + $numRows = $db->do("UPDATE apps SET state = 'WAITING'"); + push(@outArray, "$this_subs_name - UPDATE apps SET state = 'WAITING' $numRows updated"); + $numRows = $db->do("UPDATE testcase SET state = 'WAITING'"); + push(@outArray, "$this_subs_name - UPDATE testcase SET state = 'WAITING' $numRows updated"); + } + + # FOR ANY + $numRows = $db->do("UPDATE apps SET notifydate = NULL"); + push(@outArray, "$this_subs_name - UPDATE apps SET notifydate = NULL: $numRows updated"); + $numRows = $db->do("UPDATE milestones SET time = eta"); + push(@outArray, "$this_subs_name - UPDATE milestones SET time = eta: $numRows updated"); + #$db->do("UPDATE milestones SET duetime = strftime('%s','now')"); + + $numRows = $db->do("UPDATE milestones SET comptime = NULL, duetime = NULL"); + push(@outArray, "$this_subs_name - UPDATE milestones SET comptime = NULL, duetime = NULL: $numRows updated"); + $numRows = $db->do("UPDATE testcase SET comptime = NULL"); + push(@outArray, "$this_subs_name - UPDATE testcase SET comptime = NULL: $numRows updated"); + + $numRows = $db->do("UPDATE workflow SET currowner=(SELECT milestones.owner FROM milestones + LEFT JOIN wfms ON milestones.topic=wfms.milestone + LEFT JOIN workflow ON workflow.topic=wfms.workflow + WHERE + wfms.ord=(SELECT min(wfms.ord) FROM wfms WHERE wfms.workflow=workflow.topic AND wfms.hold = 0) + AND + wfms.workflow=workflow.topic)"); + push(@outArray, "$this_subs_name - UPDATE workflow SET currowner...: $numRows updated"); + + # Clear notes table + $numRows = $db->do("DELETE FROM notes"); + push(@outArray, "$this_subs_name - DELETE FROM notes: $numRows updated"); + $numRows = $db->do("DELETE FROM prnote"); + push(@outArray, "$this_subs_name - DELETE FROM prnote: $numRows updated"); + $numRows = $db->do("DELETE FROM problemregister"); + push(@outArray, "$this_subs_name - DELETE FROM problemregister $numRows updated"); + + $returntext = "{ \"resetData\": "; + + my $reaSize = @outArray; + my $firstTimeThru = 1; + if ($reaSize > 0) { + $returntext .= " { \"messages\": ["; + foreach my $inval (@outArray) { + if ($firstTimeThru) { + $firstTimeThru = 0; + } else { + $returntext .= ","; + } + $returntext .= "{ \"msg\": \"$inval\" }"; + } + $returntext .= " ] }"; + my $message = "Reset performed - type $inhash{'type'}"; + _writeAudit( $session, $user, 'r', 'Reset', $message ); + } + $returntext .= "}"; + + return $returntext; +} + +# ========================================================================== + +=begin twiki + +---+++ restInsertVal + +=cut + +sub restInsertVal { + use Time::Piece; + my($session, $params, $theTopic, $theWeb) = @_; + + my $query = TWiki::Func::getCgiQuery(); + my $returntext = ""; + my @errorArray = (); + my @outArray = (); + my $this_subs_name = (caller(0))[3]; + + # metricType=IntCounter&metricName=RTBI|ActivationSpecs|ODMSTGA_C1M1|wberuntimeear:EventReceiver&metricValue=1 + + my %inhash = (); + my @requiredInput = ('metricType','metricName','metricValue'); + foreach my $parmin (@requiredInput) { + $inhash{$parmin} = $query->param($parmin); + unless( $inhash{$parmin} ) { + push(@errorArray, "$this_subs_name - no $parmin"); + $session->writeWarning("$this_subs_name - no $parmin") if $debug; + } + } + + if (@errorArray) { + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } + + # Do first split + my @argArray = split(/:/, $inhash{'metricName'}); + if (@argArray != 2) { + push(@errorArray, "$this_subs_name - invalid metricName"); + $session->writeWarning("$this_subs_name - invalid metricName") if $debug; + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } + + # clean up name + (my $invlName = $argArray[1]) =~ s/[^a-zA-Z0-9_-]//g; + # remove spaces + $invlName =~ s/^\s+|\s+$//g; + if (length($invlName) == 0) { + push(@errorArray, "$this_subs_name - illegal interval name"); + $session->writeWarning("$this_subs_name - illegal interval name") if $debug; + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } + + # Do second split + my @pathArray = split(/\|/, $argArray[0]); + # Push interval on end of array + push @pathArray, $invlName; + my $parentID = 1; + my $isIntervalEntry = 1; + my @paCopy = @pathArray; + + # Get database connection + my $db = &_getConnection; + my $numRows = 0; + + foreach my $tpathLvl (@pathArray) { + (my $pathLvl = $tpathLvl) =~ s/[^a-zA-Z0-9_-]//g; + #print "found path level: $pathLvl \n"; + if (@paCopy == 1) { + #print "Size of array is 1\n"; + $isIntervalEntry = 0; + } + my $newPID = &_handleDirectoryQuery(\$db, $parentID, $pathLvl, $isIntervalEntry); + if ($newPID =~/x/i) { + # !!!! NOTHING FOUND, SO SHOULD START CREATING + # Send $parentID & @paCopy to routine to create new path(s) + $parentID = _createPathFromArray(\$db, $parentID, \@paCopy); + last; + } elsif ($newPID =~/f/i) { + # "f" means a mismatch, so fail + push(@errorArray, "$this_subs_name - mismatch type found"); + $session->writeWarning("$this_subs_name - mismatch type found") if $debug; + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } else { + $parentID = $newPID; + shift @paCopy; + } + } + my $rowsUpdated = _insertValue(\$db, $parentID, $inhash{'metricValue'}); + push(@outArray, "$inhash{'metricName'}: $rowsUpdated row(s) updated"); + + $returntext = "{ \"epagent\": "; + + my $reaSize = @outArray; + my $firstTimeThru = 1; + if ($reaSize > 0) { + $returntext .= " { \"messages\": ["; + foreach my $inval (@outArray) { + if ($firstTimeThru) { + $firstTimeThru = 0; + } else { + $returntext .= ","; + } + $returntext .= "{ \"msg\": \"$inval\" }"; + } + $returntext .= " ] }"; + } + $returntext .= "}"; + + return $returntext; +} + +sub _handleDirectoryQuery +{ + my $this_subs_name = (caller(0))[3]; + my $inDb = $_[0]; + my $inPid = $_[1]; + my $inMatch = $_[2]; + my $isIntNode = $_[3]; + my $db = $$inDb; + my $success = 1; + my $retVal = 'x'; + my $getSelStmt03 = $db->prepare_cached("SELECT closure.child, nodes.name, nodes.internal FROM closure JOIN nodes ON(closure.child = nodes.id) WHERE closure.parent = ? and depth = 1"); + $success &&= $getSelStmt03->execute($inPid); + my $allx = $getSelStmt03->fetchall_arrayref; + if ($getSelStmt03->rows == 0) { + # NO Children + return $retVal; + } else { + foreach my $rowx (@$allx) { + my ($ci, $ln, $ntype) = @$rowx; + if ($ln =~/$inMatch/i) { + #print "SUCCESS: match found! $ci:$ln:$ntype \n"; + if ($isIntNode != $ntype) { + # found match, but different type, so fail + #print "TYPE: Different type found \n"; + $retVal = 'f'; + last; + } + $retVal = $ci; + last; + } + } + } + return $retVal; +} + +sub _createPathFromArray +{ + my $this_subs_name = (caller(0))[3]; + my $inDb = $_[0]; + my $inPid = $_[1]; + my @inMatch = @{$_[2]}; + my $db = $$inDb; + my $success = 1; + my $retVal = 'x'; + my $iType = 1; + my @inCopy = @inMatch; + foreach my $spathLvl (@inMatch) { + if (@inCopy == 1) { + $iType = 0; + } + (my $xpathLvl = $spathLvl) =~ s/[^a-zA-Z0-9_-]//g; + #print "!! Will want to create: $xpathLvl \n"; + ## ADD NEW NODE + #print "Generating new num\n"; + my $newNode = $db->selectrow_array("SELECT max(id)+1 FROM nodes"); + #print "Inserting location\n"; + my $updateL_handle = $db->prepare_cached('INSERT INTO nodes (id, parent, name, internal) VALUES (?, ?, ?, ?)'); + $success &&= $updateL_handle->execute($newNode,$inPid,$xpathLvl,$iType); + #print "Inserting base LH\n"; + my $updateLH1_handle = $db->prepare_cached('INSERT INTO closure (parent, child, depth) VALUES (?, ?, ?)'); + $success &&= $updateLH1_handle->execute($newNode,$newNode,0); + #print "Inserting full LH\n"; + my $updateLH2_handle = $db->prepare_cached('INSERT INTO closure(parent, child, depth) SELECT p.parent, c.child, p.depth+c.depth+1 FROM closure p, closure c WHERE p.child = ? AND c.parent = ?'); + $success &&= $updateLH2_handle->execute($inPid,$newNode); + $inPid = $newNode; + shift @inCopy; + } + return $inPid; +} + +sub _insertValue +{ + my $this_subs_name = (caller(0))[3]; + my $inDb = $_[0]; + my $inPid = $_[1]; + my $inVal = $_[2]; + my $db = $$inDb; + my $retVal = 'x'; + my $updateTS_handle = $db->prepare_cached('INSERT INTO entries (loc_id, intval) VALUES (?, ?)'); + my $numRows = $updateTS_handle->execute($inPid,$inVal); + return $numRows; +} + +# ========================================================================== + +=begin twiki + +---+++ handleShowErrorCodes + +=cut + +sub handleShowErrorCodes { + my ( $session, $params ) = @_; + my %options = %$params; + + my $text .= ""; + my $inECref = &_getErrorCodeHash(); + my %errorCodes = %{$inECref}; + + $text .= "| *Code* | *Name* | *Desc & Help* |\n"; + for my $hkey ( keys %errorCodes ) { + $text .= "| $hkey| $errorCodes{$hkey}[0] | $errorCodes{$hkey}[1] |\n"; + } + + return $text; +} + + +sub handleListEnv { + my ( $session, $params ) = @_; + + my $text = ''; + + $text .= "<table>\n"; + $text .= "<tr><th> *Key* </th><th> *Value* </th></tr>\n"; + foreach (sort keys %ENV) { + $text .= "<tr><td> $_ </td><td> $ENV{$_} </td></tr>\n"; + } + $text .= "</table>\n"; + + return $text; +} + +sub _trim($) +{ + my $string = shift; + $string =~ s/^\s+//; + $string =~ s/\s+$//; + return $string; +} + +sub _returnJSONerror { + #my ( $code, $msg, $desc ) = @_; + my ( $code, $extraInfo ) = @_; + + my $text = "{"; + + my $inECref = &_getErrorCodeHash(); + my %errorCodes = %{$inECref}; + my @receivedErrors = @{$extraInfo}; + my $reaSize = @receivedErrors; + + if (exists $errorCodes{$code}) { + $text .= " \"errors\": {"; + $text .= " \"code\" : \"$code\","; + $text .= " \"message\" : \"$errorCodes{$code}[0]\","; + $text .= " \"description\" : \"$errorCodes{$code}[1]\""; + my $firstTimeThru = 1; + if ($reaSize > 0) { + $text .= ","; + $text .= " \"errors\" : ["; + foreach my $inval (@receivedErrors) { + if ($firstTimeThru) { + $firstTimeThru = 0; + } else { + $text .= ","; + } + $text .= "{ \"error\": \"$inval\" }"; + } + $text .= " ]"; + } + $text .= " }"; + } else { + $text .= " \"errors\": {"; + $text .= " \"code\" : \"$code\","; + $text .= " \"message\" : \"Bad error code\","; + $text .= " \"description\" : \"Why did you pass this undefined error code?\""; + $text .= " }"; + } + + $text .= "}"; + + return $text; +} + +# ========================================================================== + +=begin twiki + +---+++ _returnJSONoutput + +=cut + +sub _returnJSONoutput { + my ( $extraInfo ) = @_; + + my $text = "{"; + + my @receivedInput = @{$extraInfo}; + my $reaSize = @receivedInput; + + $text .= " \"outdata\": {"; + my $firstTimeThru = 1; + if ($reaSize > 0) { + # $text .= ","; + $text .= " \"info\" : ["; + foreach my $inval (@receivedInput) { + if ($firstTimeThru) { + $firstTimeThru = 0; + } else { + $text .= ","; + } + $text .= "{ \"msg\": \"$inval\" }"; + } + $text .= " ]"; + } + $text .= " }"; + + $text .= "}"; + + return $text; +} + +# ========================================================================== + +=begin twiki + +---+++ _getErrorCodeHash + * Definition of error codes + * Returns hash reference + +=cut + +sub _getErrorCodeHash { + # error codes, with array of [ 'base message', 'extended message & help' ] + my $errorCodes; + $errorCodes->{'1001'} = [ 'No parameter passed' , 'You must pass a parameter' ]; + $errorCodes->{'1002'} = [ 'Required parameter not passed: Xparmin' , 'You must provide the parameter' ]; + $errorCodes->{'1003'} = [ 'No data' , 'No data was returned from the database' ]; + $errorCodes->{'1004'} = [ 'No rows updated' , 'No data was updated in the database' ]; + $errorCodes->{'1010'} = [ 'Request must be POST' , 'Set the POST' ]; + $errorCodes->{'1011'} = [ 'Errors!' , 'Fix your errors' ]; + $errorCodes->{'1100'} = [ 'Delete failed' , 'Delete failed' ]; + $errorCodes->{'1101'} = [ 'Prepare failed' , 'Prepare failed' ]; + $errorCodes->{'1102'} = [ 'Update failed' , 'Update failed' ]; + $errorCodes->{'1103'} = [ 'TNX failed' , 'Transaction failed' ]; + return $errorCodes; +} + +# ========================================================================== + +=begin twiki + +---+++ _returnSQLHash + * SQL! + * Returns hash reference + +=cut + +sub _returnSQLHash { + my $trackerSql; + $trackerSql->{'allAppsNotOOS'} = "SELECT apps.topic, apps.name, apps.type, apps.pri, apps.rto, apps.description, apps.auto, apps.notifydate, apps.state FROM apps where apps.state <> 'OUTOFSCOPE'"; + $trackerSql->{'allApps'} = "SELECT apps.topic, apps.name, apps.type, apps.pri, apps.rto, apps.description, apps.auto, apps.state, apps.initstate FROM apps"; + $trackerSql->{'testCaseInfo'} = "SELECT apptc.app, apptc.testcase, testcase.state, testcase.name FROM apptc LEFT JOIN testcase ON apptc.testcase=testcase.topic"; + $trackerSql->{'milestoneGoodies'} = "SELECT appms.app, appms.milestone, milestones.state, milestones.duetime, milestones.comptime FROM appms LEFT JOIN milestones ON appms.milestone=milestones.topic"; + $trackerSql->{'appList'} = "SELECT apps.topic, apps.name, apps.type, apps.pri, apps.rto, apps.description, apps.state FROM apps"; + $trackerSql->{'testCaseList'} = "SELECT testcase.topic, testcase.name, testcase.description, testcase.importance FROM testcase"; + + # milestones(id INTEGER PRIMARY KEY, topic TEXT, name TEXT, owner TEXT, eta INTEGER, time INTEGER, description TEXT, initstate TEXT, cmems TEXT, state TEXT, basetime INTEGER, duetime INTEGER, comptime INTEGER, runnernote TEXT, forhotfail INTEGER, ack INTEGER) + # + #$trackerSql->{'milestoneList'} = "SELECT milestones.topic, milestones.name, milestones.owner, milestones.eta, milestones.time, milestones.description, milestones.initstate, milestones.state FROM milestones"; + $trackerSql->{'milestoneList'} = "SELECT milestones.topic, milestones.name, milestones.owner, milestones.eta, milestones.time, milestones.description, + milestones.initstate, milestones.state, milestones.basetime, milestones.duetime, milestones.comptime, + CASE WHEN EXISTS (SELECT wfms.workflow FROM wfms WHERE wfms.milestone = milestones.topic AND wfms.hold = 0) THEN '1' ELSE '0' END, + CASE WHEN EXISTS (SELECT wfms.workflow FROM wfms WHERE wfms.milestone = milestones.topic AND wfms.hold = 1) THEN '1' ELSE '0' END, + CASE WHEN EXISTS (SELECT mscl.parent FROM mscl WHERE mscl.parent = milestones.topic) THEN '1' ELSE '0' END, + CASE WHEN EXISTS (SELECT mscl.child FROM mscl WHERE mscl.child = milestones.topic) THEN '1' ELSE '0' END, + CASE WHEN EXISTS (SELECT appms.app FROM appms WHERE appms.milestone = milestones.topic) THEN '1' ELSE '0' END + FROM milestones"; + + $trackerSql->{'milestoneListNOOOS'} = "SELECT DISTINCT milestones.topic, milestones.name, milestones.owner, milestones.eta, milestones.time, milestones.description, + milestones.initstate, milestones.state, milestones.basetime, milestones.duetime, milestones.comptime, milestones.runnernote, + CASE WHEN EXISTS (SELECT wfms.workflow FROM wfms WHERE wfms.milestone = milestones.topic AND wfms.hold = 0) THEN '1' ELSE '0' END, + CASE WHEN EXISTS (SELECT wfms.workflow FROM wfms WHERE wfms.milestone = milestones.topic AND wfms.hold = 1) THEN '1' ELSE '0' END, + CASE WHEN EXISTS (SELECT mscl.parent FROM mscl WHERE mscl.parent = milestones.topic) THEN '1' ELSE '0' END, + CASE WHEN EXISTS (SELECT mscl.child FROM mscl WHERE mscl.child = milestones.topic) THEN '1' ELSE '0' END, + CASE WHEN EXISTS (SELECT appms.app FROM appms WHERE appms.milestone = milestones.topic) THEN '1' ELSE '0' END + FROM wfms LEFT JOIN milestones ON milestones.topic=wfms.milestone WHERE milestones.state <> 'OUTOFSCOPE' AND milestones.state <> 'COMPLETE'"; + #FROM milestones LEFT JOIN wfms ON milestones.topic=wfms.milestone WHERE milestones.state <> 'OUTOFSCOPE' AND milestones.state <> 'COMPLETE'"; + #FROM milestones WHERE milestones.state <> 'OUTOFSCOPE' AND milestones.state <> 'COMPLETE'"; + #FROM milestones INNER JOIN wfms ON wfms.milestone=milestones.topic WHERE milestones.state <> 'OUTOFSCOPE' AND milestones.state <> 'COMPLETE'"; + #my $availmsinfo = $db->selectall_arrayref("SELECT milestones.topic, milestones.name FROM milestones LEFT JOIN wfms ON milestones.topic=wfms.milestone WHERE wfms.milestone IS NULL"); + + return $trackerSql; +} + +# ========================================================================== + +=begin twiki + +---+++ _getSQL + +=cut + +sub _getSQL { + my ( $code ) = @_; + + my $inHashRef = &_returnSQLHash(); + my %sqlHash = %{$inHashRef}; + + if (exists $sqlHash{$code}) { + return $sqlHash{$code}; + } else { + my $rtnGarbage = "garbage"; + return $rtnGarbage; + } +} + +sub _pushInMatrix +{ + # http://www.troubleshooters.com/codecorn/littperl/perlsub.htm#Dereferencing_in_Place + my $incoming = $_[0]; + foreach my $row (@$incoming) { + push @{$_[1]}, \@$row; + } + +} + +# ========================================================================== + +=begin twiki + +---+++ _pushInHash + +=cut + +sub _pushInHash +{ + # return 1 for new hit found, zero for no hits + my $incoming = $_[0]; + my @newarray = @{$incoming}; + my $paramhash = $_[1]; + my $inSession = $_[2]; + my $session = $$inSession; + $session->writeWarning(" ==> inside _pushInHash"); + my $foundNewHit = 0; + foreach my $row (@newarray) { + my ($a, $b, $c) = @$row; + my $newkey = "${a}${b}${c}"; + unless (exists $paramhash->{$newkey}) { + $paramhash->{$newkey} = 'x'; + $foundNewHit = 1; + $session->writeWarning(" ==> _pushInHash: $newkey <=="); + } + } + return $foundNewHit; + +} + +# ========================================================================== + +=begin twiki + +---+++ _pushRowInMatrix + +=cut + +sub _pushRowInMatrix +{ + my @newarray = @{$_[0]}; + my $incoming = $_[0]; + push @{$_[1]}, \@newarray; +} + +# ========================================================================== + +=begin twiki + +---+++ _pushRowInHash + +=cut + +sub _pushRowInHash +{ + # return 1 for new hit found, zero for no hits + my @newarray = @{$_[0]}; + my $paramhash = $_[1]; + my $inSession = $_[2]; + my $session = $$inSession; + my $foundNewHit = 0; + my ($a, $b, $c, $d) = @newarray; + my $newkey = "${a}${b}${c}"; + unless (exists $paramhash->{$newkey}) { + $paramhash->{$newkey} = 'x'; + $foundNewHit = 1; + $session->writeWarning(" ==> _pushRowInHash key: $newkey") if $debug; + } + return $foundNewHit; + +} + +# ========================================================================== + +=begin twiki + +---+++ _pushStringInHash + +=cut + +sub _pushStringInHash +{ + # return 1 for new hit found, zero for no hits + my $newstring = $_[0]; + my $paramhash = $_[1]; + my $inSession = $_[2]; + my $session = $$inSession; + my $foundNewHit = 0; + unless (exists $paramhash->{$newstring}) { + $paramhash->{$newstring} = 'x'; + $foundNewHit = 1; + $session->writeWarning(" ==> _pushStringInHash key: $newstring") if $debug; + } + return $foundNewHit; + +} + +# ========================================================================== + +=begin twiki + +---+++ _bindAndExecute + +=cut + +sub _bindAndExecute +{ + my $localStatement = $_[0]; + my $parms = $_[1]; + foreach my $val (@{$parms}) { + $localStatement->bind_param( $val->[0], $val->[1] ); + } + $localStatement->execute(); +} + +# ========================================================================== + +=begin twiki + +---+++ _printHash + +=cut + +sub _printHash +{ + my $hashname = $_[0]; + my $hash_ref = $_[1]; + my $inSession = $_[2]; + my $session = $$inSession; + + while( my ($k, $v) = each %$hash_ref ) { + $session->writeWarning(" ==> _printHash \"$hashname\" key:$k value:$v "); + } +} + +1; + Added: twiki/trunk/EPAgentPlugin/working/work_areas/EPAgentPlugin/epagent.db =================================================================== (Binary files differ) Property changes on: twiki/trunk/EPAgentPlugin/working/work_areas/EPAgentPlugin/epagent.db ___________________________________________________________________ Added: svn:mime-type + application/octet-stream |