BeanIO item reader Comments require reader.markSupported() to return true - jberet

I have my beanioItemReader map defined as follows -
<stream name="DTA" format="fixedlength">
<parser>
<property name="comments" value="#" />
</parser>
...
And getting the exception -
jberet - WARN JBERET000001: Failed to run batchlet org.jberet.job.model.RefArtifact#67af20cb
java.lang.IllegalArgumentException: Comments require reader.markSupported() to return true
at org.beanio.stream.util.CommentReader.<init>(CommentReader.java:61) ~[beanio-2.1.0.jar:2.1.0]
at org.beanio.stream.fixedlength.FixedLengthReader.<init>(FixedLengthReader.java:101) ~[beanio-2.1.0.jar:2.1.0]
I do not see any documented properties to pass to the beanioItemReader for comments. Can/How do I get comments to work?

The location to BeanIO mapping file is configured in BeanIOItemReaderWriterBase class , so whatever configuration specified in the mapping file will be passed to the underlying BeanIO reader.
From the stack trace, it looks like it's complaining about the underlying reader does not support mark (reader.markSupported returns false). But JBeret BeanIOItemReader class uses a BufferedReader, which does support mark.

Related

You called the function 'Value Selector' with these arguments

I am in the process of implementing a LoanBroker with Mulesoft but have an error message when sending a request. I get the following error message back from Postman and Mulesoft Anypoint Studio:
ERROR 2021-06-27 15:20:51,133 [[MuleRuntime].uber.04: [loanbroker].LoanBrokerFlow_Gr7.CPU_LITE #254be3ee] [processor: LoanBrokerFlow_Gr7/processors/0; event: 7e49f560-d74a-11eb-b598-b66921dc5aa5] org.mule.runtime.core.internal.exception.OnErrorPropagateHandler:
********************************************************************************
Message: "You called the function 'Value Selector' with these arguments:
1: Binary ("" as Binary {base: "64"})
2: Name ("amount")
But it expects one of these combinations:
(Array, Name)
(Array, String)
(Date, Name)
(DateTime, Name)
(LocalDateTime, Name)
(LocalTime, Name)
(Object, Name)
(Object, String)
(Period, Name)
(Time, Name)
1| payload.amount
^^^^^^^^^^^^^^
Trace:
at main (line: 1, column: 1)" evaluating expression: "payload.amount".
Element : LoanBrokerFlow_Gr7/processors/0 # loanbroker:bi_gruppe7.xml:34 (Copy_of_setAmount)
Element DSL : <set-variable value="#[payload.amount]" doc:name="Copy_of_setAmount" doc:id="cbcca557-1a69-4cf2-80b1-64333175589d" variableName="amount"></set-variable>
Error type : MULE:EXPRESSION
FlowStack : at LoanBrokerFlow_Gr7(LoanBrokerFlow_Gr7/processors/0 # loanbroker:bi_gruppe7.xml:34 (Copy_of_setAmount))
(set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
Can anyone help me?
Thanks
This generally happens when one tries to access inner value of a payload like json but incoming payload is NOT actually a json type.
One could check the payload mediaType and then try to access the amount in order to avoid Value Selector exception.
%dw 2.0
output application/java
---
if( !isEmpty(payload) and payload.^mediaType contains "json" )
payload.amount
else
read(payload, "application/json").amount //best effort
Would recommend creating a separate dataweave file like dwl/set-amount.dwl and referencing it.
You are probably sending some body in the HTTP request from Postman but Mule doesn't know how to read it. Maybe you did not the Content-Type header in the request to let DataWeave know it is a JSON (application/json) or XML (application/XML).
Ensure you are sending the right content type.
I ran into the same situation. I know exactly the base64 is a json. So, I tried to set the MIME Type by
<set-payload value="#[payload]" doc:name="Set Payload" mimeType="application/json"/>
It works for me.

Dynamic URI based on file name/cfg file/property name

I am trying to pass a to URI value dynamically with a property value. That property value will be configured already in the cfg file.
When the file name is extracted using CamelFileNameOnly header, it has to get passed to the to Uri endpoint. So that the same name is referred in the code.
Please find my code below:
I have dropped a file with name KevinFile.txt in my server location= D:\Servers\jboss-fuse-6.2.0.redhat-133\data\myLocalFTP (file://data/myLocalFTP)
Config File
local.folder.url=file://data/myLocalFTP
KevinFile=file://data/KevinFileDirectory
Camel Route
<route id="awsRoute">
<from uri="{{local.folder.url}}"/>
<bean ref="processorClass" method="process"/>
<log message="myProperty value is ${exchangeProperty.myProperty}"/> <---Gives the fileName
<to uri="{{${exchangeProperty.myProperty}}}"/> <--This is the spot i am getting error :(
</route>
ProcessorClass.java
public class ProcessorClass implements Processor{
#Override
public void process(Exchange exchange) throws Exception {
String fileName = (String) exchange.getIn().getHeader("CamelFileNameOnly");
exchange.setProperty("myPropertyNew", fileName);
}
}
If I understand correctly, you need to specify "dynamic" vlue for the constant part of the producer. Instead of <to uri="{{${exchangeProperty.myProperty}}}"/> you can use recipientList or routingSlip:
<recipientList>
<simple>${exchangeProperty.myProperty}</simple>
</recipientList>
or
<routingSlip>
<simple>${exchangeProperty.myProperty}</simple>
</routingSlip>
Ah what your looking for is simply setting the header as a property. You can do that like this:
from("direct:start")
.setHeader("CamelFileNameOnly").simple("{{myPropertyName}}")
.to("file://data/myLocalDisk");
You can also simplify this by using the uri syntax available on the file component in this case (Thanks to Sergii for the recommendation). Just make sure you check the camel documentation for each component certain components rely on exchange headers, while others can leverage URI properties.
from("direct:start")
.to("file://data/myLocalDisk?fileName={{myPropertyName}}");
Its also worth noting that if you have logic that you want to use before setting the header you can have the setHeader call a bean.
from("direct:start")
.setHeader("CamelFileNameOnly").bean(MyPropertyLogicBean.class, "someMethod({{myPropertyName}})")
.to("file://data/myLocalDisk");
Use the camel properties component to get this property to resolve.
Reference: http://camel.apache.org/properties.html

Issue with SBOS ACCELERATORS module

in my sitecore instance i install SOLS ACCELERATORS Module,
when I verify my showconfig in /admin/showconfig.aspx
i found this error message
error on line 2383 at column 612: Extra happy at the end of the document
in app_config/include/Sitecore.SBOSAccelerators.config
I removed the following line
<pageextenders>
       <pageextender type="Sitecore.SbosAccelerators.Shared.PageExtenders.InsertAnalyticsDataExtender, Sitecore.SbosAccelerators" />
     </ pageextenders>
the showconfig.aspx works well
I tried to analyze the code of InsertAnalyticsDataExtender, but I found nothing until now,
someone already has this kind of problem?
thank you
ok that's fixed,
the author of SOLS ACCELERATORS Module, verify if the context of the current Site is not Shell or Sheel_Module beffor adding a hidden field with this ID "SC_ANALYTICS_PAGE"
but what happen if the contentType of the page is an XML or a json for example
in this case i'm going to have an error,
to fixe this issue just create a new class in your solution, inherite from
Sitecore.SbosAccelerators.Shared.PageExtenders.InsertAnalyticsDataExtender
add this methode to your class
public override void Insert()
{
// you can replace Context.Site.Name by Context.Page.Page.Response.ContextType=="Text/Xml"
if (Context.Site.Name == "admin")
return;
base.Insert();
}
after that go to Sitecore.SBOSAccelerators.Config and change your pageextender to use the new class
happy conding
If you pasted the part of the configuration directly from your config file, you have a type in the config. You cannot close any tag with whitespace at the beginning of the closing tags like this </ pageextenders>. Try without the space </pageextenders>:
<pageextenders>
<pageextender type="Sitecore.SbosAccelerators.Shared.PageExtenders.InsertAnalyticsDataExtender, Sitecore.SbosAccelerators" />
</pageextenders>

Need Perl SOAP::Transport::HTTP::CGI sanity check

OK, I think there's no easy (make that lazy) way to do what I want but given the Perl SOAP::Transport::HTTP::CGI code fragment below what I am looking to do is intercept all SOAP operation passing through the service and log the result of an operation or fault...
SOAP::Transport::HTTP::CGI
-> dispatch_to(
#first arg needs to be the directory holding the PackageName.pm modules with no trailing "/". The args aftre the first are name of SPECIFIC packages to be loaded as needed by SOAP requests
#Failure to call out specific moudules below will allow the external SOAP modules to be loaded, but the overall module #INC path for other Perl modules will be blocked for security reasons
SOAP_MODULE_INCULDE, #name of the directory holding the PackageName.pm modules with no trailing "/"
"TechnicalMetaDataExtraction", #prod - wrapper for EXIFTool
"Ingest", #module (package) name
"ImageManipulation", #module (package) name
"FacebookBroadcast", #unfinished
"CompressDecompress", #unfinished
"ImageOCR", #prod - tesseract
"HandleDotNet", #prod
"Pipeline", #prod (needs work)
"TwitterBroadcast", #prototype
"Messaging", #prototype but text format email works
"Property", #development
"FileManager", #prototype
"PassThrough" #prod - module to do location conversion (URL -> Fedora Obj+DS, Fedora Obj+DS -> file, URL -> InlineBase64, etc.) but format conversion
) #done with the dispacth_to section
-> on_action(sub {
#on_action method lets you specify SOAPAction understanding. It acceptsreference to subroutine that takes three parameters: SOAPAction, method_uri and method_name.
#'SOAPAction' is taken from HTTP header and method_uri and method_name are extracted from request's body. Default behavior is match 'SOAPAction' if present and ignore it otherwise.
#die SOAP::Data->type('string')->name('debug')->value("Intercepted call, SOAP request='".shift(#_)."'");
if($Debug) {
##_ notes:
#[0] - "http://www.example.org/PassThrough/NewOperation"
#[1] - http://www.example.org/PassThrough/
#[2] - NewOperation
#[3] - "undefined"
my %DataHash=(
message => #_[0]
);
#SendMessageToAMQTopic(localtime()." - ".#_[0]);
SendDebugMessage(\%DataHash, "info");
} #there's only one element passed at this level
}) #end on_action
#-> on_debug() #not valid for SOAP::Transport::HTTP::CGI
#-> request() #valid, but does not fire - request method gives you access to HTTP::Request object which you can provide for Server component to handle request.
#-> response() #does not fire - response method gives you access to HTTP::Response object which you can access to get results from Server component after request was handled.
#-> options({compress_threshold => 10000}) #causes problems for the JavaScript soap client - removed for the moment
-> handle() #fires but ignores content in sub - handle method will handle your request. You should provide parameters with request() method, call handle() and get it back with response().
;
Initially I thought I could get the information I needed from the "on_action" method, but that only contains the destination of the SOAP call (before it is sent?) and I'm looking for data in the operation result that will be sent back to the SOAP client. The documentation of "SOAP::Transport::HTTP::CGI" is a bit thin and there are few examples online.
Anyone know if this is possible give the what the code above is set up? If not, then the only other option is to alter each method of my SOAP service code modules to include the "SendDebugMessage" function.
I would suggest subclassing SOAP::Transport::HTTP::CGI and hooking into the handle() method. An untested and probably non-working example would be:
package MySoapCGI;
use Data::Dumper;
use SOAP::Transport::HTTP;
use base 'SOAP::Transport::HTTP::CGI';
sub handle {
my $self = shift;
$self->SUPER::handle(#_);
warn Dumper($self->request);
warn Dumper($self->response);
}
Replace the dumpers with whatever logging you want. You may need to do some XML parsing, because these will be the raw HTTP::Request and HTTP::Response.

root namespace is added into the <xades:SignedProperties>

library: apache Santuario + xades4j.
using xpathto select elements and sign them.
If I try to sign a simple XML without a namespace and verify the signature, it works well , but if the XML defines a namespace, for example the XML following:
<ClinicalDocument xmlns="urn:hl7-org:v3">
<element1tobesigned.../>
<element2tobesigned.../>
</ClinicalDocument>
and the exception was found when verifying the signature
858 WARN [main] org.apache.xml.security.signature.Reference - Verification failed for URI "#xmldsig-5fb20abe-b14c-4d84-a908-e22e776cd6f1-signedprops"
858 WARN [main] org.apache.xml.security.signature.Reference - Expected Digest: q0WnWFf9j0kcT46t5cXmcPnVvu5o51oAcmej/SjCazQ=
858 WARN [main] org.apache.xml.security.signature.Reference - Actual Digest: 41zXKVkRCsxUYpNZXW5b9KkZlTC9LM9WA8O7WHQz1Rg=
xades4j.verification.ReferenceValueException: Reference '#xmldsig-5fb20abe-b14c-4d84-a908-e22e776cd6f1-signedprops' cannot be validated
the cause is that XML namespace (urn:hl7-org:v3) was added into the xades:SignedProperties then the digest became different .
858 DEBUG [main] org.apache.xml.security.utils.DigesterOutputStream - Pre-digested input
858 DEBUG [main] org.apache.xml.security.utils.DigesterOutputStream - <xades:SignedProperties xmlns="urn:hl7-org:v3" ........./>
here is the signature generation code
XadesTSigningProfile profile = new XadesTSigningProfile(keyProvider);
profile.withTimeStampTokenProvider(TestTimeStampTokenProvider.class)
.withAlgorithmsProviderEx(ExclusiveC14nForTimeStampsAlgorithmsProvider.class);
XadesSigner signer = profile.newSigner();
DataObjectDesc obj1 = new DataObjectReference("")
.withTransform(new ExclusiveCanonicalXMLWithoutComments())
.withTransform( new XPathTransform(xPath);
SignedDataObjects dataObjs = new SignedDataObjects().withSignedDataObject(obj1);
changed 2012-11-20 begin
// signer.sign(dataObjs, docToSign.getDocumentElement() );
new Enveloped(signer).sign(docToSign.getDocumentElement());
changed 2012-11-20 end
and here is the verify code
NodeList signatureNodeList = getSigElement(getDocument("my/my-document.signed.bes.countersign.xml"));
for (int i = 0; i < signatureNodeList.getLength(); i++) {
Element signatureNode = (Element) signatureNodeList.item(i);
verifySignature(signatureNode, new XadesVerificationProfile(VerifierTestBase.validationProviderMySigs));
log.info("successful validation");
}
public static XAdESForm verifySignature(Element sigElem,
XadesVerificationProfile p) throws Exception {
XAdESVerificationResult res = p.newVerifier().verify(sigElem, null);
return res.getSignatureForm();
}
It looks like that there is a document about this problem in Apache Santuario FAQ ,
2.6. I sign a document and when I try to verify using the same key, it fails
After you have created the XMLSignature object, before you sign the document, you must embed the signature element in the owning document (using a call to XMLSignature.getElement() to retrieve the newly created Element node from the signature) before calling the XMLSignature.sign() method,
During canonicalisation of the SignedInfo element, the library looks at the parent and ancestor nodes of the Signature element to find any namespaces that the SignedInfo node has inherited. Any that are found are embedded in the canonical form of the SignedInfo. (This is not true when Exclusive Canonicalisation is used, but it is still good practice to insert the element node prior to the sign() method being called).
If you have not embedded the signature node in the document, it will not have any parent or ancestor nodes, so it will not inherit their namespaces. If you then embed it in the document and call verify(), the namespaces will be found and the canonical form of SignedInfo will be different to that generated during sign().
also there is a document about this problem as following
https://stackoverflow.com/a/12759909/1809884
It looks like that it is not a bug of xades4j, but a xml signature problem.
--add 2012-11-15
here is how to get the docToSign . in fact , i just reused the code in class SignatureServicesTestBase . so i am sure that it is namespaceaware.
static
{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
db = dbf.newDocumentBuilder();
}
public static Document getDocument(String fileName) throws Exception
{
String path = toPlatformSpecificXMLDirFilePath(fileName);
Document doc = db.parse(new FileInputStream(path));
// Apache Santuario now uses Document.getElementById; use this convention for tests.
Element elem = doc.getDocumentElement();
DOMHelper.useIdAsXmlId(elem);
return doc;
}
and docToSign is return by calling SignatureServicesTestBase.getDocument()
Document docToSign = SignatureServicesTestBase.getDocument("my/cdamessage.xml");
and the SignedProperties element as following
<xades:SignedSignatureProperties>
<xades:SigningTime>2012-11-15T13:58:26.167+09:00</xades:SigningTime>
<xades:SigningCertificate>
<xades:Cert>
<xades:CertDigest>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>4btVb5gQ5cdcNhGpvDSWQZabPQrR9jf1x8e3YF9Ajss=</ds:DigestValue>
</xades:CertDigest>
<xades:IssuerSerial>
<ds:X509IssuerName>CN=Itermediate,OU=CC,O=ISEL,C=PT</ds:X509IssuerName>
<ds:X509SerialNumber>-119284162484605703133798696662099777223</ds:X509SerialNumber>
</xades:IssuerSerial>
</xades:Cert>
<xades:Cert>
<xades:CertDigest>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>vm5QpbblsWV7fCYXotPhNTeCt4nk8cLFuF36L5RJ4Ok=</ds:DigestValue>
</xades:CertDigest>
<xades:IssuerSerial>
<ds:X509IssuerName>CN=TestCA,OU=CC,O=ISEL,C=PT</ds:X509IssuerName>
<ds:X509SerialNumber>-46248926895392336918291885380930606289</ds:X509SerialNumber>
</xades:IssuerSerial>
</xades:Cert>
<xades:Cert>
<xades:CertDigest>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>AUaN+IdhKQqxIVmEOrFwq+Dn22ebTkXJqD3BoOP/x8E=</ds:DigestValue>
</xades:CertDigest>
<xades:IssuerSerial>
<ds:X509IssuerName>CN=TestCA,OU=CC,O=ISEL,C=PT</ds:X509IssuerName>
<ds:X509SerialNumber>-99704378678639105802976522062798066869</ds:X509SerialNumber>
</xades:IssuerSerial>
</xades:Cert>
</xades:SigningCertificate>
</xades:SignedSignatureProperties>
</xades:SignedProperties>
also , i use xpath to get the elements to be signed, and namespace(xmlns="urn:hl7-org:v3" ) is add into the result as well .
543 DEBUG [main] org.apache.xml.security.utils.ElementProxy - setElement("ds:Transform", "null")
544 DEBUG [main] org.apache.xml.security.utils.ElementProxy - setElement("dsig-xpath:XPath", "null")
658 DEBUG [main] org.apache.xml.security.utils.DigesterOutputStream - Pre-digested input:
658 DEBUG [main] org.apache.xml.security.utils.DigesterOutputStream - <component xmlns="urn:hl7-org:v3" Id="ES" contextConductionInd="true" typeCode="COMP">
<section classCode="DOCSECT" moodCode="EVN">
<code code="ES" codeSystem="2.16.840.1.113883.6.1" codeSystemName="SectionCode" codeSystemVersion="1.0" displayName="english"></code>
<text>english</text>
</section>
</component>
something wrong with xpath ? xpath is driving my crazy . I think i have to study xpath from beginning now.
chris
You're creating an enveloped signature but the enveloped signature transform is missing! Since the whole document is being signed the signature node itself has to be excluded, because some of its contents change after signature calculation.
Can't believe how I didn't see it until you mentioned the Enveloped class. Btw, this class is just an utility class for simple, straightforward enveloped sigantures. It robably shouldn't even be there. You can just add the transform yourself:
DataObjectDesc obj1 = new DataObjectReference("")
.withTransform(new EnvelopedSignatureTransform())
.withTransform(new ExclusiveCanonicalXMLWithoutComments())
...