Skip to content

Commit

Permalink
stm feed:
Browse files Browse the repository at this point in the history
- Support for INTERVAL and DELAY in milliseconds
- Default no of events to is -1 (infinite)
- Feed configuration updated default values for publish settings

stm:
- Empty payload fix (when sent as binary)
- Hex-dump only when the payload is a true binary data (non-UTF8)
  • Loading branch information
gvensan committed Oct 3, 2024
1 parent ecf4492 commit c353cde
Show file tree
Hide file tree
Showing 12 changed files with 115 additions and 82 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@solace-community/stm",
"version": "0.0.57",
"version": "0.0.58",
"description": "Solace Try-Me Command Line Tool",
"repository": {
"type": "git",
Expand Down
64 changes: 35 additions & 29 deletions public/feed/manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -953,20 +953,20 @@ async function configureApiPlaceHolderRules(rules, refresh = false) {
<div class="col-4">
<label for="count-publish" class="small">No. of Events</label>
<input id="count-publish" type="number" class="form-control"
value="${rules.publishSettings.count}" min="1" max="1000" data-param="count" onchange="publishApiSettingsChange(this)">
<span style="font-size: 0.75rem;">Range: 1 to 1000</span>
value="${rules.publishSettings.count}" min="0" max="1000" default="0" data-min="0" data-max="1000" data-default="0" data-param="count" onchange="publishApiSettingsChange(this)">
<span style="font-size: 0.75rem;">Default: 0 (infinite) or a +ve number</span>
</div>
<div class="col-4">
<label for="interval-publish" class="small">Interval (secs)</label>
<label for="interval-publish" class="small">Interval (milliseconds)</label>
<input id="interval-publish" type="number" class="form-control"
value="${rules.publishSettings.interval}" min="1" max="30" data-param="interval" onchange="publishApiSettingsChange(this)">
<span style="font-size: 0.75rem;">Range: 1 to 30 secs</span>
value="${rules.publishSettings.interval}" min="1000" max="120000" default="1000" data-min="1000" data-max="120000" data-default="1000" data-param="interval" onchange="publishApiSettingsChange(this)">
<span style="font-size: 0.75rem;">Range: 1000 - 120000 ms</span>
</div>
<div class="col-4">
<label for="delay-publish" class="small">Initial Delay (secs)</label>
<label for="delay-publish" class="small">Initial Delay (milliseconds)</label>
<input id="delay-publish" type="number" class="form-control"
value="${rules.publishSettings.delay}" min="0" max="30" data-param="delay" onchange="publishApiSettingsChange(this)">
<span style="font-size: 0.75rem;">Range: 0 to 30</span>
value="${rules.publishSettings.delay}" min="0" max="120000" default="0" data-min="0" data-max="120000" data-default="0" data-param="delay" onchange="publishApiSettingsChange(this)">
<span style="font-size: 0.75rem;">Range: 0 - 120000 ms</span>
</div>
</div>
</div>`;
Expand Down Expand Up @@ -1152,20 +1152,20 @@ async function configureMessageSendTopics(messageName, rules, refresh = false) {
<div class="col-4">
<label for="count-publish" class="small">No. of Events</label>
<input id="count-publish" type="number" class="form-control"
value="${rule.publishSettings.count}" min="1" max="1000" data-param="count" onchange="publishSettingsChange(this)">
<span style="font-size: 0.75rem;">Range: 1 to 1000</span>
value="${rule.publishSettings.count}" min="0" max="1000" default="0" data-min="0" data-max="1000" data-default="0" data-param="count" onchange="publishSettingsChange(this)">
<span style="font-size: 0.75rem;">Default: 0 (infinite) or a +ve number</span>
</div>
<div class="col-4">
<label for="interval-publish" class="small">Interval (secs)</label>
<label for="interval-publish" class="small">Interval (milliseconds)</label>
<input id="interval-publish" type="number" class="form-control"
value="${rule.publishSettings.interval}" min="1" max="30" data-param="interval" onchange="publishSettingsChange(this)">
<span style="font-size: 0.75rem;">Range: 1 to 30 secs</span>
value="${rule.publishSettings.interval}" min="0" max="120000" default="1000" data-min="0" data-max="120000" data-default="1000" data-param="interval" onchange="publishSettingsChange(this)">
<span style="font-size: 0.75rem;">Range: 0 - 120000 ms</span>
</div>
<div class="col-4">
<label for="delay-publish" class="small">Initial Delay (secs)</label>
<label for="delay-publish" class="small">Initial Delay (milliseconds)</label>
<input id="delay-publish" type="number" class="form-control"
value="${rule.publishSettings.delay}" min="0" max="30" data-param="delay" onchange="publishSettingsChange(this)">
<span style="font-size: 0.75rem;">Range: 0 to 30</span>
value="${rule.publishSettings.delay}" min="0" max="120000" default="0" data-min="0" data-max="120000" data-default="0" data-param="delay" onchange="publishSettingsChange(this)">
<span style="font-size: 0.75rem;">Range: 0 - 120000 ms</span>
</div>
</div>
</div>`;
Expand Down Expand Up @@ -1839,34 +1839,40 @@ async function exitTool() {

async function publishApiSettingsChange(evt) {
var data = evt.dataset;
console.log('DATA', data);

var feed = JSON.parse(localStorage.getItem('currentFeed'));
var rule = feed.rules

console.log('RULE', rule);
if (!rule) return;

var publishSettings = rule.publishSettings ? rule.publishSettings : {};
if (data.param === 'count') {
var val = document.getElementById('count-publish').value;
if (val < 1 || val > 1000) {
document.getElementById('count-publish').value = publishSettings.count ? publishSettings.count : 20;
return;
var el = document.getElementById(`${data.param}-publish`);
var val = el.value;
console.log('VAL', val);

if (data.param === 'count') {
if (el && (parseInt(val) < parseInt(el.getAttribute('min')) ||
parseInt(val) > parseInt(el.getAttribute('max')))) {
val = parseInt(el.getAttribute('default'));
}
document.getElementById(`${data.param}-publish`).value = val;
publishSettings[data.param] = val;
}
else if (data.param === 'interval') {
var val = document.getElementById('interval-publish').value;
if (val < 1 || val > 30) {
document.getElementById('interval-publish').value = publishSettings.interval ? publishSettings.interval : 1;
return;
if (el && (parseInt(val) < parseInt(el.getAttribute('min')) ||
parseInt(val) > parseInt(el.getAttribute('max')))) {
val = parseInt(el.getAttribute('default'));
}
document.getElementById(`${data.param}-publish`).value = val;
publishSettings[data.param] = val;
} else if (data.param === 'delay') {
var val = document.getElementById('delay-publish').value;
if (val < 0 || val > 30) {
document.getElementById('delay-publish').value = publishSettings.delay ? publishSettings.delay : 0;
return;
if (el && (parseInt(val) < parseInt(el.getAttribute('min')) ||
parseInt(val) > parseInt(el.getAttribute('max')))) {
val = parseInt(el.getAttribute('default'));
}
document.getElementById(`${data.param}-publish`).value = val;
publishSettings[data.param] = val;
}

Expand Down
32 changes: 19 additions & 13 deletions public/feed/mapform.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,8 @@ function mapAssignSubmit() {

async function publishSettingsChange(evt) {
var data = evt.dataset;
console.log(data);
console.log('DATA', data);

var feed = JSON.parse(localStorage.getItem('currentFeed'));
var topic = $('#topic_name').text();
var message = $('#message-feed-name').text();
Expand All @@ -343,31 +344,36 @@ console.log(data);
if (!rule) return;

var publishSettings = rule.publishSettings ? rule.publishSettings : {};
var el = document.getElementById(`${data.param}-publish`);
var val = el.value;
console.log('VAL', val);

if (data.param === 'count') {
var val = document.getElementById('count-publish').value;
if (val < 1 || val > 1000) {
document.getElementById('count-publish').value = publishSettings.count ? publishSettings.count : 20;
return;
if (el && (parseInt(val) < parseInt(el.getAttribute('min')) ||
parseInt(val) > parseInt(el.getAttribute('max')))) {
val = parseInt(el.getAttribute('default'));
}
document.getElementById(`${data.param}-publish`).value = val;
publishSettings[data.param] = val;
}
else if (data.param === 'interval') {
var val = document.getElementById('interval-publish').value;
if (val < 1 || val > 30) {
document.getElementById('interval-publish').value = publishSettings.interval ? publishSettings.interval : 1;
return;
if (el && (parseInt(val) < parseInt(el.getAttribute('min')) ||
parseInt(val) > parseInt(el.getAttribute('max')))) {
val = parseInt(el.getAttribute('default'));
}
document.getElementById(`${data.param}-publish`).value = val;
publishSettings[data.param] = val;
} else if (data.param === 'delay') {
var val = document.getElementById('delay-publish').value;
if (val < 0 || val > 30) {
document.getElementById('delay-publish').value = publishSettings.delay ? publishSettings.delay : 0;
return;
if (el && (parseInt(val) < parseInt(el.getAttribute('min')) ||
parseInt(val) > parseInt(el.getAttribute('max')))) {
val = parseInt(el.getAttribute('default'));
}
document.getElementById(`${data.param}-publish`).value = val;
publishSettings[data.param] = val;
}

rule.publishSettings = publishSettings;
console.log('Updated Settings', rule.publishSettings)
localStorage.setItem('currentFeed', JSON.stringify(feed));

const path = window.location.href.substring(0, window.location.href.lastIndexOf('/'));
Expand Down
2 changes: 1 addition & 1 deletion public/feedportal
8 changes: 1 addition & 7 deletions src/common/publish-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,6 @@ export class SolaceClient extends VisualizeClient {
} catch (error) {
message.setSdtContainer(solace.SDTField.create(solace.SDTFieldType.STRING, payload));
}
} else if (payloadType === 'bytes') {
message.setBinaryAttachment(payload);
} else {
if (typeof payload === 'object') {
const encoder = new TextEncoder();
Expand All @@ -195,11 +193,7 @@ export class SolaceClient extends VisualizeClient {
}
}
else {
if (payloadType === 'text') {
message.setSdtContainer(solace.SDTField.create(solace.SDTFieldType.STRING, ""));
} else {
message.setBinaryAttachment("");
}
message.setSdtContainer(solace.SDTField.create(solace.SDTFieldType.STRING, ""));
}

this.options.acknowledgeImmediately && message.setAcknowledgeImmediately(true);
Expand Down
16 changes: 8 additions & 8 deletions src/lib/feed-generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,8 @@ const generateAPIFeed = async (options: ManageFeedClientOptions, optionsSource:
var feed:any = { type: 'restapi_feed', name: feedName };
var apiRules:any = {
publishSettings: {
"count": 20,
"interval": 1,
"count": 0,
"interval": 1000,
"delay": 0
}
}
Expand Down Expand Up @@ -514,8 +514,8 @@ const generateAPIFeed = async (options: ManageFeedClientOptions, optionsSource:

const pCount = new Input({
message: `${chalkBoldWhite('Number of events')}\n` +
`${chalkBoldLabel('Hint')}: The total number of events to be published in a single feed run\n`,
initial: apiRules.publishSettings ? apiRules.publishSettings.count : '20',
`${chalkBoldLabel('Hint')}: The total number of events to be published: 0 (infinite) or a valid count\n`,
initial: apiRules.publishSettings ? apiRules.publishSettings.count : 0,
validate: (value: string) => { return !!value; }
});

Expand All @@ -530,8 +530,8 @@ const generateAPIFeed = async (options: ManageFeedClientOptions, optionsSource:

const pInterval = new Input({
message: `${chalkBoldWhite('Publish interval')}\n` +
`${chalkBoldLabel('Hint')}: The time gap (in secs) between successive publish operations\n`,
initial: apiRules.publishSettings ? apiRules.publishSettings.interval : '3',
`${chalkBoldLabel('Hint')}: The time gap (in milliseconds) between successive publish operations\n`,
initial: apiRules.publishSettings ? apiRules.publishSettings.interval : 1000,
validate: (value: string) => { return !!value; }
});

Expand All @@ -546,8 +546,8 @@ const generateAPIFeed = async (options: ManageFeedClientOptions, optionsSource:

const pDelay = new Input({
message: `${chalkBoldWhite('Initial delay')}\n` +
`${chalkBoldLabel('Hint')}: The initial delay (in secs) before the first publish operation starts\n`,
initial: apiRules.publishSettings ? apiRules.publishSettings.delay : '0',
`${chalkBoldLabel('Hint')}: The initial delay (in milliseconds) before the first publish operation starts\n`,
initial: apiRules.publishSettings ? apiRules.publishSettings.delay : 0,
validate: (value: string) => { return !!value; }
});

Expand Down
4 changes: 2 additions & 2 deletions src/lib/feed-ruleset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ const formulateRules = async (data: any) => {
topic.payload = send.message.payload.properties;
}
topic.publishSettings = {
count: 20,
interval: 1,
count: 0,
interval: 1000,
delay: 0
}
ruleSet.push(topic);
Expand Down
4 changes: 2 additions & 2 deletions src/lib/feed-run-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ const feedRunApi = async (options: ManageFeedPublishOptions, optionsSource: any)
topic: optionsSource.topic === 'cli' ? options.topic :
apiFeedRule?.hasOwnProperty('topic') ? apiFeedRule.topic : 'solace/feed/' + apiFeedInfo.name.toLowerCase(),
count: optionsSource.count === 'cli' ? options.count :
apiFeedRule.publishSettings?.hasOwnProperty('count') ? apiFeedRule.publishSettings?.count : 20,
apiFeedRule.publishSettings?.hasOwnProperty('count') ? apiFeedRule.publishSettings?.count : 0,
interval: optionsSource.interval === 'cli' ? options.interval :
apiFeedRule.publishSettings?.hasOwnProperty('interval') ? apiFeedRule.publishSettings?.interval : 3,
apiFeedRule.publishSettings?.hasOwnProperty('interval') ? apiFeedRule.publishSettings?.interval : 1000,
delay: optionsSource.initialDelay === 'cli'? options.initialDelay :
apiFeedRule.publishSettings?.hasOwnProperty('delay') ? apiFeedRule.publishSettings?.delay : 0,
published: 0
Expand Down
4 changes: 2 additions & 2 deletions src/lib/feed-run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,9 @@ const feedRun = async (options: ManageFeedPublishOptions, optionsSource: any) =>
options: options,
optionsSource: optionsSource,
count: optionsSource.count === 'cli' ? options.count :
feedRule.publishSettings?.hasOwnProperty('count') ? feedRule.publishSettings?.count : 20,
feedRule.publishSettings?.hasOwnProperty('count') ? feedRule.publishSettings?.count : 0,
interval: optionsSource.interval === 'cli' ? options.interval :
feedRule.publishSettings?.hasOwnProperty('interval') ? feedRule.publishSettings?.interval : 3,
feedRule.publishSettings?.hasOwnProperty('interval') ? feedRule.publishSettings?.interval : 1000,
delay: optionsSource.initialDelay === 'cli'? options.initialDelay :
feedRule.publishSettings?.hasOwnProperty('delay') ? feedRule.publishSettings?.delay : 0,
published: 0
Expand Down
12 changes: 1 addition & 11 deletions src/lib/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,6 @@ import { displayHelpExamplesForPublish } from '../utils/examples';
import { fileExists, saveOrUpdateCommandSettings } from '../utils/config';
import { StdinRead } from '../utils/stdinread'

const isBinaryFile = (filePath: string): boolean => {
const fileBuffer = fs.readFileSync(filePath);
for (let i = 0; i < 24; i++) {
if (fileBuffer[i] === 0) {
return true;
}
}
return false;
};

const publish = async (
options: MessageClientOptions,
optionsSource: any
Expand Down Expand Up @@ -59,7 +49,7 @@ const publish = async (
}

try {
if (isBinaryFile(file)) {
if (Logger.isBinaryFile(file)) {
message = fs.readFileSync(file, 'binary');
payloadType = 'bytes';
} else {
Expand Down
45 changes: 41 additions & 4 deletions src/utils/logger.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as fs from 'fs'
import chalk from 'chalk';
import { Signale } from 'signale'
import { prettyXML, prettyJSON } from '../utils/prettify'
Expand Down Expand Up @@ -95,6 +96,7 @@ const Logger = {
});
return str;
},

printStream: (stream: any, out: any) => {
stream.getFields().forEach((field: any) => {
if (field.getType() === 15)
Expand All @@ -103,6 +105,21 @@ const Logger = {
out += `${field.getName()}=${field.getValue()}\r\n`;
});
},

isBinaryFile: (filePath: string): boolean => {
const fileBuffer = fs.readFileSync(filePath);
return Logger.isBinaryPayload(fileBuffer);
},

isBinaryPayload(payload: any): boolean {
for (let i = 0; i < 24; i++) {
if (payload[i] === 0) {
return true;
}
}
return false;
},

prettyPrintMessage: (message: any, payload:any, messageType: number, outputMode:string, pretty: boolean) => {
var properties = message.dump(0);
if (messageType === 1) { // MAP MESSAGE
Expand Down Expand Up @@ -138,8 +155,18 @@ const Logger = {

if (payload) {
if (messageType === 0) {
var hexdump = require('hexdump-nodejs');
Logger.logMessage(`Payload\r\n${hexdump(payload)}`);
var bPayload = payload.toString('utf8').trim();
var binaryData = Logger.isBinaryPayload(payload);
if (binaryData) {
var hexdump = require('hexdump-nodejs');
Logger.logMessage(`Payload\r\n${hexdump(payload)}`);
} else if (bPayload.startsWith('<?xml')) {
var prettyPayload = prettyXML(bPayload, 2);
Logger.logMessage(`Payload\r\n${prettyPayload}`);
} else {
var prettyPayload = prettyJSON(bPayload);
Logger.logMessage(`Payload\r\n${prettyPayload}`);
}
} else if (messageType === 3) {
if (payload.startsWith('<?xml')) {
var prettyPayload = prettyXML(payload.trim(), 2);
Expand Down Expand Up @@ -175,8 +202,18 @@ const Logger = {
Logger.logMessage(`Destination: ${message.getDestination()}`);
if (payload) {
if (messageType === 0) {
var hexdump = require('hexdump-nodejs');
Logger.logMessage(`Payload\r\n${hexdump(payload)}`);
var bPayload = payload.toString('utf8').trim();
var binaryData = Logger.isBinaryPayload(payload);
if (binaryData) {
var hexdump = require('hexdump-nodejs');
Logger.logMessage(`Payload\r\n${hexdump(payload)}`);
} else if (bPayload.startsWith('<?xml')) {
var prettyPayload = prettyXML(bPayload, 2);
Logger.logMessage(`Payload\r\n${prettyPayload}`);
} else {
var prettyPayload = prettyJSON(bPayload);
Logger.logMessage(`Payload\r\n${prettyPayload}`);
}
} else if (messageType === 3) {
if (payload.startsWith('<?xml')) {
var prettyPayload = prettyXML(payload.trim(), 2);
Expand Down
4 changes: 2 additions & 2 deletions src/utils/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -648,8 +648,8 @@ export const addFeedRunOptions = (cmd: Command, advanced: boolean) => {
// message options
.addOption(new Option(`\n/* ${chalk.whiteBright('MESSAGE SETTINGS')} */`) .hideHelp(advanced))
.addOption(new Option('--count <COUNT>', chalk.whiteBright('the number of events to publish')) .argParser(parseNumber) .default(defaultMessagePublishConfig.count) .hideHelp(advanced))
.addOption(new Option('--interval <SECONDS>', chalk.whiteBright('the time to wait between publish')) .argParser(parseNumber) .default(3) .hideHelp(advanced))
.addOption(new Option('--initial-delay <SECONDS>', chalk.whiteBright('the time to wait before starting the event publish')) .argParser(parseNumber) .default(defaultMessagePublishConfig.initialDelay) .hideHelp(advanced))
.addOption(new Option('--interval <MILLISECONDS>', chalk.whiteBright('the time to wait between publish')) .argParser(parseNumber) .default(3000) .hideHelp(advanced))
.addOption(new Option('--initial-delay <MILLISECONDS>', chalk.whiteBright('the time to wait before starting the event publish')) .argParser(parseNumber) .default(defaultMessagePublishConfig.initialDelay) .hideHelp(advanced))

// message print options
.addOption(new Option(`\n/* ${chalk.whiteBright('MESSAGE OUTPUT SETTINGS')} */`) .hideHelp(advanced))
Expand Down

0 comments on commit c353cde

Please sign in to comment.