A little something I cooked up last night
# ./Get-C8Tuple ccl://localhost:6789/Stream/Default/Proj/outStream
param([string]$curl,[int]$maxRows=-1)
function Resolve-Url($url)
{
$wc = new-object Net.WebClient
$urib = [UriBuilder] $url
$urib.Scheme = "http"
$urib.Path= "/Manager/ResolveUri"
$wc.UploadString($urib.uri,$url)
}
function Get-TD($url)
{
$urib = [UriBuilder] $url
$urib.Scheme = "http"
$urib.Path= "/Manager"
$wc = new-object Net.WebClient
$wc.Headers.Add("Content-Type",'application/soap+xml; charset=utf-8; action="urn:coral8.com:SOAPAction"')
$soapBody = "<soap:Envelope xmlns:soap='http://www.w3.org/2003/05/soap-envelope' xmlns:soapenc='http://www.w3.org/2003/05/soap-encoding' xmlns:tns='urn:coral8.com:Manager' xmlns:types='urn:coral8.com:Manager/encodedTypes' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'><soap:Body> <tns:GetTD><uri xsi:type='xsd:string'>$url</uri></tns:GetTD></soap:Body></soap:Envelope>"
$soapResp = $wc.UploadString($urib.uri,$soapBody)
$td = ([xml]$soapResp).Envelope.Body.GetTDResponse.Return."#text"
([xml]$td).TupleDescriptor.Field
}
function ConvertFrom-C8CSV($csv,$names,$types)
{
# TODO - support quoted csv values
$vals = $csv.Split(",")
$o = new-object PSObject
for ($ii=0;$ii -lt $vals.Count;$ii++)
{
$t = $types[$ii]
if ($t -eq "datetime")
{
$v = ([datetime]"1/1/1970 GMT").AddTicks( ([long]$vals[$ii]) * 10 )
}
else
{
$v = $vals[$ii] -as $t
}
$o | add-member -membertype noteproperty -name $names[$ii] -value $v
}
return $o
}
function ConvertFrom-C8TypeName([string] $c8Type)
{
switch -wildcard ($c8Type)
{
"Integer*" { return "int" }
"Long*" { return "long" }
"Float*" {return "double" }
"Bool*" { return "bool" }
"String*" { return "string" }
"Time*" { return "datetime" }
"XML*" { return "xml" }
default { throw "Type '$c8Type' not implemented" }
}
}
write-progress "Resolve URL" "Pending"
$url = Resolve-Url $curl
$td = Get-TD $curl
$fieldNames = @("Timestamp") + ($td | % { $_.Name })
$fieldTypes = @("datetime") + ($td | % { ConvertFrom-C8TypeName $_.type })
write-progress "Resolve URL" "Done"
$urib = [UriBuilder] $url
$urib.Scheme = "http"
$req = [Net.WebRequest]::Create($urib.uri)
$req.Headers.Add('X-C8-StreamFormat', 'CSV')
$req.Headers.Add('X-C8-StreamFormatOptions', 'TitleRow=false')
$req.Method = "GET"
$resp = $req.GetResponse()
$rdr = [IO.StreamReader] $resp.GetResponseStream()
$cnt=0
while ($MaxRows -eq -1 -or $cnt -lt $MaxRows)
{
write-progress "Reading tuples" "in progress" -currentOperation "count - $cnt"
$csv = $rdr.ReadLine()
ConvertFrom-C8CSV $csv $fieldNames $fieldTypes
$cnt++
}
$resp.Close()
Code comments -
- I couldn't find a WSDL for the manager service or a light weight .net/powershell SOAP api, so I had to resort to sending in a canned request.
- A nice Powershell feature is how the casting operator will search the type's constructors to new up the object needed. I love it.
So my coworker, err boss :) seems to have started playing with Powershell, which is great. It looks like his first foray into PowerShell development is a commandlet for tibco ems topics. My initial feeling on this is that the benefits of commandlets syntax checking are not worth the tax of compiling and installing it. I would've used a native PowerShell approach. On the other hand, a full navigation provider...
function Get-TibcoTopic([string]$topicName,
[string]$url="tcp://localhost:7222",
[string]$username="admin",
[string]$password)
{
$null = [Reflection.Assembly]::LoadFrom("C:\tibco\ems\clients\cs\TIBCO.EMS.dll")
$null = [Reflection.Assembly]::LoadFrom("C:\tibco\ems\clients\cs\TIBCO.EMS.ADMIN.dll")
$admin = new-object TIBCO.EMS.ADMIN.Admin -arg $url, $username, $password
$admin.Topics | ? { $_.Name -eq $topicName }
}
But I am seeing this a lot with myself and coworkers around new technologies. I guess the first step in learning a technology is getting something that works, and the second phase is getting something implemented the right way. For me, I'm struggling with WPF. I wanted to implement a bullet graph
and do with the right way so that if I wanted a more traditional gauge approach, highway just need to swap out the template. I couldn't get it to work so I switched to implementing the control as the panel. It feels wrong, and I know I'm going to run into trouble with it shortly, but at least it works.