Whistle로 스크립트 작성

이 가이드에서는 파서용 휘슬 스크립트 작성에 관한 일반적인 안내를 제공합니다. Whistle 문법 및 사용 가능한 함수에 대한 자세한 내용은 Whistle 참조를 참고하세요.

휘파람 스크립트 작성

Whistle 스크립트를 작성하기 전에 다음을 수행하는 것이 좋습니다.

  1. 파서가 구독하는 소스 메시지 클래스의 메시지 스키마를 이해합니다. 매핑 실패로 인해 메시지가 데드 레터 큐에 도착하는 것을 방지하려면 Whistle 스크립트가 모든 수신 메시지를 매핑할 수 있어야 합니다. 메시지 스키마가 메시지마다 다른 경우 Whistle 스크립트에서 이러한 차이를 처리해야 합니다.

    소스 메시지 스키마를 알면 소스 메시지에 어떤 필드가 있고 데이터 유형이 무엇인지 파악하여 소스 메시지의 필드를 타겟 유형 스키마에 매핑하는 방법을 결정할 수 있습니다. 또한 소스 메시지의 어떤 부분을 타겟 스키마의 속성에 매핑해야 하는지 효과적으로 결정할 수 있도록 데이터의 시맨틱을 이해하는 것도 중요합니다.

    예를 들어 속성 값 변경 빈도를 알면 어떤 데이터를 삽입된 메타데이터로 매핑해야 하는지, 어떤 데이터를 클라우드 메타데이터로 매핑해야 하는지 결정하는 데 도움이 됩니다. 소스 메시지 클래스 모델링데이터 모델링 섹션을 참고하세요.

  2. 파서에 정의된 유형 버전의 스키마를 이해합니다. 파서의 Whistle 스크립트는 소스 메시지를 파서에 정의된 유형 버전 스키마에 매핑합니다. 유형 버전의 요구사항을 충족하는 프로토 레코드를 구성하는 방법을 알아보려면 유형 사양을 조회해야 합니다. 특히 data 필드의 스키마와 메타데이터 버킷 연결을 참고해야 합니다. 메타데이터 버킷 연결이 required: true로 표시되는지 특히 주의해야 합니다. 값으로 메타데이터 인스턴스를 조회하려는 경우 연결된 버킷의 스키마를 기록해 두어야 합니다.

  3. 휘파람 스크립트를 작성합니다. Whistle 스크립트는 실제 소스-타겟 변환을 실행합니다. 소스 메시지는 $root라는 입력에 로드됩니다. 언어 및 사용 가능한 함수에 관한 개요는 Whistle 참조를 참고하세요. 이 섹션의 다른 가이드(예: 레코드를 메타데이터 인스턴스에 연결하는 방법)도 참고하세요.

권장사항

이 섹션에서는 휘슬 스크립트 작성에 관한 권장사항을 설명합니다.

메시지 속성에 액세스할 때 null 검사 실행

속성이 정의되지 않을 수 있는 경우에는 메시지 속성에 액세스할 때 null을 확인하는 것이 좋습니다.

//Add metadata from source bucket if metadata.source attribute is present
if(isNotNil(input.metadata) and isNotNil(input.metadata.source)) then {
{
    var metadataArray[]: {
        bucketReference: {
            bucketName: "source";
            version: 1;
        };
            naturalKey: input.metadata.source;
        }
    }
}

예시

다음 섹션에서는 Whistle을 사용한 기본 작업의 몇 가지 예를 보여줍니다.

간단한 Whistle 매핑

다음 소스 메시지가 주어졌다고 가정해 보겠습니다.

{
  "sensor": "rotation-speed-sensor",
  "machine": "m-234",
  "timestamp": "1687973092857",
  "value": 1200
}

다음 Whistle 스크립트:

package mde

[
    {
        tagName: $root.machine + " - " + $root.sensor;
        data: {
            numeric: $root.value;
        };
        timestamps: {
            eventTimestamp: $root.timestamp;
        }
    }
]

파서는 다음과 같은 프로토 레코드 출력을 생성합니다.

[
  {
    "tagName": "m-234-rotation-speed-sensor",
    "data": {
      "numeric": 1200
    },
    "timestamps": {
      "eventTimestamp": "1687973092857"
    }
  }
]

함수를 사용한 간단한 Whistle 매핑

다음 소스 메시지가 주어졌다고 가정해 보겠습니다.

{
  "sensor": "rotation-speed-sensor",
  "machine": "m-234",
  "timestamp": "1687973092857",
  "value": 1200
}

다음 Whistle 스크립트:

package mde

[
    {
        tagName: getTagName($root);
        data: getValue($root);
        timestamps: getTimestamp($root)
    }
]

def getTagName(input) {
    input.machine + "-" + input.sensor;
}

def getTimestamp(input) {
    eventTimestamp: input.timestamp;
}

def getValue(input) {
    numeric: input.value;
}

파서는 다음과 같은 프로토 레코드 출력을 생성합니다.

[
  {
    "tagName": "m-234-rotation-speed-sensor",
    "data": {
      "numeric": 1200
    },
    "timestamps": {
      "eventTimestamp": "1687973092857"
    }
  }
]

파서 1에서 여러 프로토 레코드 내보내기

다음 소스 메시지가 주어졌다고 가정해 보겠습니다.

{
  "tag": "plc-34",
  "machine": "controller",
  "timestamp": "1687973092857",
  "values": [200, 499]
}

다음 Whistle 스크립트:

package mde

var valueLen: listLen($root.values);
var indexes: range(0, valueLen);

[
    getProtoRecords($root.values[], indexes[], $root)
]

def getProtoRecords(value, index, input) {
        tagName: input.machine + "-" + input.tag + "-" + index;
        data: {
            numeric: value;
        };
        timestamps: {
            eventTimestamp: input.timestamp;
        };
}

파서는 다음과 같은 프로토 레코드 출력을 생성합니다.

[
  {
    "tagName": "controller-plc-34-0",
    "data": {
      "value": 200.0
    },
    "timestamps": {
      "eventTimestamp": "1687973092857"
    }
  },
  {
    "tagName": "controller-plc-34-1",
    "data": {
      "value": 499.0
    },
    "timestamps": {
      "eventTimestamp": "1687973092857"
    }
  }
]

파서 2에서 여러 프로토 레코드 내보내기

다음 소스 메시지가 주어졌다고 가정해 보겠습니다.

{
  "machine": "controller",
  "timestamp": "1687973092857",
  "sensors": [
    {
      "tag": "plc-34",
      "value": 200
    },
    {
      "tag": "plc-35",
      "value": 499
    }
  ]
}

다음 Whistle 스크립트:

package mde

[$$
    getProtoRecords($root.sensors[], $root)
]

def getProtoRecords(sensor, input) {
        tagName: input.machine + "-" + sensor.tag;
        data: {
            numeric: sensor.value;
        };
        timestamps: {
            eventTimestamp: input.timestamp;
        };
}

파서는 다음과 같은 프로토 레코드 출력을 생성합니다.

[
  {
    "tagName": "controller-plc-34",
    "timestamps": {
      "eventTimestamp": "1687973092857"
    },
    "data": {
      "numeric": 200
    }
  },
  {
    "tagName": "controller-plc-35",
    "timestamps": {
      "eventTimestamp": "1687973092857"
    },
    "data": {
      "numeric": 499
    }
  }
]