Parameter HandleCorsRequest = 1;
Should be enough.
Anyway, what error are you getting?
- Log in to post comments
Parameter HandleCorsRequest = 1;
Should be enough.
Anyway, what error are you getting?
I debug installers from a terminal:
TSTART do installer
Then I check the system, errors, etc. After that:
TROLLBACK
And I can run installer again (only need to delete all created files, if any)
I'd recommend running with log level 3 for debugging purposes, and using transactions. I think MainDB is undefined or empty.
It can be done with Gzip stream directly:
set ^dbg=123
set s=##class(%Stream.FileBinaryGzip).%New()
do s.LinkToFile("1.xml")
do $System.OBJ.ExportToStream("dbg*.GBL", s)
do s.%Save()
kill
kill ^dbg
set s=##class(%Stream.FileBinaryGzip).%New()
do s.LinkToFile("1.xml")
do $System.OBJ.LoadStream(s)
write ^dbg
>123Execute this SQL in every namespace you need to get a list of production classes and their descriptions:
SELECT ID, Description FROM Ens_Config.Production
Here's a sample project with query that executes in every Ensemble namespace. Also article about writing custom queries.
Here's a sample BP that calls BO asynchronously. BO returns current request state, upon which BP decides to wait some more, report an error or process an answer:
Class test.BP Extends Ens.BusinessProcess
{
/// Operation name
Property Operation As %String(MAXLEN = 250) [ Required ];
/// How long to wait for an answer. 0 - forever.
Property MaxProcessTime As %Integer(MINVAL = 0) [ InitialExpression = 3600 ];
Parameter SETTINGS = "MaxProcessTime:Basic,Operation:Basic:selector?context={Ens.ContextSearch/ProductionItems?targets=1&productionName=@productionId}";
/// Identifier for a first request
Parameter callCOMPLETIONKEY = "*call*";
/// Identifier for a state request
Parameter getStateCOMPLETIONKEY = "*getState*";
/// Alarm identifier
Parameter alarmCOMPLETIONKEY = "*alarm*";
Method OnRequest(pRequest As Ens.StringRequest, Output pResponse As Ens.StringResponse) As %Status
{
#dim msg As Ens.StringRequest = pRequest.%ConstructClone(1)
quit ..SendRequestAsync(..Operation, msg, $$$YES, ..#callCOMPLETIONKEY)
}
/// Process Async reply from Operation
Method OnResponse(request As Ens.StringRequest, ByRef response As Ens.StringResponse, callrequest As Ens.StringRequest, callresponse As Ens.StringResponse, pCompletionKey As %String) As %Status
{
#dim sc As %Status = $$$OK
// Got an error
if $$$ISERR(callresponse.status)
{
set response = callresponse
quit $$$OK
}
// Got primary answer
if (pCompletionKey = ..#callCOMPLETIONKEY) || (pCompletionKey = ..#alarmCOMPLETIONKEY)
{
quit ..OnResponseFromCallOrAlarm(request, .response, callrequest, callresponse, pCompletionKey)
}
// Got getState
if (pCompletionKey = ..#getStateCOMPLETIONKEY)
{
// Current processing state (1 - received; 2 - in work; 3 - done)
#dim status As %String = callresponse.StringValue
// If not 3, run getState again
if (status '= "3")
{
// Check how much time passed since we started
set processTime = $system.SQL.DATEDIFF("s", ..%TimeCreated, $$$ts)
if ((..MaxProcessTime=0) || (processTime<..MaxProcessTime)) {
// Let's run getState again in 30 seconds
#dim alarmMsg As Ens.AlarmRequest = ##class(Ens.AlarmRequest).%New()
set alarmMsg.Duration = "PT30S"
quit ..SendRequestAsync("Ens.Alarm", alarmMsg, $$$YES, ..#alarmCOMPLETIONKEY)
} else {
// Timeout
set response = ##class(Ens.StringResponse).%New()
set response.status = $$$ERROR($$$GeneralError, "Timeout")
quit $$$OK
}
}
else
{
quit ..OnResponseFromGetState3(request, .response, callrequest, callresponse, pCompletionKey)
}
}
// unrecognized pCompletionKey value
quit $$$ERROR($$$InvalidArgument)
}
/// OnResponse for alarm or call - run get state
Method OnResponseFromCallOrAlarm(request As Ens.StringRequest, ByRef response As Ens.StringResponse, callrequest As Ens.StringRequest, callresponse As Ens.StringResponse, pCompletionKey As %String) As %Status [ Private ]
{
#dim msg As Ens.StringRequest = pRequest.%ConstructClone(1)
quit ..SendRequestAsync(..Operation, msg, $$$YES, ..#getStateCOMPLETIONKEY)
}
/// OnResponse for an answer
Method OnResponseFromGetState3(request As Ens.StringRequest, ByRef response Ens.StringResponse, callrequest As Ens.StringRequest, callresponse As Ens.StringResponse, pCompletionKey As %String) As %Status [ Private ]
{
// Process complete response
quit $$$OK
}OnResponse would be an automatic observer, and can in turn notify anything else. You can use original request id or SessionID to identify what you need to notify.
What's the status of:
Set tSC = ##class(Ens.Director).EnableConfigItem(pConfigItemName,0,1)
What is "productdescription"? How do you access it now? Use this code to switch namespaces:
new $namespace set $namespace = <Other namespace> do stuff
Docs for $namespace, zn.
Yes, subclassing %CSP.REST is much easier.
From the class documentation on OSUserName:
Operating system username of process. Username given to the process by the operating system when the process is created. When displayed, it is truncated to 16 characters. Note that the real O/S username is only returned when connecting to UNIX or VMS systems; For Windows, it will return the O/S username for a console process, but for telnet it will return the $USERNAME of the process. For client connections, it contains the O/S username of the client. This field is truncated at 16 characters.
_Ensemble is a Caché user under which all Ensemble jobs are run.
If you need to understand the context under which the service runs execute in a BS:
do $zf(-1,"set > vars.txt")
to output all environment variables to a file.
There is no Cache function to do that.
But as PDF contains readable "postscript" parts you can use regexp to search for relevant information. Stack. Article. It's not guaranteed to be precise though.
Here's my article about using LibreOffice for work with documents. I've also used ghostscript and postscript to work with pdf from Caché and it's all fairly straightforward.
Also, here's the code I wrote (execute is defined here) to add footer to every page of a PDF file using ghostscript:
/// Use ghostscript (%1) to apply postscript script %3
/// Upon source pdf (%4) to get output pgf (%2)
/// Attempts at speed -dProvideUnicode -dEmbedAllFonts=true -dPDFSETTINGS=/prepress
Parameter STAMP = "%1 -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile=%2 %3 -f %4";
ClassMethod stampPDF(pdf, psFile, pdfOut) As %Status
{
set cmd = $$$FormatText(..#STAMP, ..getGS(), pdfOut, psFile, pdf)
return ..execute(cmd)
}
ClassMethod createPS(psFile, text) As %Status
{
set stream = ##class(%Stream.FileCharacter).%New()
// For cyrillic text
set stream.TranslateTable = "CP1251"
set sc = stream.LinkToFile(psFile)
quit:$$$ISERR(sc) sc
do stream.WriteLine("<<")
do stream.WriteLine(" /EndPage")
do stream.WriteLine(" {")
do stream.WriteLine(" 2 eq { pop false }")
do stream.WriteLine(" {")
do stream.WriteLine(" gsave")
do stream.WriteLine(" /MyFont 12 selectfont")
do stream.WriteLine(" 30 70 moveto (" _ text _ ") show")
do stream.WriteLine(" grestore")
do stream.WriteLine(" true")
do stream.WriteLine(" } ifelse")
do stream.WriteLine(" } bind")
do stream.WriteLine(">> setpagedevice")
quit stream.%Save()
}
/// Get gs binary
ClassMethod getGS()
{
if $$$isWINDOWS {
set gs = "gswin64c"
} else {
set gs = "gs"
}
return gs
}Ghostscript can be used to get a number of pages in a PDF file. Here's how.
In my case I need everything in the url as one argument. But that's also useful for some use cases.
Thank you. That helped.
Class Try.REST Extends %CSP.REST
{
XData UrlMap
{
<Routes>
<Route Url="(.*)" Method="GET" Call="GET"/>
</Routes>
}
ClassMethod GET(href)
{
w "OK"
s ^dbg($i(^dbg)) = $g(href)
q 1
}
}Can documentation be expanded to include information about SQL search. I always forget&rediscover where things are and especially how they are related
Do not forget to mark answer as accepted.
Check UserAction method of %Studio.Extension.Base class. You can call CSP pages from there.
In your BO try:
Set result = ..Adapter.FTP.MakeDirectory(.path)
Adapter is EnsLib.FTP.OutboundAdapter and FTP is %Net.FtpSession.
I would subclass the adapter and add MakeDirectory method there, with code pointing to the FTP method and status conversion.
Use %ZEN.Auxiliary.JSONProvider class.
SQLCODE=100
would be a codepath for no data.
It's a valid sample. You just can't write directly into ZEN context. Well, you can, obviously, but that causes errors.
Where exactly in samples?
Try commenting out all write statements in sqlTest method.
1. https certificate would apply to the cache and csp sites defined under IIS. It would apply to everyrhing really.
2. Not sure about html landing page being a security threat. That depends on your setup. Do you embed http parts in your (future) https pages?
I'd recommend as a first step to install let's encrypt certificate - it's free and easy.
Then force http->https redirect on your iis server.
After that check how your html landing page behaves.
Thank you! That's very useful.
Is there a way to return real implementation class?
For example, consider these classes:
Class App.Use {
ClassMethod Test()
{
w 1/0
}
}and:
Class App.Use2 Extends App.Use
{
}If I call:
do ##class(App.Use2).Test()
I get the following CLS source line:
App.Use2:Test+1
Yet, the relevant code is actually implemented in
App.Use:Test+1
One approach I see is checking %Dictionary.MethodDefinition recursively till I find a method definition, but there's bound to be many problems multiple inheritance.
I don't understand your question. Please elaborate on the following points:
Because I want it done automatically. I already wrote several converters manually as described, but started thinking about automating the task.