Article Eduard Lebedyuk · Mar 13, 2018 4m read

In this series of articles, I'd like to present and discuss several possible approaches toward software development with InterSystems technologies and GitLab. I will cover such topics as:

  • Git 101
  • Git flow (development process)
  • GitLab installation
  • GitLab Workflow
  • Continuous Delivery
  • GitLab installation and configuration
  • GitLab CI/CD

In the first article, we covered Git basics, why a high-level understanding of Git concepts is important for modern software development, and how Git can be used to develop software.

In the second article, we covered GitLab Workflow - a complete software life cycle process and Continuous Delivery.

I this article we'll discuss:

  • GitLab installation and configuration
  • Connecting your environments to GitLab
2
1 2187
Article Eduard Lebedyuk · Mar 7, 2018 7m read

In this series of articles, I'd like to present and discuss several possible approaches toward software development with InterSystems technologies and GitLab. I will cover such topics as:

  • Git 101
  • Git flow (development process)
  • GitLab installation
  • GitLab Workflow
  • Continuous Delivery
  • GitLab installation and configuration
  • GitLab CI/CD

In the previous article, we covered Git basics, why a high-level understanding of Git concepts is important for modern software development, and how Git can be used to develop software. Still, our focus was on the implementation part of software development, but this part presents:

  • GitLab Workflow - a complete software life cycle process - from idea to user feedback
  • Continuous Delivery - software engineering approach in which teams produce software in short cycles, ensuring that the software can be reliably released at any time. It aims at building, testing, and releasing software faster and more frequently.
1
3 3477
Article Eduard Lebedyuk · Mar 1, 2018 6m read

Everybody has a testing environment.

Some people are lucky enough to have a totally separate environment to run production in.

-- Unknown

.

In this series of articles, I'd like to present and discuss several possible approaches toward software development with InterSystems technologies and GitLab. I will cover such topics as:

  • Git 101
  • Git flow (development process)
  • GitLab installation
  • GitLab WorkFlow
  • GitLab CI/CD
  • CI/CD with containers

This first part deals with the cornerstone of modern software development - Git version control system and various Git flows.

1
4 4979
Article Eduard Lebedyuk · Feb 20, 2018 1m read

I needed to know programmatically if last ran failed or not.

After some exploring, here's the code:

ClassMethod isLastTestOk() As %Boolean
{
  set in = ##class(%UnitTest.Result.TestInstance).%OpenId(^UnitTest.Result)
  for i=1:1:in.TestSuites.Count() {
    #dim suite As %UnitTest.Result.TestSuite
    set suite = in.TestSuites.GetAt(i)
    return:suite.Status=0 $$$NO
  }
  quit $$$YES
}
4
1 697
Question Eduard Lebedyuk · Feb 20, 2018

Several $System.OBJ methods have ByRef errorlog argument:

Compile(ByRef classes As %String = "", qspec As %String = "", ByRef errorlog As %String, recurse As %Boolean = 0)

ImportDir(dir As %String = "", wildcards As %String, qspec As %String = "", ByRef errorlog As %String, recurse As %Boolean = 0, ByRef imported As %String, listonly As %Boolean, ByRef selectedlist As %String)

What's the best approach of working with errorlog?

Do you convert it to status? If so - how? Manual iteration over local?

Is there some system method to convert it into %Status?

1
0 407
Question Eduard Lebedyuk · Feb 19, 2018

Let's say I want to execute  this cache script (saved as test.txt) from OS terminal:

zn "USER"
write 1
zn "%SYS"
write 2
halt

Executing the following command in a terminal:

csession cache < test.txt

Would yield this output:

$ csession cache < script.txt

Node: gitlab-test, Instance: CACHE

USER>

USER>
1
USER>

%SYS>
2
%SYS>
Job succeeded

Is there a better way to run these scripts?

Currently I have two problems:

  1. I have several variables defined in my bash script, what's the best approach to pass them into Caché?
1
0 1162
Question Eduard Lebedyuk · Feb 5, 2018

Currently to check if the class  is mapped I call:

ClassMethod IsClassMapped(class) As %Boolean

{
  set sc = $system.OBJ.GetClassList(.classes,"/system=0 /percent=0 /mapped=0")
  quit $data(classes(class))
}

And it works, but I'm interested if there is a simpler approach out there?

2
0 443
Question Eduard Lebedyuk · Dec 25, 2017

Let's say I have Macro.Parent class:

Include Parent
Class Macro.Parent
{

ClassMethod Test()
{
    write "Class: " _ $classname() _ $c(10,13) _ "Value: " _ $$$name
}

}

which references Parent.inc macro name:

#define name "Parent"

Now, I want in my subclass Macro.Child to have Test method with the same code, but to redefine value of name macro.

6
0 446
Article Eduard Lebedyuk · Dec 7, 2017 3m read

In this article I'd like to discuss asynchronous REST and approaches to implementing it.

Why do we need asynchronous REST? Simply put - answering the request takes too much time. While most requests usually can be satisfied immediately, some can't. The reasons are varied:

  • You need to perform time-consuming calculations
  • Performing action actually takes time (for example container creation)
  • etc.

The solution to these problems is asynchronous REST. Asynchronous REST works by separating request and real response. Here's an example, let's consider the following simple async REST broker:

9
0 1897
Question Eduard Lebedyuk · Oct 30, 2017

I'm extracting text from HTML (more on how - here), and after I extract text it has two problems:

  • Lot's of $c(10) control characters
  • Multiple whitespaces

Here's an example of the text extracted from HTML page:

set text = " "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_" Word1"_$c(10)_" "_$c(10)_" "_$c(10)_" "_$c(10)_"
2
0 2031
Question Eduard Lebedyuk · Oct 26, 2017

I have a classname and a property name. I want to know, when I get object value directly from a global, which property corresponds to which position in the $lb structure.

Here's what I got so far:

Class Utils.Storage {

/// write ##class(Utils.Storage).GetPosition()
ClassMethod GetPosition(class As %Dictionary.CacheClassname = "Sample.Address", property As %Dictionary.CacheIdentifier = "Zip") As %Integer
{
    set strategy = $$$comClassKeyGet(class, $$$cCLASSstoragestrategy)    
    set strategyId  = class _ "||" _ strategy
    &sql(SELECT Name INTO :position
         FROM %Dictionary.
6
0 701
Question Eduard Lebedyuk · Oct 5, 2017

Trying to connect Ensemble to RabbitMQ following this article I'm using Java Gateway and encountered the following problem - in all my calls I need to pass connection object, which is always the same but it takes a long time to create. Here's java code:

package com.myorgname.rabbitmq;

import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.
1
0 515
Question Eduard Lebedyuk · Sep 5, 2017

Let's say I have this property:

Property FavoriteColors As List Of %String;

I heed to convert it to JSON using SQL or at least without object access (so direct global access).

What's the fastest way to do that?

I thought about JSON_ARRAY and JSON_ARRAYAGG sql functions but they don't do that.

5
0 1400
Article Eduard Lebedyuk · Sep 4, 2017 5m read

In the first article I started discussing RESTForms - REST API for your persistent classes. We talked about basic features, now, I'd like to discuss advanced features - mainly queries capabilites:

  • Basic queries
  • Query arguments
  • Custom queries

Queries

Queries allow getting slices of data, based on arbitrary criteria. There are two query types in RESTForms:

  • Basic queries work for all RESTForms classes once defined and they differ only by the field list
  • Custom queries work only for the classes in which they are specified and available, but the developer has full access to query text
2
2 1807
Question Eduard Lebedyuk · Aug 31, 2017

I need to check if one class is a subclass of another (either direct or indirect).

For example:

Class Package.ClassA Extends %Library.Persistent
{
}

Class Package.ClassB Extends Package.ClassA 
{
}

Class Package.ClassC Extends Package.ClassB
{
}

In this example Package.ClassC is a subclass of 3 classes: %Library.Persistent, Package.ClassA, Package.ClassB.

So any of these checks should return 1:

Write ##class(Some.System.Class).IsSubclass("Package.ClassC", "%Library.Persistent")
Write ##class(Some.System.Class).IsSubclass("Package.ClassC", " Package.ClassA")
Write ##class(Some.System.
3
0 952
Question Eduard Lebedyuk · Aug 31, 2017

I need to get a list of all classes that are subclasses of two unrelated classes.

For example I want to get a list of all classes that are both:

  • Persistent (extends %Library.Persistent)
  • XML-Enabled (extends %XML.Adaptor)

To get subclasses of one class I can use this query:

set rs = ##class(%Dictionary.ClassDefinitionQuery).SubclassOfFunc("%Library.Persistent")

But what about two classes?

I suppose I can run this query twice, build two $lb, then iterate over one of them and build a new $lb with classes that appear in both lists. Are there any better approaches?

6
0 745
Question Eduard Lebedyuk · Aug 8, 2017

I have a Caché server with external apache.

It has a hostname, i.e.: http://myserver.com

There is an index page, which is available over http://myserver.com/index.html (/ is a Caché CSP app)

How can I make index.html available from http://myserver.com?

Here's the relevant parts of my apache config:

<Directory />
    CSP On
    DirectoryIndex index.html
    Options FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>
<Location />
    DirectoryIndex index.
3
0 908
Question Eduard Lebedyuk · Jul 26, 2017

I'm trying to create asynchronous Ensemble service/operation pair for SOAP passthrough.

General configuration:

  • Ensemble Service receives a message and immediately returns an answer to a caller (message received or some error)
  • Ensemble Service asynchronously calls Business Operation
  • Business Operation  does guaranteed message delivery, etc.

Is it a viable approach?

Any tips? Ideas? Caveats? Code?

Seems like I can sublass EnsLib.SOAP.GenericService and change Sync to ASync (and provide a default reply immediately).

3
0 836
Question Eduard Lebedyuk · Jul 26, 2017

I have tried to create Ensemble SOAP passthrough operation following this guide.

Here's my production configuration (after steps 1-4):

Class Passthrough.Production Extends Ens.Production
{

XData ProductionDefinition
{
<Production Name="Passthrough.Production" LogGeneralTraceEvents="false">
  <Description></Description>
  <ActorPoolSize>2</ActorPoolSize>
  <Item Name="PassthroughOperation" Category="" ClassName="EnsLib.SOAP.GenericOperation" PoolSize="1" Enabled="true" Foreground="false" Comment="" LogTraceEvents="false" Schedule="">
    <Setting Target="Adapter" Name="HTTPServer">www.
3
0 738
Question Eduard Lebedyuk · Jul 10, 2017

Hi, Community!

And so I continue with publishing of the tasks for the Final round of InterSystems Contest on InterSystems Caché and DeepSee as a part of IT Planet Student Championship in Sochi. This year we had about 2 000 participants in InterSystems Contest.

One of the tasks for the finals was to crack the black box and another to output 9876543210!

Here's the next task: gravity!

3
0 456