Iterate through a FHIR element binding - hl7-fhir

I'm trying to iterate through a FHIR capability statement to pull down a list of all the questions and values sets that are supported by the server.
I have a downloaded FHIR capability statement, and subsequent structure definition and within the structure definition I am iterating through each snapshot element.
Some of the elements have a binding, which I can see is correctly populated from the console and debug break points but I can't determine the correct way to access this in code.
For example, the immediate window is giving me the following information about the element.Binding.ValueSet:
element.Binding.ValueSet
{url: http://hl7.org/fhir/ValueSet/adverse-event-category}
Children: {Hl7.Fhir.Model.ResourceReference.<get_Children>d__32}
Display: null
DisplayElement: null
ElementId: null
Extension: Count = 0
Identifier: null
IsContainedReference: false
NamedChildren: {Hl7.Fhir.Model.ResourceReference.<get_NamedChildren>d__34}
Reference: "http://hl7.org/fhir/ValueSet/adverse-event-category"
ReferenceElement: {Value="http://hl7.org/fhir/ValueSet/adverse-event-category"}
Type: null
TypeElement: null
TypeName: "Reference"
Url: {http://hl7.org/fhir/ValueSet/adverse-event-category}
Results View: Expanding the Results View will enumerate the IEnumerable
But I can't access these "Properties", for example:
element.Binding.ValueSet.Reference returns
element.Binding.ValueSet.Reference
error CS1061: 'DataType' does not contain a definition for 'Reference' and no accessible extension method 'Reference' accepting a first argument of type 'DataType' could be found (are you missing a using directive or an assembly reference?)
When I interrogate the type or properties I get the following:
element.Binding.ValueSet.GetType() (results abridged)
{Name = "ResourceReference" FullName = "Hl7.Fhir.Model.ResourceReference"}
Assembly: {Hl7.Fhir.Support.Poco, Version=4.3.0.0, Culture=neutral, PublicKeyToken=d706911480550fc3}
AssemblyQualifiedName: "Hl7.Fhir.Model.ResourceReference, Hl7.Fhir.Support.Poco, Version=4.3.0.0, Culture=neutral,
PublicKeyToken=d706911480550fc3"
BaseType: {Name = "DataType" FullName = "Hl7.Fhir.Model.DataType"}
DeclaredNestedTypes: {System.Reflection.TypeInfo.<get_DeclaredNestedTypes>d__22}
DeclaredProperties: {System.Reflection.PropertyInfo[13]}
FullName: "Hl7.Fhir.Model.ResourceReference"
Module (System.Reflection.MemberInfo): {Hl7.Fhir.Support.Poco.dll}
Module: {Hl7.Fhir.Support.Poco.dll}
Name: "ResourceReference"
Namespace: "Hl7.Fhir.Model"
UnderlyingSystemType: {Name = "ResourceReference" FullName = "Hl7.Fhir.Model.ResourceReference"}
element.Binding.ValueSet.GetType().GetProperties()
{System.Reflection.PropertyInfo[14]}
[0]: {System.String TypeName}
[1]: {Hl7.Fhir.Model.FhirString ReferenceElement}
[2]: {System.String Reference}
[3]: {Hl7.Fhir.Model.FhirUri TypeElement}
[4]: {System.String Type}
[5]: {Hl7.Fhir.Model.Identifier Identifier}
[6]: {Hl7.Fhir.Model.FhirString DisplayElement}
[7]: {System.String Display}
[8]: {System.Collections.Generic.IEnumerable'1[Hl7.Fhir.Model.Base] Children}
[9]: {System.Collections.Generic.IEnumerable'1[Hl7.Fhir.Model.ElementValue]
NamedChildren}
[10]: {System.Uri Url}
[11]: {Boolean IsContainedReference}
[12]: {System.String ElementId}
[13]: {System.Collections.Generic.List`1[Hl7.Fhir.Model.Extension] Extension}
I can convert this object to a list, it appears to be some enumerable of KVPs:
element.Binding.ValueSet.ToList()
Count = 1
[0]: {[reference, {Value=http://hl7.org/fhir/ValueSet/adverse-event-category}]}
But calling for the element.Binding.ValueSet.Keys or element.Binding.ValueSet.Values does not work either
What is the correct way to work with this object?

Assuming you are using FHIR STU3, element.Binding.ValueSet will be of the generic DataType which can mean any of the FHIR datatypes, since this element is a choice property and could be either of type Reference or Uri.
The way to access the data inside is to cast the ValueSet property to ResourceReference or use as ResourceReference, after which you'll be able to access the reference properties.

Related

Apple FAX printer using ipp-server configuration for faxout does not transmit the phone number

I am working on a IPP-FAX client.
I am using the ippserver stuff from: https://github.com/istopwg/ippsample.git
I have a small configuration that provides two printers.
However, when I use the fax-job.test from the library, my client receives the phone number: IPP_DESTINATION_URIS='{destination-uri=tel:4055551212},{destination-uri=ipp://11.22.33.44/ipp/print print-quality=high media=na_letter_8.5x11in}'
As expected.
But: when I use the same ipp-device as a fax from apple's printer menues, the pages are sent, but the destination-uri are not send (not included in the IPP transmission).
I am using the following in the service:
[root#Comp ~/Printing/ippsample3]# perl -ne 's/#.*//; print unless /^\s*$/' t2/print/faxout.conf
MAKE "thilo"
MODEL "(GPL Ghostscript)"
DeviceURI ipp://Comp.local/ipp/print
Attr textWithoutLanguage printer-device-id "MFG:XSimulated;MDL:Fax;CMD:URF;URF:W8,SRGB24,CP255,PQ4,RS200-300-600,V1.4;MINSIZE:1x5in;MAXSIZE:8.5x14in;TEST-MARGINS:0 0 0 0;TEST-NO-PNG:1;TEST-NO-PDF:1;TEST-FAX:1;"
Command /root/Printing/ippsample3/hell.sh
ATTR keyword urf-supported "W8","SRGB24","ADOBERGB24-48","DM3","CP255","OFU0","IS1-4-5-7","IFU0","MT1-2-3-7-8-9-10-11-12","OB9","PQ3-4-5","RS300-600","V1.4"
ATTR keyword job-creation-attributes-supported "copies","confirmation-sheet-print","cover-sheet-info","destination-uris","media","media-col","multiple-document-handling","number-of-retries","page-ranges","print-quality","printer-resolution","retry-interval","retry-time-out"
ATTR uriScheme destination-uri-schemes-supported "tel"
ATTR boolean ipp-attribute-fidelity true
ATTR boolean confirmation-sheet-print-default false
ATTR integer number-of-retries-default 1
ATTR integer retry-interval-default 15
ATTR keyword cover-sheet-info-supported "date-time","from-name","subject","to-name","message"
ATTR no-value cover-sheet-info-default
ATTR rangeOfInteger number-of-retries-supported 0-1
ATTR rangeOfInteger retry-interval-supported 15-60
ATTR uri printer-icons "http://Comp.local:8632/icons/fax.png","http://Comp.local:8632/icons/large/fax.png"
ATTR uri printer-more-info "http://Comp.local:8632/"
ATTR uri printer-supply-info-uri "http://Comp.local:8632/"
ATTR uri printer-uuid "urn:uuid:3f63711e-bcc3-3570-707e-cc14008da4b6"
ATTR keyword uri-authentication-supported "none","none"
ATTR keyword uri-security-supported "tls","tls"
ATTR uri printer-geo-location "geo:37.33182,122.03118"
ATTR uri device-uri "urf:///1+1"
from reading http://ftp.pwg.org/pub/pwg/candidates/cs-ippfaxout10-20140618-5100.15.pdf . I understand that the destination-uris would be mandatory in the job descriptor.
I either fail to teach the IPP-server to require if from the client, or I fail to configure the client correctly.
From: https://github.com/michaelrsweet/libcups/raw/f06f42779f98073e2ba782a7a73ebf54636b60d0/examples/fax-job.test
GROUP job-attributes-tag
ATTR collection destination-uris {
MEMBER uri destination-uri tel:4055551212
},{
MEMBER uri destination-uri ipp://11.22.33.44/ipp/print
MEMBER enum print-quality 5
MEMBER keyword media na_letter_8.5x11in
}
Any hints how the service should be configured to make apple printer also send this scheme?
It seems, that once the faxout uri is changed in the server sources to use '/ipp/faxout' instead of the (I think also standard compliant) /ipp/print/faxout, Apple is sending the destination-uri
and the script gets the environment variable: IPP_DESTINATION_URIS='{destination-uri=tel:1234567890123456}
as expected.

Puppet 6 and module puppetlabs/accounts does not create user account in Hiera YAML format

When I run puppet agent --test I have no errors output but the user did not create.
My puppet hira.yaml configuration is:
---
version: 5
datadir: "/etc/puppetlabs/code/environments"
data_hash: yaml_data
hierarchy:
- name: "Per-node data (yaml version)"
path: "%{::environment}/nodes/%{::trusted.certname}.yaml"
- name: "Common YAML hierarchy levels"
paths:
- "defaults/common.yaml"
- "defaults/users.yaml"
users.yaml is:
accounts::user:
joed:
locked: false
comment: System Operator
uid: '1700'
gid: '1700'
groups:
- admin
- sudonopw
sshkeys:
- ssh-rsa ...Hw== sysop+moduledevkey#puppetlabs.com
I use this module
Nothing in Hiera data itself causes anything to be applied to target nodes. Some kind of declaration is required in a manifest somewhere or in the output of an external node classifier script. Moreover, the puppetlabs/accounts module provides only defined types, not classes. You can store defined-type data in Hiera and read it back, but automated parameter binding via Hiera applies only to classes, not defined types.
In short, then, no user is created (and no error is reported) because no relevant resources are declared into the target node's catalog. You haven't given Puppet anything to do.
If you want to apply the stored user data presented to your nodes, you would want something along these lines:
$user_data = lookup('accounts::user', Hash[String,Hash], 'hash', {})
$user_data.each |$user,$props| {
accounts::user { $user: * => $props }
}
That would go into the node block matched to your target node, or, better, into a class that is declared by that node block or an equivalent. It's fairly complicated for so few lines, but in brief:
the lookup function looks up key 'accounts::user' in your Hiera data
performing a hash merge of results appearing at different levels of the hierarchy
expecting the result to be a hash with string keys and hash values
and defaulting to an empty hash if no results are found;
the mappings in the result hash are iterated, and for each one, an instance of the accounts::user defined type is declared
using the (outer) hash key as the user name,
and the value associated with that key as a mapping from parameter names to parameter values.
There are a few problems here.
You are missing a line in your hiera.yaml namely the defaults key. It should be:
---
version: 5
defaults: ## add this line
datadir: "/etc/puppetlabs/code/environments"
data_hash: yaml_data
hierarchy:
- name: "Per-node data (yaml version)"
path: "%{::environment}/nodes/%{::trusted.certname}.yaml"
- name: "Common YAML hierarchy levels"
paths:
- "defaults/common.yaml"
- "defaults/users.yaml"
I detected that using the puppet-syntax gem (included if you use PDK, which is recommended):
▶ bundle exec rake validate
Syntax OK
---> syntax:manifests
---> syntax:templates
---> syntax:hiera:yaml
ERROR: Failed to parse hiera.yaml: (hiera.yaml): mapping values are not allowed in this context at line 3 column 10
Also, in addition to what John mentioned, the simplest class to read in your data would be this:
class test (Hash[String,Hash] $users) {
create_resources(accounts::user, $users)
}
Or if you want to avoid using create_resources*:
class test (Hash[String,Hash] $users) {
$users.each |$user,$props| {
accounts::user { $user: * => $props }
}
}
Note that I have relied on the Automatic Parameter Lookup feature for that. See the link below.
Then, in your Hiera data, you would have a key named test::users to correspond (class name "test", key name "users"):
---
test::users: ## Note that this line changed.
joed:
locked: false
comment: System Operator
uid: '1700'
gid: '1700'
groups:
- admin
- sudonopw
sshkeys:
- ssh-rsa ...Hw== sysop+moduledevkey#puppetlabs.com
Use of automatic parameter lookup is generally the more idiomatic way of writing Puppet code compared to calling the lookup function explicitly.
For more info:
PDK
Automatic Parameter Lookup
create_resources
(*Note that create_resources is "controversial". Many in the Puppet community prefer not to use it.)

pyyaml parse data with tag

I have yaml data like the input below and i need output as key value pairs
Input
a="""
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
code:
- '716'
- '718'
id:
- 488
- 499
"""
ouput needed
{'code': ['716', '718'], 'id': [488, 499]}
The default constructor was giving me an error. I tried adding new constructor and now its not giving me error but i am not able to get key value pairs.
FYI, If i remove the !ruby/hash:ActiveSupport::HashWithIndifferentAccess line from my yaml then it gives me desired output.
def new_constructor(loader, tag_suffix, node):
if type(node.value)=='list':
val=''.join(node.value)
else:
val=node.value
val=node.value
ret_val="""
{0}
""".format(val)
return ret_val
yaml.add_multi_constructor('', new_constructor)
yaml.load(a)
output
"\n [(ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'code'), SequenceNode(tag=u'tag:yaml.org,2002:seq', value=[ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'716'), ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'718')])), (ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'id'), SequenceNode(tag=u'tag:yaml.org,2002:seq', value=[ScalarNode(tag=u'tag:yaml.org,2002:int', value=u'488'), ScalarNode(tag=u'tag:yaml.org,2002:int', value=u'499')]))]\n "
Please suggest.
This is not a solution using PyYAML, but I recommend using ruamel.yaml instead. If for no other reason, it's more actively maintained than PyYAML. A quote from the overview
Many of the bugs filed against PyYAML, but that were never acted upon, have been fixed in ruamel.yaml
To load that string, you can do
import ruamel.yaml
parser = ruamel.yaml.YAML()
obj = parser.load(a) # as defined above.
I strongly recommend following #Andrew F answer, but in case you
wonder why your code did not get the proper result, that is because
you don't correctly process the node under the tag in your tag
handling.
Although the node's value is a list (of tuples with key value pairs),
you should test for the type of the node itself (using isinstance)
and then hand it over to the "normal" mapping processing routine as
the tag is on a mapping:
import yaml
from yaml.loader import SafeLoader
a = """\
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
code:
- '716'
- '718'
id:
- 488
- 499
"""
def new_constructor(loader, tag_suffix, node):
if isinstance(node, yaml.nodes.MappingNode):
return loader.construct_mapping(node, deep=True)
raise NotImplementedError
yaml.add_multi_constructor('', new_constructor, Loader=SafeLoader)
data = yaml.load(a, Loader=SafeLoader)
print(data)
which gives:
{'code': ['716', '718'], 'id': [488, 499]}
You should not use PyYAML's yaml.load(), it is documented to be potentially unsafe
and above all it is not necessary. Just add the new constructor to the SafeLoader.

API Blueprint and Dredd - Required field missing from response, but tests still pass

I am using a combination of API Blueprint and Dredd to test an API my application is dependent on. I am using attributes in API blueprint to define the structure of the response's body.
Apparently I'm missing something though because the tests always pass even though I've purposefully defined a fake "required" parameter that I know is missing from the API's response. It seems that Dredd is only testing whether the type of the response body (array) rather than the type and the parameters within it.
My API Blueprint file:
FORMAT: 1A
HOST: http://somehost.net
# API Title
## Endpoints [GET /endpoint/{date}]
+ Parameters
+ date: `2016-09-01` (string, required) - Date
+ Response 200 (application/json; charset=utf-8)
+ Attributes (array[Data])
## Data Structures
### Data
- realParameter: 2432432 (number)
- realParameter2: `some string` (string, required)
- realParameter3: `Something else` (string, required)
- realParameter4: 1 (number, required)
- fakeParam: 1 (number, required)
The response body:
[
{
"realParameter": 31,
"realParameter2": "some value",
"realParameter3": "another value",
"realParameter4": 8908
},
{
"realParameter": 54,
"realParameter2": "something here",
"realParameter3": "and here too",
"realParameter4": 6589
}
]
And my Dredd config file:
reporter: apiary
custom:
apiaryApiKey: somekey
apiaryApiName: somename
dry-run: null
hookfiles: null
language: nodejs
sandbox: false
server: null
server-wait: 3
init: false
names: false
only: []
output: []
header: []
sorted: false
user: null
inline-errors: false
details: false
method: []
color: true
level: info
timestamp: false
silent: false
path: []
blueprint: myApiBlueprintFile.apib
endpoint: 'http://ahost.com'
Does anyone have any idea why Dredd ignores the fact that "fakeParameter" doesn't actually show up in the response body and still allows the test to pass?
You've run into a limitation of MSON, the language API Blueprint uses for describing attributes. In many cases, MSON describes what MAY be present in the data structure rather than what MUST exactly be present.
The most prominent case are arrays, where basically any content of the array is optional and thus the underlying generated JSON Schema doesn't put any constraints on array contents. Dredd just respects that, so indirectly it becomes a Dredd issue too, however there's not much Dredd can do about it.
There's an issue for the problem: apiaryio/mson#66 You can follow and comment under the issue to get updated about this. Dredd is usually very prompt in getting the latest API Blueprint parser, so once it's implemented in the language itself, it won't take long to appear in Dredd.
Obvious (but tedious) workaround is to specify your own JSON Schema with stricter rules using the + Schema section alongside the + Attributes section.

Acceleo java wrapping service doesn't take complex parameter - Invalid result for expression self.invoke

I can't call a java wrapping service in Acceleo because it doesn't recognize parameters type. This is my simple test code: the main calls a query stored in Services.mtl, that calls the java service that just return the name of an object "Send"
Main.mtl
[file ('system.P', false, 'UTF-8')]
[for (t : Send | aSystemBehavior.transitions)) ]
[getName(t)/]
[/for]
[/file]
Services.mtl
[query public getName(arg0 : Send) : String
= invoke('myPackage.Services', 'getName(myPackage.Send)', Sequence{arg0})
/]
Services.java
public class Services
{
public String getName(Send t)
{return t.getName();}
}
The Error Log shows:
Invalid result for expression
self.invoke('myPakage.Services',
'getName(myPakage.Send)', Sequence {arg0}) at line 0 in
Module services for query getName(Send). Last recorded value of self
was org.eclipse.emf.ecore.impl.DynamicEObjectImpl#1f00eb36 (eClass:
org.eclipse.emf.ecore.impl.EClassImpl#2c2aade3 (name: Send)
(instanceClassName: null) (abstract: false, interface: false)).
Problem found while generating the file system.P'.
If I use a String as parameter type instead of Send, everything works fine.
Does the package containing the service "Services" has been exported? If not, open the file MANIFEST.MF, go in the runtime tab and add its package to the list of exported packages. Are you sure that your "Send" object has a name? This message only indicates that null was returned by the query getName.
I don't have anymore this problem... I created a new Acceleo project from scratch, and it works. I am not sure what was the problem... maybe it's something about che choice of metamodels to import during the creation of the Module (I have to choose between run-tim and develop-time metamodel).

Resources