Add non-standard segments with nhapi - mirth

My system has to generate an xml in which the node ORM_O01.ORDER_DETAIL must contain the node ORM_O01.OBRRQDRQ1RXOODSODT_SUPPGRP, because it has to communicate with Mirth.
I am using the nhapi library version 2.5, in which this node does not contain it.
var obr = _ormO01Message.GetORDER().ORDER_DETAIL.OBR;
obr.SetIDOBR.Value = "1";
obr.PlacerOrderNumber.EntityIdentifier.Value = "123456";
obr.PlacerOrderNumber.NamespaceID.Value = "6543";
obr.PlacerOrderNumber.UniversalID.Value = "10009";
obr.UniversalServiceIdentifier.Identifier.Value = "NS";
Is it possible to add a node in ORM_O01.ORDER_DETAIL that is not standard?
Thanks.
<ORM_O01.ORDER_DETAIL>
<ORM_O01.OBRRQDRQ1RXOODSODT_SUPPGRP>
<OBR>
<OBR.1>1</OBR.1>
<OBR.2>
<EI.1>123456</EI.1>
<EI.2>6543</EI.2>
<EI.3>10009</EI.3>
</OBR.2>
<OBR.4>
<CE.1>NS</CE.1>
</OBR.4>
</OBR>
</ORM_O01.OBRRQDRQ1RXOODSODT_SUPPGRP>
</ORM_O01.ORDER_DETAIL>

ORM_O01.OBRRQDRQ1RXOODSODT_SUPPGRP looks like it actually is standard for 2.5, but neither nhapi or hapi (which mirth uses) include it. I wouldn't worry about trying to add it in because mirth probably wouldn't be able to parse it if you did.
See similar issue where a mirth user needed to strip that group out.

Related

Scala Netty is there any way to share a ReplayingDecoder

I am looking to open up multiple connections using a netty client bootstrap in order to parse messages coming from multiple sources. The messages all have the same format, however, due to the amount of data that needs to be processed, I must run each connection on separate threads (This is assuming netty creates a thread per client channel, which I couldn't find a reference for - if that's not the case, how would this be achieved?).
This is the code that I use to connect to the data server:
var b = new Bootstrap()
.group(group)
.channel(classOf[NioSocketChannel])
.handler(RawFeedChannelInitializer)
var ch1 = b.clone().connect(host, port).sync().channel();
var ch2 = b.clone().connect(host, port).sync().channel();
The initializer calls RawPacketDecoder, which extends ReplayingDecoder, and is defined here.
The code works well without #Sharable when opening a single connection, but for the purpose of my application I must connect to the same server multiple times.
This results in the runtime error #Sharable annotation is not allowed pointing to my RawPacketDecoder class.
I am not entirely sure on how to get past this issue, short of reimplementing in scala an instantiable class of ReplayingDecoder as my decoder based directly on ByteToMessageDecoder.
Any help would be greatly appreciated.
Note: I am using netty 4.0.32 Final
I found the solution in this StockExchange answer.
My issue was that I was using an object based ChannelInitializer (singleton), and ReplayingDecoder as well as ByteToMessageDecoder are not sharable.
My initializer was created as a scala object, and therefore a single instance allowed. Changing the initializer to a scala class and instantiating for each bootstrap clone solved the problem. I modified the bootstrap code above as follows:
var b = new Bootstrap()
.group(group)
.channel(classOf[NioSocketChannel])
//.handler(RawFeedChannelInitializer)
var ch1 = b.clone().handler(new RawFeedChannelInitializer()).connect(host, port).sync().channel();
var ch2 = b.clone().handler(new RawFeedChannelInitializer()).connect(host, port).sync().channel();
I am not sure whether this ensures multithreading as wanted but it does allow to split the data access into multiple connections to the feed server.
Edit Update: After performing additional research on the subject, I have determined that netty does in fact create a thread per channel; this was verified by printing to console after the creation of each channel:
println("No. of active threads: " + Thread.activeCount());
The output shows an incremental number as channels are created and associated with their respective threads.
By default NioEventLoopGroup uses 2*Num_CPU_cores threads as defined here:
DEFAULT_EVENT_LOOP_THREADS = Math.max(1, SystemPropertyUtil.getInt(
"io.netty.eventLoopThreads",
Runtime.getRuntime().availableProcessors() * 2));
This value can be overriden to something else by setting
val group = new NioEventLoopGroup(16)
and then using the group to create/setup the bootstrap.

Magnolia HierarchyManager and Content are depreciated. How do I replicate functionality using Session and jcrNode?

I'm trying to do some logic in my Spring controller where I route to a website node based on the template used in another website node.
I can use LifeTimeJCRSessionUtil.getHierarchyManager("website").getContent("mynodepath").getTemplate() to do this, but I see that the HierarchyManager and Content classes are depreciated.
I looked at the Session class, but I have thus far been unable to figure out how to get the Template id based on the jcrNode.
You can use instead:
javax.jcr.Session jcrSession = LifeTimeJCRSessionUtil.getSession("website");
Node mynode = jcrSession.getNode("/my/node/path");
info.magnolia.cms.core.MetaData metaData = info.magnolia.jcr.util.MetaDataUtil.getMetaData(mynode);
String template = metaData.getTemplate();
Basically, instead of getHierarchyManager("website").getContent("mynodepath") you should use
getSession("website").getNode("/my/node/path").

QBO Queries and SpecifyOperatorOption

I'm trying to query QBO for, among other entities, Accounts, and am running into a couple of issues. I'm using the .Net Dev Kit v 2.1.10.0 (I used NuGet to update to the latest version) and when I use the following technique:
Intuit.Ipp.Data.Qbo.AccountQuery cquery = new Intuit.Ipp.Data.Qbo.AccountQuery();
IEnumerable<Intuit.Ipp.Data.Qbo.Account> qboAccounts = cquery.ExecuteQuery<Intuit.Ipp.Data.Qbo.Account>(context);
(i.e. just create a new AccountQuery of the appropriate type and call ExecuteQuery) I get an error. It seems that the request XML is not created properly, I just see one line in the XML file. I then looked at the online docs and tried to emulate the code there:
Intuit.Ipp.Data.Qbo.AccountQuery cquery = new Intuit.Ipp.Data.Qbo.AccountQuery();
cquery.CreateTime = DateTime.Now.Date.AddDays(-20);
cquery.SpecifyOperatorOption(Intuit.Ipp.Data.Qbo.FilterProperty.CreateTime,
Intuit.Ipp.Data.Qbo.FilterOperatorType.AFTER);
cquery.CreateTime = DateTime.Now.Date;
cquery.SpecifyOperatorOption(Intuit.Ipp.Data.Qbo.FilterProperty.CreateTime,
Intuit.Ipp.Data.Qbo.FilterOperatorType.BEFORE);
// Specify a Request validator
Intuit.Ipp.Data.Qbo.AccountQuery cquery = new Intuit.Ipp.Data.Qbo.AccountQuery();
IEnumerable<Intuit.Ipp.Data.Qbo.Account> qboAccounts = cquery.ExecuteQuery<Intuit.Ipp.Data.Qbo.Account>(context);
unfortunately, VS 2010 insists that AccountQuery doesn't contain a definition for SpecifyOperatorOption and there is no extension method by that name. So I'm stuck.
Any ideas how to resolve this would be appreciated.

SSRS ReportingService2010 change embedded DataSource to shared DataSource

I have SQL Server 2008 with SSRS installed on one server and SQL Server 2008 R2 with SSRS installed on a new server. I want to migrate 200+ reports as well as a few shared schedules and a couple data sources from the first server to the second one using the SSRS web service API. For simplicity sake since there are only a couple of shared data sources I went ahead and created those using the Report Manager interface.
Unfortunately, those who came before me embedded the data source information in each report (connection string, login, password, etc). I thought this would be a great time to change these to point to the shared data source so this would not have to be done for each report, one by one. I can create the reports on the new server just fine using CreateCatalogItem but I can't seem to determine how to properly go about changing from an embedded data source to a shared data source.
So far I have tried both SetItemReferences:
itemRef.Reference = "/Data Sources/TMS";
itemRef.Name = "TMS";
itemRef.Reference = "/Data Sources/TMS";
rs2010.SetItemReferences(catItem.Path, new ReportService2010.ItemReference[] { itemRef });
and SetItemDataSources:
ReportService2010.DataSourceReference dataSourceRef = new ReportService2010.DataSourceReference();
dataSourceRef.Reference = "/Data Sources/TMS";
ReportService2010.DataSource dataSource = new ReportService2010.DataSource();
dataSource.Name = "TMS";
dataSource.Item = dataSourceRef;
rs2010.SetItemDataSources(catItem.Path, new ReportService2010.DataSource[] { dataSource });
Both methods result in a "NotFoundException" when attempted on a report with an embedded data source but they both work just fine on reports that are already pointing to a shared data source.
Furthermore, I have searched all over Google as well as StackOverflow for a solution but have found nothing. Can anyone point me in the right direction here?
So I kept working with the SetItemReferences method and had a brilliant idea that ended up working. The final code I used is below:
List<ReportService2010.ItemReference> itemRefs = new List<ReportService2010.ItemReference>();
ReportService2010.DataSource[] itemDataSources = rs2010.GetItemDataSources(catItem.Path);
foreach (ReportService2010.DataSource itemDataSource in itemDataSources)
{
ReportService2010.ItemReference itemRef = new ReportService2010.ItemReference();
itemRef.Name = itemDataSource.Name;
itemRef.Reference = "/Data Sources/TMS";
itemRefs.Add(itemRef);
}
rs2010.SetItemReferences(catItem.Path, itemRefs.ToArray());
The problem was that I was not using the same DataSource name as what was found in the report .rdl file. I was able to determine what the name should be using the GetItemDataSources method. Since this method returns an array and may have more than one item in said array, I looped through it to create multiple ItemReferences if more than one existed though I doubt that happens very often if at all.

How to add some extra parameter in the airbrake parameters for JS errors

When we are sending the airbrake error to the airbrake server, by default it includes the controller name and action name.
But the question is that I want to add some extra parameters like username, email of the current user. If anyone has any idea please suggest how to do that?
In my layout application.html:
- if ['development'].include?(Rails.env)
= airbrake_javascript_notifier
= render :partial => 'layouts/airbrake_notifier'
and in the partial I have written:
Airbrake.errorDefaults['name'] = "#{current_user.name}";<br/>
Airbrake.errorDefaults['email'] = "#{current_user.email}";<br/>
Airbrake.errorDefaults['phone'] = "#{current_user.phone}";<br/>
Airbrake.errorDefaults['title'] = "#{current_user.title;<br/>
Not a great solution, but the Airbrake Knowledge Base recommends essentially patching the airbrake gem source of the lib/airbrake/notice.rb file.
def initialize(args)
...
self.parameters = args[:parameters] ||
action_dispatch_params ||
rack_env(:params) ||
{'username' => current_user.name}
It would certainly be better to have this be configurable without patching source.
What I've done instead is simply add a few pieces of data to the session (current_user.name mainly), since session data is sent with the request. I wouldn't do this for more than a few little pieces of data.
We've just added getting current users into the Airbrake Gem.
https://github.com/airbrake/airbrake/wiki/Sending-current-user-information
You'll soon be able to sort by current user in an upcoming redesign of the UI.