HAPI FHIR: how to read extension from custom datatype of standard resource? - hapi-fhir

I would like to add custom extension to Patient->telecom class by extending HAPI's ContactPoint class and adding new extension . So this is standard boilerplate code I took from https://hapifhir.io/hapi-fhir/docs/model/custom_structures.html
#DatatypeDef(name="MyContactPoint")
public class MyContactPoint extends ContactPoint implements ICompositeType {
private static final long serialVersionUID = 1L;
#Override
protected MyContactPoint typedCopy() {
MyContactPoint retVal = new MyContactPoint();
super.copyValues(retVal);
return retVal;
}
#Child(name="my-ext-value")
#Extension(definedLocally = false, isModifier = false, url = "http://someurl")
private BooleanType valueMyExtValue;
public Boolean getMyExtValue() {
return valueMyExtValue.getValue();
}
public MyContactPoint setMyExtValue(Boolean theValue) {
this.valueMyExtValue = new BooleanType(theValue);
return this;
}
}
And it works fine when I generate XML:
Patient data = new Patient();
MyContactPoint telecom = new MyContactPoint();
telecom.setMyExtValue(true);
data.addTelecom(telecom);
However, I cannot wrap my head how I can LOAD this data from XML to get strongly-typed MyContactPoint object? I know I can do telecom.getExtensionByUrl() etc and finally load it - but I was hoping there is a way to outsource this legwork to HAPI-FHIR by declaring extensions.
I know I can do it easily in "parent" profile like this:
#ResourceDef()
public class MyTask extends Task {
#Child(name="my-ext-value")
#Extension(definedLocally = false, isModifier = false, url = "http://someurl")
private BooleanType valueMyExtValue;
public Boolean getMyExtValue() {
return valueMyExtValue.getValue();
}
public MyTask setMyExtValue(Boolean theValue) {
this.valueMyExtValue = new BooleanType(theValue);
return this;
}
}
and then I load it as follows:
var fhirContext = FhirContext.forR4Cached();
var fhirParser = fhirContext.newXmlParser();
fhirParser.setPreferTypes(List.of(MyTask.class));
var res = fhirParser.parseResource(xml);
var myTask = (MyTask)res;
var theValue = myTask.getMyExtValue();
So that was easy for IBaseResource->custom extension flow. But how do I do this for IBaseResource->Custom DataType (overriding existing field!)->custom extension?

Related

Actionscript Classes: variable reference within method not recognized

Whenever I try to access a variable within a class method, Flash gives the error message: Access of undefined variable
This is true for variables vertices, i, deltap, etc. below. All of these should be defined for the whole class, as far as I can see. What am I missing?
package
{
import flash.display.Shape;
import flash.display.Graphics;
import fl.motion.Color;
public dynamic class Quadrilateral extends Shape {
public var vertices:Array = new Array();
public var endvertices:Array;
public var angle:Number;
public var mycolor:Color;
private var steps:Number;
private var deltap:Array = new Array(4);
private var i:Number;
public function Quadrilateral(vertexlist, fillcolor, stepcount=100) {
vertices = vertexlist;
mycolor = fillcolor;
steps = stepcount;
drawme()
}
public static function setfinal(vertexlist) {
endvertices = vertexlist;
for (i=0;i<4;i++) {
deltap[i] = (endvertices[i] - vertices[i])/100;
}
}
}
You are missing that the method is static, which means that you cannot access non static members from inside it.
That method should not be static.

Testing code in a custom NancyFx Bootstrapper

I have a custom Nancy Bootstrapper which uses StructureMapNancyBootstrapper but the issue is the same regardless of container.
public class CustomNancyBootstrapper : StructureMapNancyBootstrapper
{
protected override void RequestStartup(IContainer container, IPipelines pipelines, NancyContext context)
{
var auth = container.GetInstance<ICustomAuth>();
auth.Authenticate(context);
}
}
I want to write a test to assert that Authenticate is called with the context... something like this...
[Test]
public void RequestStartup_Calls_CustomAuth_Authenticate_WithContext()
{
// set up
var mockAuthentication = new Mock<ICustomAuth>();
var mockContainer = new Mock<IContainer>();
var mockPipelines = new Mock<IPipelines>();
var context = new NancyContext();
mockContainer.Setup(x => x.GetInstance<ICustomAuth>()).Returns(mockAuthentication.Object);
// exercise
_bootstrapper.RequestStartup(_mockContainer.Object, _mockPipelines.Object, context);
// verify
mockAuthentication.Verify(x => x.Authenticate(context), Times.Once);
}
The problem is that I can't call RequestStartup because it's protected as defined in NancyBootstrapperBase.
protected virtual void RequestStartup(TContainer container, IPipelines pipelines, NancyContext context);
Is there a "proper"/"offical" Nancy way to do this without creating another derived class and exposing the methods as that just seems like a hack?
Thanks
I guess you can "fake" the request by using Browser from Nancy.Testing:
var browser = new Browser(new CustomNancyBootstrapper());
var response = browser.Get("/whatever");
There is a good set of articles about testing NancyFx application:
http://www.marcusoft.net/2013/01/NancyTesting1.html
Turns out Nancy offers a IRequetStartup interface so you can take the code out of the custom bootstrapper and do something like this...
public class MyRequestStart : IRequestStartup
{
private readonly ICustomAuth _customAuthentication;
public MyRequestStart(ICustomAuth customAuthentication)
{
if (customAuthentication == null)
{
throw new ArgumentNullException(nameof(customAuthentication));
}
_customAuthentication = customAuthentication;
}
public void Initialize(IPipelines pipelines, NancyContext context)
{
_customAuthentication.Authenticate(context);
}
}
and the test is easy and concise
[Test]
public void When_Initialize_Calls_CustomAuth_Authenticate_WithContext()
{
// set up
var mockAuth = new Mock<ICustomAuth>();
var requestStartup = new MyRequestStart(mockAuth.Object);
var mockPipeline = new Mock<IPipelines>();
var context = new NancyContext();
// exercise
requestStartup.Initialize(mockPipeline.Object, context);
// verify
mockAuth.Verify(x => x.Authenticate(context), Times.Once);
}
https://github.com/NancyFx/Nancy/wiki/The-Application-Before%2C-After-and-OnError-pipelines#implementing-interfaces

Autofac.Extras.Quartz with ConcurrentExecutionDisallowed not working

In my Windows service I am using Quartz.net together with Autofac. To assist me here I am using the Nuget Autofac.Extras.Quartz.
So far so good, but when I try to apply the DisallowConcurrencyExecution attribute it is ignored and multiple jobs are spawned.
I am using as follows:
REGISTRATION
builder.RegisterModule(new QuartzAutofacFactoryModule());
builder.RegisterType<CompanyDatabaseProcessor>().As<IJob>().InstancePerLifetimeScope();
SETUP
var fact = container.Resolve<IJobFactory>();
_scheduler = StdSchedulerFactory.GetDefaultScheduler();
_scheduler.JobFactory = fact;
_scheduler.Start();
var job = JobBuilder.Create<IJob>()
.WithIdentity("QProcJob", "A3Group")
.Build();
var trigger = TriggerBuilder.Create()
.WithIdentity("QProcTrigger", "A3Group")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(executeEvery)
.RepeatForever())
.Build();
_scheduler.ScheduleJob(job, trigger);
and when in my IJob, I check the context.JobDetail.ConcurrentExecutionDisallowed it is always set to false.
I see this question is old, but I encountered the same problem and I going to post my solution, so it could be useful to someone.
The problem is that when you use JobFactory, the type of your job is unknown to quartz, so he assigns an internal type (NoOpJob) that is not decorated with DisallowConcurrentExecution attribute, causing that JobDetailImpl(the class that is used by quartz.net for IJobDetail) return false in ConcurrentExecutionDisallowed property.
What I did was a simple class that inherits from JobDetailImpl and add an extensions method Build to the JobBuilder class to maintain the same fluent code in the job creation. Here is the code:
public class SingleJobDetail : JobDetailImpl
{
public SingleJobDetail() : base()
{
}
public override bool ConcurrentExecutionDisallowed => true;
}
public static class JobHelper
{
public static IJobDetail Build(this JobBuilder builder, bool disallowConcurrent)
{
var job = builder.Build();
if (!disallowConcurrent)
return job;
var singleJob = new SingleJobDetail();
singleJob.JobType = job.JobType;
singleJob.Description = job.Description;
singleJob.Key = job.Key;
singleJob.Durable = job.Durable;
singleJob.RequestsRecovery = job.RequestsRecovery;
if (!singleJob.JobDataMap.IsEmpty)
singleJob.JobDataMap = job.JobDataMap;
return singleJob;
}
}
And in the job creation:
var job = JobBuilder.Create().WithIdentity(id).Build(true);

How can I archive my arg pack in Ocean for Petrel?

I have a custom Ocean workstep in Petrel, but I cannot succeed in persisting my arguments package. My package contains PillarGrid objects (Gird, Property, Zone) as shown below :
[Archivable(Version = 1, Release = "2013.6")]
public class MyArguments : DescribedArgumentsByReflection, IIdentifiable
{
[Archived]
private Grid grid = Grid.NullObject;
[Archived]
private int seedNumber;
[Archived]
private int numberRealizations = 1;
[Archived]
private Zone regionZone = Zone.NullObject;
[Archived]
private Property property = Property.NullObject;
[Archived]
private Droid droid = Droid.Empty;
...
public DeeSseArguments()
: base()
{
// adding this to datasource
IDataSourceManager dsManager = DataManager.DataSourceManager;
string DataSourceId = DeeSseDataSourceFactory.DataSourceId;
StructuredArchiveDataSource dataSource = dsManager.GetSource(DataSourceId) as StructuredArchiveDataSource;
this.droid = dataSource.GenerateDroid();
dataSource.AddItem(this.droid, this);
}
}
I created a DataSourceFactory based on a StructuredArchiveDataSource :
public class MyDataSourceFactory : DataSourceFactory
{
public static string DataSourceId = "MyArgsPackId";
public override Slb.Ocean.Core.IDataSource GetDataSource()
{
return new StructuredArchiveDataSource(DataSourceId, new[] { typeof(MyArguments) });
}
}
I registered this DataSourceFactory in he module method "integrate".
When I try to save my project in Petrel, I have the following error message : "System.Exception: MyArgsPackId: Not an archivable type 'Slb.Ocean.Petrel.DomainObject.PillarGrid.Property'"
How can I manage this persistence please ?
PillarGrid and other complex types cannot be persisted in this manner.
For IIdentifiable objects you should persist their DROID.
Later you can then retrieve the object from said DROID using DataManager.Resolve.
Chippy

How to assign/opt from multiple delegates for a 'moled' method?

I am currently examining Moles from the outside while I wait for my VS 2010 license, and I wonder whether Moles allows me to:
provide the ability to assígn multiple mole delegates for a method being moled, perhaps at a test fixture setup level?
switch in runtime in my test case, which of my mole delegates must be invoked for the upcoming call(s) to the moled method being isolated?
Any hints?
Best Answer:
It is much easier and makes far more sense to include gating logic in the detour method, than using two stubs for the same method! For example, MyMethod reads data from three different files on disk, each requiring different mock data to be returned. We may detour System.IO.File.OpenRead and gate the return value by analyzing the input parameters of OpenRead:
TEST METHOD:
[TestMethod]
[HostType("Moles")]
public void Test()
{
System.IO.Moles.MFile.OpenReadString = filePath => {
var mockStream = new System.IO.FileStream();
byte[] buffer;
switch (filePath)
{
case #"C:\DataFile.dat":
mockStream.Write(buffer, 0, 0); // Populate stream
break;
case #"C:\TextFile.txt":
mockStream.Write(buffer, 0, 0); // Populate stream
break;
case #"C:\LogFile.log":
mockStream.Write(buffer, 0, 0); // Populate stream
break;
}
return mockStream;
};
var target = new MyClass();
target.MyMethod();
}
TARGET TYPE:
using System.IO;
public class MyClass
{
public void MyMethod()
{
var fileAData = File.OpenRead(#"C:\DataFile.dat");
var fileBData = File.OpenRead(#"C:\TextFile.txt");
var fileCData = File.OpenRead(#"C:\LogFile.log");
}
}
Direct Answer to Your Questions:
Yes to #1: instantiate one type for each detour, and then use each for the desired behavior. And, yes to #2: act upon one instance of the mole type or the other. This requires addition of method input parameters or class constructor injection.
For example, MyMethod reads three data files from disk, and you need to pass back three different data mocks. MyMethod requires three parameters, an overtly intrusive solution. (Note input parameters are FileInfo type; because, System.IO>File is static and can not be instantiated: For example:
TEST METHOD:
[TestMethod]
[HostType("Moles")]
public void Test()
{
var fileInfoMoleA = new System.IO.Moles.MFileInfo();
fileInfoMoleA.OpenRead = () => { return new FileStream(); };
var fileInfoMoleB = new System.IO.Moles.MFileInfo();
fileInfoMoleB.OpenRead = () => { return new FileStream(); };
var fileInfoMoleC = new System.IO.Moles.MFileInfo();
fileInfoMoleC.OpenRead = () => { return new FileStream(); };
var target = new MyClass();
target.MyMethod(fileInfoMoleA, fileInfoMoleB, fileInfoMoleC);
}
TARGET TYPE:
using System.IO;
public class MyClass
{
// Input parameters are FileInfo type; because, System.IO.File
// is a static class, and can not be instantiated.
public void MyMethod(FileInfo fileInfoA, FileInfo fileInfoB, FileInfo fileInfoC)
{
var fileAData = fileInfoA.OpenRead();
var fileBData = fileInfoB.OpenRead();
var fileCData = fileInfoC.OpenRead();
}
}
UPDATE:
In response to #Chai comment, it is possible to create common methods, within the test project, that may be referenced as the mole detour delegate. For example, you may wish to write a common method that may be referenced by any unit test, that sets up a variety of pre-configured scenarios. The following example displays how a parameterized method could be used. Get creative -- they're just method calls!
TARGET TYPES:
namespace PexMoleDemo
{
public class MyClass
{
private MyMath _math;
public MyClass()
{
_math = new MyMath() { left = 1m, right = 2m };
}
public decimal GetResults()
{
return _math.Divide();
}
}
public class MyOtherClass
{
private MyMath _math;
public MyOtherClass()
{
_math = new MyMath() { left = 100m, right = 200m };
}
public decimal Divide()
{
return _math.Divide();
}
}
public class MyMath
{
public decimal left { get; set; }
public decimal right { get; set; }
public decimal Divide()
{
return left / right;
}
}
}
TEST METHODS:
ArrangeScenarios() sets up mole detours, by switching on the enumeration parameter. This allows the same scenarios to be erected, in a DRY manner, throughout many tests.
using System;
using Microsoft.Moles.Framework;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PexMoleDemo;
[assembly: MoledAssembly("PexMoleDemo")]
namespace TestProject1
{
[TestClass()]
public class ProgramTest
{
public enum Scenarios
{
DivideByZero,
MultiplyInsteadOfDivide
}
private void ArrangeScenario(Scenarios scenario)
{
switch (scenario)
{
case Scenarios.DivideByZero:
PexMoleDemo.Moles.MMyMath.AllInstances.rightGet =
instance => { return 0m; };
break;
case Scenarios.MultiplyInsteadOfDivide:
PexMoleDemo.Moles.MMyMath.AllInstances.Divide =
instance => { return instance.left * instance.right; };
break;
default:
throw new NotImplementedException("Invalid scenario.");
}
}
[TestMethod]
[HostType("Moles")]
[ExpectedException(typeof(DivideByZeroException))]
public void Test1()
{
ArrangeScenario(Scenarios.DivideByZero);
var target = new PexMoleDemo.MyClass();
var math = new PexMoleDemo.MyMath() { left = 1, right = 2 };
var left = math.left;
var right = math.right;
var actual = target.GetResults();
}
[TestMethod]
[HostType("Moles")]
public void Test2()
{
ArrangeScenario(Scenarios.MultiplyInsteadOfDivide);
// Perform some sort of test that determines if code breaks
// when values are multiplied instead of divided.
}
[TestMethod]
[HostType("Moles")]
[ExpectedException(typeof(DivideByZeroException))]
public void Test3()
{
ArrangeScenario(Scenarios.DivideByZero);
var target = new PexMoleDemo.MyOtherClass();
var math = new PexMoleDemo.MyMath() { left = 1, right = 2 };
var left = math.left;
var right = math.right;
var actual = target.Divide();
}
[TestMethod]
[HostType("Moles")]
public void Test4()
{
ArrangeScenario(Scenarios.MultiplyInsteadOfDivide);
// Perform some sort of test that determines if code breaks
// when values are multiplied instead of divided.
}
}
}