Eduard Lebedyuk · Sep 23, 2018 go to post

JVM is probably out of memory. Try this.

1. Define Excel server at SMP > System > Configuration > Zen Report Excel Servers > Zen Report Excel Server, let's say at port 44444

2. Start it. Copy OS command. Should be something like:

C:\InterSystems\Ensemble\lib\ExcelExporter\runserver.bat -port 44444 -numthreads 5 -loglevel 3 -maxlogfilesize 32000 -logrotationcount 100 -numpingthreads 5 -pingport 44445 2>&1

3. Stop Excel server

4. Execute the command from 2 in OS terminal, but set JVM heap size. See how.

5. In your ZEN report add:

Parameter EXCELSERVER = 44444;

to use your excel server.

6. Recompile report and try to run it again.

Eduard Lebedyuk · Sep 20, 2018 go to post

You can set this parameter in JDBC connection.
Add to the Properties of the SQL Server gateway connection:

FetchSize=1000; 
Eduard Lebedyuk · Sep 18, 2018 go to post

I think it could be a separate question:

How to export data returned from stored procedure.

Eduard Lebedyuk · Sep 18, 2018 go to post

It's better to use file streams.

Set stream = ##class(%Stream.FileCharacter).%New()
Set sc = stream.LinkToFile("E:\test\file.txt")
Do stream.Write("Some Text")
Set sc = stream.%Save()
Eduard Lebedyuk · Sep 18, 2018 go to post

To get queues list call:

Call EnsPortal.Queues_EnumerateQueues()

Or

SELECT *
FROM EnsPortal.Queues_EnumerateQueues()
Eduard Lebedyuk · Sep 17, 2018 go to post

Wouldn't it produce strings like this:

stringA","stringB","stringC

leaving strings A and C unquoted?

Eduard Lebedyuk · Sep 17, 2018 go to post

Both Service and Operation presented in the article use EnsLib.PubSub.PubSubOperation to get subscribers.

Here's getting a list of emails by domain and topic:

/// Get email addresses by domain and topic.
Method determineEmails(domain As %String, topic As %String) As %List
{
    set subRequest = ##class(EnsLib.PubSub.Request).%New()
    set subRequest.Topic = topic
    set subRequest.DomainName = domain    
    
    do ..SendRequestSync(..SubscriptionBO, subRequest, .subResponse,, "Get subscribers for domain: " _ domain _ ", topic: " _ topic)
    
    set mails = ""
    for i=1:1:subResponse.TargetList.Count() {
        #dim target As EnsLib.PubSub.Target
        set target = subResponse.TargetList.GetAt(i)
        set mails = mails _ $lb(target.Address)    
    }
    return mails
}
Eduard Lebedyuk · Sep 17, 2018 go to post

The Pub/Sub operation only gives you a list of subscribers, you decide what to do with that.

I have a sample of Pub/Sub service/operation, I'll publish it in a few hours.

Eduard Lebedyuk · Sep 14, 2018 go to post

Do I have to define both a GET and  POST for the same Route?

Yes.

Usually they have different logic so it makes more sense. What's your use case for GET and POST handlers to be the same?

Eduard Lebedyuk · Sep 14, 2018 go to post

As a direct solution you can do

write $zcvt("<CheckContractResponse><code>-1</code><message>ÐевеÑнÑй Ñип договоÑа</message></CheckContractResp>","I","UTF8")
<CheckContractResponse><code>-1</code><message>Неверный тип договора</message></CheckContractResp>
Eduard Lebedyuk · Sep 14, 2018 go to post

You need to add POST route:

Class Rest.UsuarioSvc Extends %CSP.REST
{

XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{
<Routes>
<Route Url="/Oi/:xpto" Method="GET" Call="Oi"/>
<Route Url="/Oi/:xpto" Method="POST" Call="Oi"/>
</Routes>
}

ClassMethod Oi(xpto As %String) As %Status
{
    Set tSC = $$$OK
    
    If 'tSC Quit tSC       
    Set tProxy = ##class(%ZEN.proxyObject).%New()
    Set tProxy.Oi = xpto _ "1234"
    
    Set %response.ContentType = "application/json"
    set %response.Status = 200
    Do tProxy.%ToJSON()
    
    Quit tSC
}

}
Eduard Lebedyuk · Sep 14, 2018 go to post

I'd try to avoid giving user an ability to enter arbitrary code.

1. Offer user a list of predefined operations ( >,<,=,<> or Equals,More, Not Equals,...)

2. Get input from user.

3. Check that input is actually one option on a list and not something else. 

4. Perform the check using IF, for example.

 ClassMethod main(a As %Integer, b As %Integer, operation As %String(VALUELIST="Equals,Not Equals") = "Equals") As %Boolean
{
  set operationList = $lb("Equals", "Not Equals")
  throw:'$lf(operationList, operation) ##class(%Exception.General).%New("<INVALID OPERATION>")
 
  if operation = "Equals" {
    set result = (a = b)
  } elseif operation = "Not Equals" {
    set result = (a '= b)
  } else {
    throw ##class(%Exception.General).%New("<INVALID OPERATION>")
  }
 
  quit result
}
Eduard Lebedyuk · Sep 14, 2018 go to post

What does it actually do?

I have a table SQLUser.Person for example, it returns nothing.

Eduard Lebedyuk · Sep 13, 2018 go to post

Try application/xml instead of text/xml for content type.

If it does not help, check API docs for correct type.

For accept try */*.

Eduard Lebedyuk · Sep 11, 2018 go to post

I think I encountered something similar. I added to target class:

Class Proxy.Class Extends (%Persistent, %XML.Adaptor) {

Parameter XMLIGNOREINVALIDTAG =1;

Parameter XMLIGNOREINVALIDATTRIBUTE= 1;
...

}

And it helped.

Eduard Lebedyuk · Sep 8, 2018 go to post

201 looks like a correct response.

500 on the other hand is an error. Check what's the error.

Eduard Lebedyuk · Sep 8, 2018 go to post

What's the status_code on

            response = session.post(getPropertyUrl(property), params= {"type":"%Numeric", "path": property, "unique":0}, headers=header)
            print(response.status_code)
Eduard Lebedyuk · Sep 8, 2018 go to post

It actually doesn't create neither database or property.

Check that %Service_DocDB is enabled. Your screenshot also shows that database gets created.

if I have 20 properties... this would be a long code

You need to cycle over all properties, so +2 lines probably.

Eduard Lebedyuk · Sep 8, 2018 go to post

Made an erro in URL, it's not  .../db/DBName/Propname but .../prop/db/DBName/Propname.

Here's a sample code that creates a db and a property.

import requests

def getBaseUrl(host = "127.0.0.1", port = 52773,  namespace = "user", db = "test"):
    return "http://{}:{}/api/docdb/v1/{}/db/{}" .format(*[host, port, namespace, db])

def getPropertyUrl(property, host = "127.0.0.1", port = 52773,  namespace = "user", db = "test"):
    return "http://{}:{}/api/docdb/v1/{}/prop/{}/{}" .format(*[host, port, namespace, db, property])

def main():

    url = getBaseUrl()
    print(url)
    header = {
        'Content-Type': 'application/json',
    }

    session = requests.Session()
    session.auth = ("_SYSTEM", "SYS")

    response = session.get(url, headers=header)
    #response = requests.get(url, headers=header)
    print(response.status_code)  # Number of error

    if response.status_code == 404:
        print('DB not found, create DB ...')
        response = session.post(url, headers=header)
        print(response.status_code)
    elif response.status_code != 200:
        print('Unknown error: ' + response.status_code + ' ' + response.reason)
    else:
        property = "Ergebniszuf"
        # check that property exist
        response = session.get(getPropertyUrl(property), headers=header)

        if response.status_code == 404:
            print('Property not found, creating property: ' + property)
            response = session.post(getPropertyUrl(property), params= {"type":"%Numeric", "path": property, "unique":0}, headers=header)
            print(response)
        elif response.status_code != 200:
            print('Unknown error: ' + response.status_code + ' ' + response.reason)
        else:

            print('DB found, load data...')

    return 1


if __name__ == '__main__':
    print(main())
Eduard Lebedyuk · Sep 8, 2018 go to post

2012.1.4 has JSON support via %ZEN.proxyObject

set obj = ##class(%ZEN.proxyObject).%New()
set obj.createTransactionRequest= ##class(%ZEN.proxyObject).%New()
set obj.createTransactionRequest.merchantAuthentication = ##class(%ZEN.proxyObject).%New()
set obj.createTransactionRequest.merchantAuthentication.name = "gfufet9QVgT5P"
do obj.%ToJSON()

Also you can use %ZEN.Auxiliary.jsonProvider to convert object into JSON.