Nouvelle publication

Rechercher

Article
· Déc 8, 2023 2m de lecture

Business Service to Query Internal IRIS database

Scenario

IRIS has the likes of SQL inbound adapters for use with SQL gateways such as EnsLib.SQL.InboundAdapter to repeatedly query SQL Gateway connections. A scenario appeared as that we wanted to query an Internal database for some data but did not see an out of the box service for this. 

Desired Approach

Have a Generic service that can poll internal SQL to work with downstream components.

How

What was not clear was "How do I send a result set downstream". It was not very clear as a resultset itself is not a peristent class and the object cannot be "Swizzled" an error like so 

 <METHOD DOES NOT EXIST>zNewRequestMessage+4 ^Ens.MessageHeader.1 *%GetSwizzleObject,%sqlcq.SRFT.cls535 -- logged as '-'
number - @''

The solution was using the object 

EnsLib.SQL.Snapshot

This can then be used as a business operation to send a resultset downstream in using the function Import from resultset

set result=##class(EnsLib.SQL.Snapshot).%New()
// Some SQL query here resulting in resultset where rset is the resultset object
set tSC=result.ImportFromResultSet(rset)

You can then send this on to another operation 

set tSC=..SendRequestAsync(..ForwardComponentName,result,0)  Quit:$$$ISERR(tSC)

 

Note in the code uploaded to open exchange available here via github . The example is you can open it up and query it. The below is the classmethod that is used to put into a html. This differs from released example slightly as is taken from a live implementation. 

ClassMethod GetDataTable(pRequest As EnsLib.SQL.Snapshot, html As %String) As %String
{
  //first html obj can be if the styling needs passed
  if $ISOBJECT(html){set html=""}
  //loop get column titles 
  set ColumnIteration=1
  set ColumnCount=pRequest.%ResultColumnCountGet()
  
  set html=html_" <table class=""tg"">"
  set html= html_ " " _"<tr>"
  set meta=pRequest.%GetMetadata() //this is like raw text of the result using it to get the column titles out
  if ColumnCount>0{
    while ColumnIteration<=ColumnCount{
      
      set html= html_ " <th>"_  meta.columns.GetAt(ColumnIteration).colName _" </th>"
      set ColumnIteration=ColumnIteration+1
    }

  }
  set html= html_ " " _"</tr>"
  //not get the data from each row. In html need a <tr> and a td. 
  set coldataiteration=1
  While pRequest.%Next() {
    set html= html_ " <tr>"
    while coldataiteration <=ColumnCount{
      set html= html_ " <td> "_pRequest.%GetData(coldataiteration) _" </td>"
      set coldataiteration=coldataiteration+1
    }
    
    set html= html_ " </tr>"
    set coldataiteration=1
  }
  set html= html_ " " _"</table>"
  $$$TRACE(html)
  return html
}

Sparkei/Internal-SQL-Service: Intersystems service that can be used to query an internal SQL table to send a snapshot downstream (github.com)
 

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer
Article
· Déc 8, 2023 8m de lecture

Open AI integration with IRIS - File management

 

Artificial intelligence is not limited only to generating images through text with instructions or creating narratives with simple directions.

You can also make variations of a picture or include a special background to an already existing one.

Additionally, you can obtain the transcription of audio regardless of its language and the speed of the speaker.

So, let's analyze how the file management works.

The Problem

When analyzing the OpenAI information about the methods that require a file as an input value, the parameters must be provided using a multipart/form-data.

In IRIS we know how to create a call to a POST method using JSON content. However, in this case, using a parameter with the file content in Base64 format will not be practical.

To include the file content in a multipart/form-data, you must employ the class %Net.MIMEPart.

To include a file in our call, you should create a Content-Disposition header associated with the class object %Net.MIMEPart

set content = ##class(%Net.MIMEPart).%New()
set contentDisposition = "form-data; name="_$CHAR(34)_"image"_$CHAR(34)
set contentDisposition = contentDisposition_"; filename="_$CHAR(34)_fileName_$CHAR(34)
do content.SetHeader("Content-Disposition",contentDisposition)

Since we utilize a Request class to retain the values ​​of our process, we must convert the Base64 content into a stream that will constitute the Body of our content.

We can operate the StreamUtils utility to convert the Base64 into a Stream.

Note: the “pImage” variable contains the Base64 string of the file content.

Do ##class(HS.Util.StreamUtils).Base64Encode(pImage, .tStream)
Set content.Body = tStream

Yet, there is a better trick that I was lucky enough to learn from an InterSystems expert at the Global Summit 2023. He taught me that the execution is more effective than StreamUtils, which, in the end, has a loop that reads the String and records in the Stream.

This solution is as simple as using a JSON and doing the Get that converts it into a Stream.

set contentfile = {}
set contentfile.file = pImage
set content.Body = contentfile.%Get("file",,"stream<base64")

Once we have included all the parameters required in the call, we can finally create a new MIMEPart class to enclose the parts.

Set rootMIME = ##class(%Net.MIMEPart).%New()
do rootMIME.Parts.Insert(content)
set writer = ##class(%Net.MIMEWriter).%New()
set tSC = writer.OutputToStream(tHttpRequest.EntityBody)
set tSC = writer.WriteMIMEBody(rootMIME)
Set tContentType = "multipart/form-data; boundary="_rootMIME.Boundary
set tSC = ..Adapter.SendFormDataArray(.tHttpResponse, "POST", tHttpRequest,,,url)

This is how we send the file content to the method we need in OpenAI.

Image files

The image method allows you to send a picture and perform a variation. Since all illustrations must be in PNG format, when we indicate the file content in Base64 format, the file name is generated randomly with the PNG extension.

Here is an example of how it alters a photo.

Original Variation

As you can see, the program has interpreted instructions in its own way.

It has decided that the company logo was a circle, so it has replaced it with another one. It has also recognized that the office had a glass door and substituted it with another one but with a brick wall for now.

Besides that, it has modified the color of the shirt and changed the position of the man's arms.

Additionally, OpenIA allows you to edit an image by providing a mask with the area where you want to insert the content indicated in the prompt.

Utilizing the same image, I have applied a mask that has removed the image background.

Original Mask

When I asked it to transport me to a Jamaican beach, I got the following result:

Now you can brag about your holidays the next time you see your friends and family 😊

Image

Endpoint: POST https://api.openai.com/v1/images/variations

It allows you to create a modification of an already existing image. Since it does not require a prompt indicating how you want to alter it, we have to trust the AI's taste in how it would interpret this image. In addition, we can define the size and the way we want the result to be returned, be it through a link or content in Base64.

The input parameters would be as mentioned below:

  • image: Required
  • Here, you mention the image file that you want to transform.
  • n: Optional. Default 1
  • In this area, you determine the maximum number of images to generate. (Use numbers between 1 and 10).
  • size: Optional. Default 1024x1024
  • This parameter characterizes the size of the generated image. The value here must be “256x256”, “512x512”, or “1024x1024”.
  • response_format: Optional. By default, it is “url”
  • This element is about the format of how you wish the generated images to be returned. The values here should be “url” or “b64_json”.

Endpoint: POST https://api.openai.com/v1/images/edits

It lets you modify an existing image that, based on the mask file, will create a picture according to the prompt. Besides, we can specify the dimensions and the way we want the result to be returned to us, whether through a link or content in Base64.

The input parameters should be as follows:

  • image: Required
  • Here, you mention the image file that you want to alter.
  • mask: Required
  • This part is about the mask image file that should be applied.
  • n: Optional. Default 1
  • In this area, you determine the maximum number of images to generate. (Use numbers between 1 and 10).
  • size: Optional. Default 1024x1024
  • This parameter characterizes the size of the generated image. The value here must be “256x256”, “512x512”, or “1024x1024”.
  • response_format: Optional. By default, it is “url”
  • This element is about the format of how you wish the generated images to be returned. The values here should be “url” or “b64_json”.

Audio files

Images are not the only ones to be managed by OpenAI. We can also use audio files to obtain a transcription or translation of the provided recording.

This method uses the Whisper model, which allows you to differentiate proper names, brands, and slang to provide correct transcription and translation. For instance, talking about the “micromachine” as a brand is not the same as translating “micro machines” as a common noun into Spanish.

The upcoming example is a transcription of a well-known advertising spot from the 80s:

So, the result of instructing Whisper to make a transcription of the audio for us is as stated below:

{
    "text": "This is the Micromachine Man presenting the most midget miniature motorcade of micromachines. 
Each one has dramatic details, terrific trim, precision paint jobs, plus incredible micromachine pocket playsets. 
There's a police station, fire station, restaurant, service station, and more. Perfect pocket portables to take anyplace. 
And there are many miniature playsets to play with and each one comes with its own special edition micromachine vehicle and 
fun fantastic features that miraculously move. Raise the boat lift at the airport, marina, man the gun turret at 
the army base, clean your car at the car wash, raise the toll bridge. And these playsets fit together to form a micromachine world.
Micromachine pocket playsets, so tremendously tiny, so perfectly precise, so dazzlingly detailed, you'll want to pocket them all.
Micromachines and micromachine pocket playsets sold separately from Galoob. The smaller they are, the better they are."
}

It is Amazing! Don't you think so?

The abovementioned outcome is possible due to the training the Whisper model has received. We can see some information about it in the following diagram offered by the OpenAI page.

 

You can find more information at https://openai.com/research/whisper

Remember that it is crucial to inform the program about the file name because the service needs to know what type of file it is processing (e.g. WAV, MP3, OGG, etc).

Since we only include the Base64 content in our call, we must also indicate the file extension to create the file name with random text and the suggested extension.

For example, the St.OpenAi.Msg.Audio.AudioRequest message has the “type” property to reveal the kind of audio: MP3, OGG, WAV, FLAC, etc.

Endpoint: https://api.openai.com/v1/audio/transcriptions

This method lets you transcribe the audio content into the audio language.

The input parameters should be as follows:

  • file: Required
  • Here you specify the audio file that you want to transcribe (not the file name). It supports the following formats: FLAC, MP3, MP4, MPEG, MPGA, M4A, OGG, WAV, or WEBM
  • model: Required.
  • The model to use to make the transcription. For now, only “whisper-1” is available
  • language: Optional. By default, it is the audio language.
  • If indicated, according to ISO-639-1, it will improve accuracy and latency.
  • prompt: Optional.
  • It is an optional text to guide the style of the model or continue the previous audio segment. The message here must match the language of the audio.
  • response_format. Optional. By default, it is “json”.
  • In this part, you clarify the format of the transcription output. Use one of the following options: “json”, “text”, “verbose_json”.
  • temperature: Optional. By default, the value is 0.
  • The sampling temperature should be between 0 and 1. While higher values like 0.8 will make the output more random, lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use the log-likelihood to increase the temperature automatically until certain thresholds are reached.

You can see the documentation for this method at https://platform.openai.com/docs/api-reference/audio/createTranscription<.

Endpoint: https://api.openai.com/v1/audio/translations

This method lets you translate the audio content into English.

The input parameters should be as follows:

  • file: Required
  • It is the audio file that you wish to translate (not the file name). It supports the following formats: FLAC, MP3, MP4, MPEG, MPGA, M4A, OGG, WAV, or WEBM
  • model: Required.
  • In this field, you type the model to utilize to make the transcription. For now, only “whisper-1” is available.
  • prompt: Optional.
  • It is an optional text to guide the style of the model or continue the previous audio segment. The message here must be in English.
  • response_format. Optional. By default, it is “json”.
  • Here you determine the format of the transcription output in one of the following options: “json”, “text”, “verbose_json”.
  • temperature: Optional. By default, the value is 0.
  • The sampling temperature comes between 0 and 1. Whereas higher values like 0.8 will make the output more random, lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will employ log-likelihood to raise the temperature automatically until particular thresholds are reached.

You can explore the documentation for this method at https://platform.openai.com/docs/api-reference/audio/createTranscription.

What's next?

Since OpenAi is in continuous evolution, the next iteration will be the method to convert text into audio, and some other new features.

Remember to mark the article with a “like” if you enjoyed it.

2 Comments
Discussion (2)2
Connectez-vous ou inscrivez-vous pour continuer
Question
· Déc 6, 2023

HTTP access to list S3 buckets

I am looking for any examples on hoe to use http request to connect to S3, list buckets and loop thru them to download files recursively.

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer
Article
· Déc 4, 2023 10m de lecture

通用RESTful 业务服务和业务操作

1. 通用RESTful业务服务和业务操作


InterSystems IRIS 提供了一组通用的RESTful 业务服务和业务操作类,用户无需开发自定义的业务服务和业务操作类,就可以直接向外提供RESTful服务和调用外部的RESTful API。

BS EnsLib.REST.GenericService 通用REST业务服务
BS EnsLib.REST.SAMLGenericService 检查SAML令牌的签名和时间戳的REST业务服务
BO EnsLib.REST.GenericOperation 通用REST业务操作
BO EnsLib.REST.GenericOperationInProc 用于透传模式的通用REST业务操作

 

2. 通用RESTful 消息

 

通用的RESTful 业务服务和业务操作类使用一个通用的RESTful消息类 - EnsLib.REST.GenericMessage,它是EnsLib.HTTP.GenericMessage的子类,二者数据结构都是

HTTPHeaders 记录http头的数组
Stream 记录http体的数据流
Type 数据流类型,例如是字符流还是二进制流。自动赋值,无需设置
Attributes 记录属性的数组
OriginalFilename 无需使用
OutputFolder 无需使用
OutputFilename 无需使用

因此EnsLib.REST.GenericMessage和EnsLib.HTTP.GenericMessage都可以被通用RESTful业务操作和业务服务所使用。

 

3. 通用RESTful 业务操作

使用通用的RESTful业务操作,可以连接到任何第三方的RESTful服务器,调用其RESTful API。

3.1 向production中加入通用RESTful业务操作

增加通用RESTful业务操作,只需要在Production配置页面的操作中添加EnsLib.REST.GenericOperation。

建议加入Production时,给业务操作起一个名字,用于代表具体的业务,例如是连接到LIS的RESTful 服务,可以命名为RESTtoLIS(可以考虑的命名规则 - 接口方式+业务系统)。如果未命名,默认会使用类名作为业务操作名。

3.2 配置通用RESTful业务操作

主要的设置项是以下3个:

1. HTTP服务器:目标RESTful服务器的服务器名或IP地址

2. HTTP端口:目标RESTful服务器提供RESTful API的端口号

3. URL:RESTful API的服务端点

启用该业务操作后,既可以访问外部RESTful API了。

注意,这里URL可以不填写,而由HTTP header动态指定。

3.3 测试通用RESTful业务操作

启用后,加入的通用的RESTful业务操作即可测试了。因为EnsLib.HTTP.GenericMessage的REST消息体是一个流类型的属性,为了测试时方便输入这个数据,我们增加一个业务流程。

1. 创建一个新的业务流程,设置其请求消息为Ens.StringRequest,用于测试时传入REST body数据。并为其上下文增加一个名为DataBody、类型为%Stream.GlobalCharacter(可持久化的字符流类型)的属性:

2. 在业务流程中增加一个代码流程(<code>),将请求消息的字符串数据写入上下文的DataBody字符流:

Do context.DataBody.Write(request.StringValue)

 注意行首加空格。

 

3. 然后在业务流程中再加入一个调用流程(<call>),调用上面已经加入production的业务操作,例如RESTtoLIS,并设置请求和响应消息为EnsLib.REST.GenericMessage或EnsLib.HTTP.GenericMessage。

4. 配置RESTtoLIS业务操作的请求消息(Request)

可以直接点击构建请求消息(Request Builder)按钮,使用图形化拖拽建立请求消息:

4.1 将左边上下文context里的DataBody拖拽到callrequest的Stream属性上;

4.2 对callrequest的HTTPHeaders赋值,它是一个元素类型为字符串的数组,代表HTTP请求的头。以下3个HTTP头是必须要填写的:

HTTP头属性说明 下标
HTTP方法 "httprequest" 例如"POST"
HTTP消息体的内容类型 "content-type" 例如"application/json"
客户端希望接收的内容类型 "Accept"  例如"*/*"

这3个数组元素赋值,可以通过在添加操作下拉列表中设置(Set)进行赋值。

4.3 (此步可选)如果在3.2中没有配置URL,则可以在这里增加对HTTPHeaders里URL的设置。例如需要动态确定URL,就可以在这里进行配置。如下:

注意,如果这里设置了“URL”,它会覆盖在BO设置中的URL。

4.4 (此步可选)如果有URL参数需要配置,例如/fhir/r4/MedicationRequest?Patient=0a8eebfd-a352-522e-89f0-1d4a13abdebc&_elements=medicationReference,这里需要设置2个URL参数:Patient和_elements,可以用HTTPHeaders的IParams进行设置。

设置方法是:

先确定有多少个参数,将数量放在IParams里,例如2个,所以设置IParams为2;

之后为每个参数设置IParams_i,这里i是参数序号,例如设置IParams_1为“Patient=0a8eebfd-a352-522e-89f0-1d4a13abdebc”;

以此类推。

 

5. 将业务流程加入Production,并测试

确保Production的设置是允许调试。在Production配置页面中选中这个业务流程,在右侧的操作标签页中选择测试按钮,并在弹出的测试消息页面里填入测试用的数据,并点击调用测试服务

然后可以检查测试的消息处理流程,并确认REST消息体和HTTP消息头被正确地传递到目标REST API

 

 

4. 通用RESTful 业务服务

使用通用的RESTful业务服务,可以向外发布能处理任何RESTful API调用请求的RESTful服务端。

4.1 将通用RESTful业务服务加入Production

在Production配置页面,点击服务后面的加号。弹出的向导页面,服务类选择EnsLib.REST.GenericService;输入服务名,建议写一个能代表组件功能的名字,例如向HIS系统开放的REST服务,可以起名RESTforHIS;选中立即启用。

RESTful通用业务服务可以通过2种方式向外提供RESTful API服务:第一种通过Web服务器向外提供服务,第二种使用IRIS服务器的特定TCP端口向外提供服务。第二种方式不依赖于独立的Web服务器,但推荐使用Web服务器,从而得到更好的性能和安全性。

这里我们使用Web服务器提供REST服务,因此在业务服务的端口配置中,保持空白。在接受消息的目标名称中,选择接收RESTful API请求的业务流程或业务操作,这里我们测试使用一个空的业务流程。点击应用激活这些设置。

4.2 建立一个向外提供RESTful API的Web应用

向外发布RESTful服务,不仅涉及到服务发布的URL,还涉及到安全。我们通过创建一个专用的Web应用来进行管理和控制。

在IRIS系统管理门户>系统管理>安全>应用程序>Web应用程序 中,点击新建Web应用程序按钮,新建一个Web应用程序,并做以下配置:

1. 名称,填写一个计划发布的服务端点,例如/IRISRESTServer。注意前面的/

2. NameSpace,选择Production所在的命名空间

3. 选中启用 REST,并设置分派类EnsLib.REST.GenericService

4. 根据安全需要,配置安全设置部分。这里方便测试起见,允许的身份验证方法选择了未验证(无需验证)。如果是生产环境,或者您在做性能压力测试,都应该选择密码Kerberos安全的身份验证方式!

注意,请保证同一个命名空间下,仅有一个分派类为EnsLib.REST.GenericService的REST类型的Web应用。

 

4.3 测试RESTful业务服务

现在就可以测试这个RESTful业务服务了。这个RESTful服务可以响应任何REST API的请求,如何响应则是后续业务流程/业务操作的事。

它的完整的RESTful URL是:[Web服务器地址]:[Web服务器端口]/[Web应用的名称]/[通用REST服务在production中的配置名]/[API名称和参数],例如我在IRIS本机的私有Apache的52773端口上访问上面创建的REST通用业务服务,调用PlaceLabOrder的API (注意,这里我们并没有实现过PlaceLabOrder这个API,但我们依然可以响应,而不会报404错误),那么完整的REST 调用地址是:

127.0.0.1:52773/IRISRESTServer/RESTforHIS/PlaceLabOrder

打开POSTMAN,用POST方法,发起上面REST API的调用:

 在IRIS里会得到类似这样的消息追踪结果,如果你没有实现过处理REST API请求的业务流程,会得到一个500错,但依然可以查看IRIS产生的EnsLib.HTTP.GenericMessage消息内容:

这个通用RESTful业务服务会把REST请求转换为EnsLib.HTTP.GenericMessage消息,向目标业务操作/业务流程发送。因此,通过解析它的消息内容,就知道REST API请求的全部信息:

1. Stream里是POST的数据

2. HTTPHeaders 的下标"HttpRequest"是HTTP的方法

3. HTTPHeaders 的下标"URL"是完整的API路径,包括了服务端点(在"CSPApplication"下标下)、REST业务服务名称(在"EnsConfigName"下标下)和API

后续业务流程可以通过这些数据对REST API请求进行响应。

4.4 使用业务流程对REST API调用进行路由

有了通用RESTful业务服务生成的EnsLib.HTTP.GenericMessage消息,我们就可以使用消息路由规则或业务流程对REST API请求进行路由。这里我使用业务流程方法对REST API请求进行路由演示。

构建一个新的业务流程,请求消息和响应消息都是EnsLib.REST.GenericMessage或EnsLib.HTTP.GenericMessage,同时为context增加一个名为ReturnMsg的字符串类型的属性,并设置它默认值为:"{""Code"":-100,""Msg"":""未实现的API""}"。

在业务流程里增加一个<switch>流程,然后在<switch>下增加2个条件分支,分别为:

名称:下达检验医嘱,条件:判断是否http头的URL为PlaceLabOrder,且http头的HttpRequest为POST:

(request.HTTPHeaders.GetAt("URL")="/IRISRESTServer/RESTforHIS/PlaceLabOrder") && (request.HTTPHeaders.GetAt("HttpRequest")="POST")

名称:查询检验项目,条件:判断是否http头的URL为GetLabItems,且http头的HttpRequest为GET:

(request.HTTPHeaders.GetAt("URL")="/IRISRESTServer/RESTforHIS/GetLabItems") && (request.HTTPHeaders.GetAt("HttpRequest")="GET")

在两个分支里,分别增加<code>, 产生返回的REST消息内容:

 Set context.ReturnMsg="{""Code"":200,""Msg"":""检验医嘱下达成功""}"
 Set context.ReturnMsg="{""Code"":200,""Msg"":""查询检验项目成功""}"

最后在<switch>后增加一个<code>,构建响应消息:

 // 初始化响应消息
 set response = ##class(EnsLib.REST.GenericMessage).%New()
 // 初始化响应消息的流数据
 Set response.Stream = ##class(%Stream.GlobalCharacter).%New()
 // 将REST返回数据写入流
 Do response.Stream.Write(context.ReturnMsg)

编译这个业务流程,并将其加入Production。

之后修改通用RESTful业务服务的设置,将接收消息的目标名称改为这个新建的业务流程。

现在再通过POSTMAN测试一下各种API,并查看返回REST响应:

在真实项目中,根据实际情况,将上面<switch>流程分支的<code>替换为API响应业务流程或业务操作即可。

 

总结:使用通用RESTful业务操作和业务服务,无需创建自定义的RESTful 业务组件类,就可以调用外部RESTful API和向外提供RESTful API服务,降低开发和实施成本,实现低代码开发。

 

后记:关于EnsLib.REST.GenericService对CORS(跨域资源共享)的支持

CORS是一种基于 HTTP 头的机制,通过允许服务器标示除了它自己以外的其它origin(域、协议和端口)等信息,让浏览器可以访问加载这些资源。
所以要让EnsLib.REST.GenericService支持CORS,需要让它的响应消息增加对于CORS支持的HTTP头的信息,这里不详细介绍这些头含义了,大家可以去W3C的网站或者搜索引擎查询具体定义,最简单可以使用以下代码替代上面4.4中的初始化响应消息代码:

  // 设置HTTP响应的头信息
  set tHttpRes=##class(%Net.HttpResponse).%New()
  set tHttpRes.Headers("Access-Control-Allow-Origin")="*"
  set tHttpRes.Headers("Access-Control-Allow-Headers")="*"
  set tHttpRes.Headers("Access-Control-Allow-Methods")="*"
  // 初始化响应消息
  set response = ##class(EnsLib.REST.GenericMessage).%New(,,tHttpRes)

 

关于Cookies:
很多REST API需要事先登陆,获取会话信息并保存到Cookies中,从而作为后续API调用的认证信息。

这种情况下,需要开启Cookies。开启方法是打开REST业务操作组件的配置项“使用Cookie”,见下图。

在开启后,上次API调用返回的消息中的Cookies信息会被保存到业务组件实例中,并在下次API调用时自动加到HTTP头中。

注意,这是针对于同一个REST业务操作组件的。Cookies并不会跨不同的REST业务操作组件共享!


关于返回消息的乱码:

如果你看到返回的REST消息是中文乱码,需要取消选中“阅读原始模式”,见下图。它默认是选中的,意思是不管HTTP头里声明的Charset是什么,它都不会进行转码,因此很适合透传。但如果取消选中该设置,IRIS会基于HTTP头的Charset进行转码,转为IRIS的内码Unicode,从而在消息追踪页面显示正确的中文。

关于HTTPS:

如果IRIS的REST客户端使用HTTPS访问REST服务器端,需要在IRIS实例上配置SSL客户端:

在IRIS系统管理门户>系统管理>安全>SSL/TLS配置中,点击“新建配置”:

输入“配置名称”;

然后“类型”选中“客户端”;

并在“此客户端的凭据” 选择证书文件和密钥文件。如果你手头上没有,可以用openssl生成一对。

保存后,可以测试一下。

然后在BO的配置页面的“Connection Settings”>SSLConfig中选中上一步创建的SSL客户端名称;同时保证HTTPPort里填写正确的端口号,默认HTTPS的端口号是443:

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer
Question
· Déc 4, 2023

Custom Application Metric

I made a custom application metric, imported it to the USER namespace and used:

set status = ##class(SYS.Monitor.SAM.Config).Add.ApplicationClass("historymonitor.errorSensor", "USER")

to add it. When I do 'w status' it returns 1 so it is added but I still can't see the custom metric in the api/monitor/metrics endpoint. Even though I added %DB_USER in the application roles for api/monitor.

Does anyone know where the problem might be that the metrics endpoint still doesn't show my metric?

1 Comment
Discussion (1)2
Connectez-vous ou inscrivez-vous pour continuer