David Hockenbroch · Jul 21, 2021 go to post

If your other system is also a Cache or IRIS server, there is a mirroring options called a reporting async that exists for this specific purpose. If you've got multiple servers and need to consolidate that data for reporting purposes, a reporting async can be a part of up to 10 mirrors to help you bring that data together, too.

David Hockenbroch · Jul 27, 2021 go to post

I'm about to go down the same path here. I have a rough idea of what I need to do. I'm going to try to use the %Net.HttpRequest object and do at least the following steps:

1. Create a new %Net.HttpRequest object

set myrequest = ##class(%Net.HttpRequest).%New()

2. Set the server

set myrequest.server = "www.whatever.com"

3. Set the locatoin

set myrequest.location = "/path/to/rest"

4. Create a global binary stream.

5. Write json data to the stream.

6. Use the stream as the EntityBody for the HttpRequest.

7. Call the get, put, or post method of the HttpRequest object to consume.

8. Use the HttpRequest's HttpResponse object to check the response

David Hockenbroch · Jul 27, 2021 go to post

I've had some time to try this now. Here are steps that worked for me:

set myrequest = ##class(%Net.HttpRequest).%New()
set myrequest.Server = "<server ip or domain here>"
set myrequest.Port = "<server port here if it isn't 80>"
set myrequest.Location = "</path/to/rest>"
do myrequest.EntityBody.Write("<your json here>")
do myrequest.Post()
set mydata = myrequest.HttpResponse.Data.Read()

At that point, the data returned in the response should be in mydata.

Depending on your specific API, you made need to take additional steps for authentication, and you may need to use myrequest.Get() or myrequest.Put() instead of myrequest.Post().

If you need to set parameters, you use the SetParam method of the HttpRequest. For example, if you're using the very most basic way to authenticate to a Cache instance, you do that by specifying a CacheUserName and a CachePassword as parameters as follows any time before your post/put/get:

do myrequest.SetParam("CacheUserName","<your username here>")
do myrequest.SetParam("CachePassword","<your password here>")
David Hockenbroch · Aug 19, 2021 go to post

That's telling you the URL you're requesting is too long, not the request body. If it was the request body that was too big, that'd be a 413, not a 414. If you're getting that when your form contains a very long entry, you're probably somehow converting the request to a get, not a post, request. Can we see the code for your form as well as how it's being submitted?

David Hockenbroch · Aug 19, 2021 go to post

The maximum URI size in Apache is usually 8,177 characters, but increasing that isn't the problem. Somewhere in your program, the value of your input is getting appended onto the URI, and it shouldn't be. Can you see anywhere that your program might be doing that?

David Hockenbroch · Sep 24, 2021 go to post

One of the properties of the %SOAP.WebClient class is HttpRequest which is an instance of %Net.HttpRequest. You might need to set the content type of that HttpRequest. So where you have "..ContentType", try "..HttpRequest.ContentType"?

David Hockenbroch · Sep 24, 2021 go to post

MAXSTRING usually indicates that you're exceeding the maximum possible length of a string somewhere. Are you sure it's a problem with the %Stream.GlobalCharacter, and not a different string variable in your program? Global character streams shouldn't have that problem.

You can see what the maximum length of a string is on your system by opening a terminal and running:

write $SYSTEM.SYS.MaxLocalLength()

David Hockenbroch · Oct 7, 2021 go to post

At the bottom of the pane you showed in your screenshot, there should be a few tabs. If you're on the "Project" tab and haven't added any classes to your project, it would look like that. If you switch it to the "Namespace" tab, you should see everything.

David Hockenbroch · Oct 11, 2021 go to post

We've seen this behavior too. Whenever we use Job, we see a license used by the user at their computer's IP address, and we also see the job running as their username@127.0.0.1 because it's executing on the server.

David Hockenbroch · Oct 15, 2021 go to post

I was updating code someone else wrote a few years ago, and they had set [Not ProcedureBlock] on the class. I'm not sure why.

David Hockenbroch · Nov 2, 2021 go to post

It looks like where you defined your method, it takes zero arguments. When you're calling it, you're providing two. That would make the event not work properly.

David Hockenbroch · Nov 2, 2021 go to post

You'll need the resource %Admin_Task to use task manager functions.

Once you have access to it, set up a class that extends %SYS.Task.Definition and override the OnTask() method. Then you can set it up in the task scheduler and it'll run the OnTask() method according to whatever schedule you set.

David Hockenbroch · Nov 4, 2021 go to post

According to this page, if it's something that still in development, you can use the CleanProduction() method to clear the message queues. Using it in a live system isn't recommended because it clears out everything pretty indiscriminately, but it's useful for debugging.

Productions get the suspend status when after shutting down there are still synchronous messages that could not be processed.

David Hockenbroch · Nov 5, 2021 go to post

Your result set should be an EnsLib.SQL.GatewayResultSet, which has a method called GetSnapshot(). That method has you pass a EnsLib.SQL.Snapshot by reference. You're probably going to want to set the FetchAll parameter on the GetSnapshot() method to 1 so it gets all the results, but you can also create your EnsLib.SQL.Snapshot before using GetSnapshot() and set it's starting row and max rows if you'd like. Then you can iterate over the snapshot instead of the result set. Once you've gone through it once, you could either create a new snapshot by calling the GetSnapshot() method again, or you can use the snapshot's Rewind() method.

David Hockenbroch · Nov 11, 2021 go to post

There's a syntax error in this line:

Set tRS = ##class(%SQL.Statement).%ExecDirect(, "Select ID From %SYS.Task Where Namespace = ? And TaskClass = ?", PICIS, "picis.core.tasks.senddelayedtrigger")

PICIS needs to be in quotes.

That wouldn't typically cause a not implemented error, though. Are you getting any errors when you try to compile the class?

David Hockenbroch · Nov 11, 2021 go to post

To use something in the task scheduler, you have to create a class that extends %SYS.Task.Definition. Within that class you have to define:

Method OnTask() As %Status{
    //The stuff you want to happen when the task is scheduled goes here.
    //In your case, that probably means calling your task method.
}

If that method is not defined, you get the "Not Implemented" error. If you've created such a class, make sure the method had the right name, isn't a classmethod, is As %Status, and does return a %Status. Also make sure the class is compiling correctly.

David Hockenbroch · Nov 13, 2021 go to post

I'm glad you found it helpful, Nigel. A fair number of our customers are still on Cache 2018. That required additional licensing costs for Ensemble, which is why I've done some of these automation projects this way. I didn't have Ensemble as an option! The Task Manager has been sufficient for our needs so far.

David Hockenbroch · Nov 16, 2021 go to post

Rochdi, when you say you've figured out how to save it to C:\Temp\filename.csv, are you saying you have it saved on the client, or on the server?

If it's saving the file on the server, you can create a class that extends %CSP.StreamServer, then override the OnPreHTTP and OnPage class methods like this for simple text files:

Class fileserver Extends %CSP.StreamServer{ClassMethod OnPreHTTP() As %Boolean{do %response.SetHeader("Content-Type","text/csv")do %response.SetHeader("Content-Disposition","attachment;filename=""myfile.csv""")quit 1}ClassMethod OnPage() As %Status{set file = ##class(%File).%New("/path/to/file.csv")do file.Open("R")while file.AtEnd '= 1{write file.ReadLine(),!}quit $$$OK}}

and then just link to it that page to download.

Once you get to things that aren't plain text, it gets a little more complicated, but this should work for a simple csv.

David Hockenbroch · Nov 17, 2021 go to post

You're exactly right; by default, the contents of the dataCombo are empty until the user clicks on it, then the query gets executed. If you set the cached property of the dataCombo to 1, it'll load as soon as the page loads instead.

David Hockenbroch · Nov 18, 2021 go to post

I don't think you can reference relationships in SqlComputeCode, so I'm not sure how you'd do this. But out of curiosity, why have a calculated field in the question class rather than just referring to it as Document.FileName (or Document->FileName in SQL)?

David Hockenbroch · Nov 18, 2021 go to post

Here's a possible alternative to using SqlComputeCode.

You can override the getter method for that property so that it always returns the related document name. In your Question class, define your docFileName property as:

Property docFileName As %String [ReadOnly];

You'll want it to be read only because you aren't going to want to be able to set this property in the question object. You're going to want to retrieve it from the document object. If it could also be set here, you'd have things weirdly out of sync. Then, in that same class, include the following method:

Method docFileNameGet() As %String{
    if ..Document '= ""{
        return ..Document.FileName
    }
    else{
        return ""
    }
}

Once you do that, whenever you refer to the question's docFileName, it'll give you the document's file name, or an empty string if there isn't one.

David Hockenbroch · Nov 22, 2021 go to post

Jacquie, I did that a couple of weeks ago, but the challenge is still "pending" even though the review was published by Gartner. How long should we expect it to take to get approved?