Thursday, July 26, 2018

How to encrypt sensitive data in web.config

As we write custom WebAPI applications, we need to take extra steps to secure sensitive information after deployment. Below is one of the steps you can take to encrypt the web.config file, which is a popular place where configurable sensitive information is stored.

Powerpoint slide

Cheers!

Saturday, January 13, 2018

Writing records to disk immediately using MIO

Last week, I ran into a scenario where I needed to create two subroutines that are called sequentially by another subroutine. The first sub creates a record and then the second sub queries the database for the record and performs extra processing. The workflow looks like this:
Overall Subroutine Begins
   Subroutine 1: creates a record
   Subroutine 2: does a select to obtain the record created in subroutine 1
Overall Subroutine Ends
There was a problem with this workflow that I was using just a FOR_THE command to create the record in sub 1. Since the record created in sub 1 stays in the running buffer, it never gets written back to disk until the overall sub ends. Because of that, sub 2 never finds the new record.

To get around this, my colleagues at Ferrilli suggested manually changing the MIO level so that sub 1's record is written to disk immediately. The code to be added is:

CALL @MIO.TRANSACTION(MIO.TX.SUSPEND)
FOR_THE record_id
  * set field values
END_THE record_id
CALL @MIO.TRANSACTION(MIO.TX.RESUME)

The two MIO calls modify the level of the buffer and that's where the magic happens. Using MIO.TX.SUSPEND, in effect, temporarily starts a new process level at level 0.  All I/O that is performed after the call to MIO.TRANSACTION using MIO.TX.SUSPEND will be held in MIO's buffers until the call to MIO.TRANSACTION using MIO.TX.RESUME is reached. In our case, as MIO.TX.RESUME is reached, the buffer of the transaction is flushed and the record is written to disk. Afterward, the MIO level returns to the normal running state. So my pseudo code looks like this at the end:

Overall Subroutine Begins
   Subroutine 1: creates a record
      CALL @MIO.TRANSACTION(MIO.TX.SUSPEND)
      FOR_THE record_id
          * set field values
      END_THE record_id
      CALL @MIO.TRANSACTION(MIO.TX.RESUME)
   Subroutine 2: does a select to obtain the record created in subroutine 1
Overall Subroutine Ends
Thanks Neal, Lea, and Geoff for the documentation, and Thomas Mantooth for verifying the code. GO FIGTEAM!

Wednesday, September 6, 2017

Record markers to ASCII (and vice versa)

Credits to Thomas Mantooth.

The UniData delimiters are in reverse order of their hierarchy. So, going in the other direction...

@RM (Record mark) = CHAR(255)
@FM (Field mark) = CHAR(254)
@VM (Value mark) = CHAR(253)
@SM (Sub-value mark) = CHAR(252)
@TM (Text mark) = CHAR(251)

One neat trick you can make use of with this comes into play when you use the REMOVE command. It assigns a value that indicates what type of delimiter it returns. Most of the time, you don't care what the specific delimiter is - you're just looking to see if it's zero, which is returned at the end when there's no delimiter. However, if you're dealing with something that can have multiple delimiters, you can use REMOVE and the delimiter value to build a new dynamic array with the same delimiters very simply.

LOOP
    REMOVE X.VALUE FROM XL.ARRAY SETTING X.DELIMITER
    * Do something to manipulate the data
    XL.NEW.ARRAY := X.VALUE
UNTIL NOT(X,DELIM) DO
    XL.NEW.ARRAY := CHAR(256 - X.DELIMITER)
REPEAT

Thursday, July 6, 2017

Check if a record exists

There are a few ways to check if a record exists in a file.

1. Call the S.VERIFY.RECORD.EXISTS subroutine:

X.RECORD.ID = record ID to check

CALL S.VERIFY.RECORD.EXISTS(X.EXISTS, X.FILE.NAME, X.RECORD.ID)

IF X.EXISTS = 0 THEN // record doesn't exists
END
2. Use  CONFIRMED command (this is good for when the subroutine can't be called, such as in IS sub):

X.FILE.NAME = A.FILE.NAME
X.RECORD.ID = A.RECORD.ID
A.EXISTS = 0
IF LEN(X.FILE.NAME) AND LEN(X.RECORD.ID) THEN
CONFIRM X.RECORD.ID IN_FILE(X.FILE.NAME)

IF CONFIRMED THEN
A.EXISTS = 1
END
END
Source: Neal Webb

Thursday, August 18, 2016

Padding preceding zeros to Colleague ID

In Colleague, ID numbers often have preceding 0s, and these are often truncated as the data is imported into Colleague. To add a small check to the ID to make sure it always is 7 number-long, you can add the following:

* Add zeros padding to PERSON ID
X.PERSON.ID.LEN = LEN(A.PERSON.ID)
X.ZEROS.TO.PAD = 7 - X.PERSON.ID.LEN
IF (X.ZEROS.TO.PAD GT 0) THEN
   A.PERSON.ID = STR("0", X.ZEROS.TO.PAD) : A.PERSON.ID
END

Monday, June 20, 2016

Detail to screens cross applications

If you are familiar with the application tree in Colleague, you know we can detail (UI screen) from a process to another within the same environment, or up one level, but not to the adjunct application. The tree looks like this:

                        UT
                          |
                     CORE
                   /      |      \
               ST     HR     CA

A screen from ST can detail to another screen in ST, or CORE, or UT, but it can't go to HR or CA. There's a trick to make this happen. If you want to detail to a HR screen from ST, you can do this:

   CALL S.SESSION.INIT('HR')
   CALL_SCREEN SUSPEND HRS105($PRIMARY)
   CALL S.SESSION.INIT('ST')

This code would initialize all environment variables required from HR application, open the screen, then reinitialize the ST application. 

Credit:  Eric Small from eCommunities.

Monday, May 30, 2016

WebAPI connection exception Error Subset Found: Server error-00150-No response returned from the server

When writing a Colleague custom WebAPI, I encountered a connection error while executing a transaction:

[Ellucian.Data.Colleague.Exceptions.ColleagueTransactionException] = {"Error Subset Found: Server error-00150-No response returned from the server."}

I made sure my credential was correct and the connection was established before calling the transaction. After much debugging, I found out that the string that was passed to the transaction exceeded the size limit of a field in Colleague. I passed in a 15 character long string and tried to write it to a 10 character long field in Colleague through the transaction, and it resulted in a truncation error which ended the Colleague session. This also returned the error above. They do not look like they're related, so it was hard to track down. Make sure you check the size of the arguments of the transaction when you get these error.