Dmitry Maslennikov · Nov 20, 2020 go to post

You should understand that there are no reasons, to implement something, which can be done better with external solutions. On Linux InterSystems does not have even telnet, for the same reasons. I'm against implementing it directly in Caché/IRIS.

Back to your the next issue. You have to understand that ssh connection should use authentication, and for sure it should be done on InterSystems side, it's should be done on SSH level. And I see only one way, how to implement it, is using Kerberos. I would suggest that, if you have Windows in your park machine, you may have Active Directory, so, Singe Sign On with Active Directory, looks the best way (it's even possible with Linux). Your users in Caché, should be tied with Active Directory accounts. Target Windows server and Caché should be configured for Kerberos authentication, as well as SSH server. In this case, any user already signed on on their machine with Active Directory account, may get fast connection to the system on Caché through SSH, without any prompt for login/password. Using the right SSH client, which will support Kerberos.

It does not matter if you even used Linux, and had to solve the same task, the solution would be exactly the same.

Dmitry Maslennikov · Nov 19, 2020 go to post

Well, I have not used Admin SDK in google, yet. And it was the first time, for me. But I've managed to get JWT and AccessToken, and was able to make requests. Unfortunately, configuration on the IRIS side is very tricky.

OAuth2 Client server should be filled manually

Issuer endpoint: https://oauth2.googleapis.com/token

This issuer is important

SSL configuration: created manually, only fill the name

And two required endpoints

https://accounts.google.com/o/oauth2/v2/auth

https://oauth2.googleapis.com/token

I did not use JSON file with private key here. But I've used it for X509

I did not manage to get it worked without configured X509. 

URL from `client_x509_cert_url` field in JSON provided by Google, opened it in browser, It contains three certificates in JSON. Took the latest one. Saved in file, replaced \n with end lines.

and `private_key` from file, saved as google.key. 

When press save, it compares certificate and private key if the match, it will be saved.

Back to OAuth2, create client configurations. First of all, go to JWT settings, fill just created X509.  And Request Algorithms.

On the Client Credentials, tab fill Client ID with value of `client_email` from JSON.

Back to General, tab, fill Application name, SSL configuration. Client Type as Resource server, ( by unknown reasons will hide Request algorithms group of fields on JWT tab).

And that's it. Code to create JWT

  Set p("scope") = "https://www.googleapis.com/auth/admin.directory.user"

  Set p("exp") =  ##class(%OAuth2.Utils).TimeInSeconds($ZTimestamp, 3600)
  Set p("iat") = ##class(%OAuth2.Utils).TimeInSeconds($ZTimestamp)

  Set jwt = ##class(%SYS.OAuth2.Request).MakeRequestJWT("google", .p, .tSC)
  If $$$ISERR(tSC) {
    Do $System.OBJ.DisplayError(tSC) 
    Quit
  }
  
  Write !,"JWT:",!,jwt

It Should be quite long, and have three groups, separated by dots, if it ends with a dot, means it did not find how to sign it. Check the settings.

And request access token

  Set hs = ##class(%Net.HttpRequest).%New()
 
  Do hs.InsertFormData("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer")
  Do hs.InsertFormData("assertion", jwt)   

  Set hs.Https = 1
  Set hs.SSLConfiguration = "google"
 
  Set tSC = hs.Post("https://oauth2.googleapis.com/token")
  If $$$ISERR(tSC) {
    Do $System.OBJ.DisplayError(tSC)
    Quit
  }
  Set response = {}.%FromJSON(hs.HttpResponse.Data)
  Set accessToken = response."access_token"
 
  Write !!,"AccessToken:",!,accessToken

And finally you can use that access token in the header Authorization, with prefix Bearer

  Set hs = ##class(%Net.HttpRequest).%New()
  Do hs.SetHeader("Authorization", "Bearer " _ accessToken)
 
  Set hs.Https = 1
  Set hs.SSLConfiguration = "google"
 
  Set tSC = hs.Post("https://www.googleapis.com/admin/directory/v1/users")
  If $$$ISERR(tSC) {
    Do $System.OBJ.DisplayError(tSC)
    Quit
  }
  Set response = {}.%FromJSON(hs.HttpResponse.Data)
Dmitry Maslennikov · Nov 19, 2020 go to post

VSCode, while configured to work with docker, have a short action to open terminal, through menu on connection status

Dmitry Maslennikov · Nov 19, 2020 go to post

Configuring SSH to connect to Caché, on Windows will be almost the same as doing it on Linux.

You have to install any SSH server, for instance, OpenSSH.

And then configure there default shell, to be something like this

c:\intersystems\cache\bin\cache.exe  -s c:\intersystems\cache\mgr

or for iris, use irisdb.exe, instead

c:\intersystems\iris\bin\irisdb.exe  -s c:\intersystems\iris\mgr

but it looks, that to change default shell in openSSH, you have to edit the registry.

Dmitry Maslennikov · Nov 18, 2020 go to post

JWT, is mostly on the server-side in such relations. And in your case, I suppose google should send it. Could you please share the exact Google API you are going to use? It would be easier to understand what are you going to achieve and how to help. 

There is a way, on how to generate JWT in IRIS or in Caché latest versions, but I'm just not sure, that you are going the right way.

Dmitry Maslennikov · Nov 13, 2020 go to post

To load such XML files, you have to use

  • $system.OBJ.Load("/path/to/some.xml", "ck", .errors) - Just one file
  • $system.OBJ.LoadStream(stream, "ck", .errors) - Load from stream
  • $system.OBJ.LoadDir("/path/to/sources", "ck", .errors, 1) - Load any source code files, recursively
  • $system.OBJ.ImportDir("/path/to/sources", "*.xml", "ck", .errors, 1) - Load any source code files by specified filter, recursively
Dmitry Maslennikov · Nov 13, 2020 go to post

This may happen if you have not opened just created workspace. You have to open any folder or workspace file.

I've never faced with accents, so, not sure about this case. But I see many useful use cases for using slugify in SQL. But this feature looks more complex in realization. There are many realizations in many languages, but no standard at all.

For the info, slug, slugify, translates string in any language to ASCII, URL compatible string.

For instance, it would help to get a cost-effective, language-independent index, but with a quite correct order.

For sure, you have good points, but some points just out of scope at all. Yes, it's limited anyway.

My main point is to not have a limited number of parameters like below

ClassMethod setValue(key1, key2, key3, key4, value) As %Status

And I was just curious if the community knows how to deal with MultiDimensional property, in such a case.

Nope, still not what I mean, I have a better solution, just would like to see if the community will find it.

IRIS is a kind of replacement for Caché, which now no active development. So, while you are evaluating it, you should not look for Caché, and switch to IRIS.

Are you sure that, your insert queries send null and not an empty string? Null and empty strings are different, what are you trying to achieve it's a null, and $c(0) is an empty string.

Documentation

Unfortunately, it does not fully support work with CSP files. If you use local instance, you can just open the folder with CSP files in VSCode, and edit them as any local file. If your server is remote, so, the only way right now is using virtual filesystem isfs.

In VSCode you just had to open any local folder. And it's a manual choice. 

When you opened any folder, which is supposed to be as a project root. Configured the server connection, you then should be able to open ObjectScript Server Explorer (by InterSystems logo icon). There you can observe your code on the server, and do export from context menu. Export will be logged to ObjectScript output, with full path's of exported items. Go to File explorer in VSCode (default view), and from context menu on any folder or class, you will have action Import and compile.

Dmitry Maslennikov · Oct 31, 2020 go to post

Extracting such amount of data with using JDBC/ODBC, will be much slower than any sort of native access in Cache.

InterSystems Cache offers a way to export the whole table, with selected columns

Open System Management Portal, System Explorer, SQL. Switch to the desired namespace. Click on Wizards and select Data Export

The next steps should be pretty much simple, just select what you need to export and starts in the background. So, you will be able to control how it is going.

Look at the documentation for more details

Dmitry Maslennikov · Oct 30, 2020 go to post

Extract data could be quite tricky depending on how old is application there. If you sure that the desired data is available through SQL, so you can use any SQL tools, DataGrip, DBeaver, Squirrel-SQL. DBeaver already supports Cache out of the box, and very soon will support IRIS as well.

Dmitry Maslennikov · Oct 19, 2020 go to post

@Bob Kuszewski, what do you mean by better processes? What does it mean for jdbc driver or any other jar files, which have only one place where they supposed to be published is, maven central. Currently, InterSystems - JDBC and InterSystems XEP just contain empty files, which have to be deleted.

JAR files here, just only 155 bytes in size or even less.

https://repo1.maven.org/maven2/com/intersystems/intersystems-jdbc/3.0.0/

https://repo1.maven.org/maven2/com/intersystems/intersystems-jdbc/2018…

https://repo1.maven.org/maven2/com/intersystems/intersystems-xep/2018.1…

Dmitry Maslennikov · Oct 19, 2020 go to post

The most interesting, is why current files on maven central us completely useless? Just empty jar files.

Dmitry Maslennikov · Oct 16, 2020 go to post

In chrome you can open developer console, switch to console tab, and copy an actual link in the latest error message.

Dmitry Maslennikov · Oct 16, 2020 go to post

I can confirm that it happens due to changes in Google Chrome, it prevents downloading files from http:// when the site is opened as https://.

Dmitry Maslennikov · Oct 12, 2020 go to post

At the same time, I would not recommend spending time on official webgateway docker image, as it made to be too specific for ICM and/or Durable %SYS. And at the same time, needs some magic to get it working. e.g. apache will not start without specifically saying so. And even if it started, it does not mean, that it will be started with the CSP module enabled.

Dmitry Maslennikov · Oct 12, 2020 go to post

Instructions of what? If saying just about Apache+webgateway.

The repo I've provided is quite complete. With some basic knowledge of docker.

So, you just have to build the docker image, publish it to some docker registry, public or private and deploy it with AWS

Deploying just IRIS itself as a container does not make so much sense at all. As it needs to be packed with some application it should run. Containerized IRIS it's not the same as IRIS running on a virtual machine, it's very different, and not so easy to explain it in a simple way.

For instance, you can look at this article, about deploying some web-based IRIS application on Amazon

I would recommend, to contact me through info@caretdev.com, so, we could schedule a discussion, where you could give more details, and I will say the ways how it can be solved.