| 1 | // Package dummy provides a mock protocol implementation for demonstration |
| 2 | // DO NOT USE IN PRODUCTION - This is only for testing the framework |
| 3 | package dummy |
| 4 | |
| 5 | import ( |
| 6 | "fmt" |
| 7 | "math/rand" |
| 8 | "time" |
| 9 | |
| 10 | "github.com/netdata/netdata/go/plugins/plugin/ibm.d/framework" |
| 11 | ) |
| 12 | |
| 13 | // Config holds dummy client configuration |
| 14 | type Config struct { |
| 15 | ConnectionString string |
| 16 | Username string |
| 17 | Password string |
| 18 | } |
| 19 | |
| 20 | // Client is the dummy protocol client for demonstration |
| 21 | type Client struct { |
| 22 | config Config |
| 23 | metrics *framework.ProtocolClient |
| 24 | |
| 25 | // Mock state |
| 26 | connected bool |
| 27 | random *rand.Rand |
| 28 | } |
| 29 | |
| 30 | // Data structures matching what real PCF would return |
| 31 | type QueueManagerInfo struct { |
| 32 | Name string |
| 33 | Version string |
| 34 | } |
| 35 | |
| 36 | type QueueData struct { |
| 37 | Name string |
| 38 | Type string |
| 39 | CurrentDepth int64 |
| 40 | MaxDepth int64 |
| 41 | EnqueueCount int64 |
| 42 | DequeueCount int64 |
| 43 | OpenInputCount int64 |
| 44 | OpenOutputCount int64 |
| 45 | TriggerDepth int64 |
| 46 | BackoutThreshold int64 |
| 47 | HasResetStats bool |
| 48 | } |
| 49 | |
| 50 | type ChannelData struct { |
| 51 | Name string |
| 52 | Type string |
| 53 | Status int32 |
| 54 | StatusName string |
| 55 | MessageCount int64 |
| 56 | BytesSent int64 |
| 57 | BytesReceived int64 |
| 58 | BatchCount int64 |
| 59 | } |
| 60 | |
| 61 | type TopicData struct { |
| 62 | Name string |
| 63 | PublisherCount int64 |
| 64 | SubscriberCount int64 |
| 65 | MessageCount int64 |
| 66 | } |
| 67 | |
| 68 | // NewClient creates a new dummy client |
| 69 | func NewClient(config Config, state *framework.CollectorState) *Client { |
| 70 | return &Client{ |
| 71 | config: config, |
| 72 | metrics: framework.NewProtocolClient("dummy", state), |
| 73 | random: rand.New(rand.NewSource(time.Now().UnixNano())), |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | // Connect simulates establishing connection |
| 78 | func (c *Client) Connect() error { |
| 79 | return c.metrics.Track("Connect", func() error { |
| 80 | // Simulate connection delay |
| 81 | time.Sleep(100 * time.Millisecond) |
| 82 | |
| 83 | if c.config.ConnectionString == "" { |
| 84 | return fmt.Errorf("connection string required") |
| 85 | } |
| 86 | |
| 87 | c.connected = true |
| 88 | return nil |
| 89 | }) |
| 90 | } |
| 91 | |
| 92 | // Disconnect simulates closing connection |
| 93 | func (c *Client) Disconnect() error { |
| 94 | c.connected = false |
| 95 | return nil |
| 96 | } |
| 97 | |
| 98 | // GetQueueManagerInfo returns mock queue manager information |
| 99 | func (c *Client) GetQueueManagerInfo() (*QueueManagerInfo, error) { |
| 100 | var info *QueueManagerInfo |
| 101 | |
| 102 | err := c.metrics.Track("GetQueueManagerInfo", func() error { |
| 103 | if !c.connected { |
| 104 | return fmt.Errorf("not connected") |
| 105 | } |
| 106 | |
| 107 | // Mock data |
| 108 | info = &QueueManagerInfo{ |
| 109 | Name: "DUMMY_QM", |
| 110 | Version: "9.3.0.0", |
| 111 | } |
| 112 | |
| 113 | return nil |
| 114 | }) |
| 115 | |
| 116 | return info, err |
| 117 | } |
| 118 | |
| 119 | // ListQueues returns mock queue names |
| 120 | func (c *Client) ListQueues(pattern string) ([]string, error) { |
| 121 | var queues []string |
| 122 | |
| 123 | err := c.metrics.TrackWithSize("ListQueues", 128, func() (int64, error) { |
| 124 | if !c.connected { |
| 125 | return 0, fmt.Errorf("not connected") |
| 126 | } |
| 127 | |
| 128 | // Mock data - simulate various queue types |
| 129 | queues = []string{ |
| 130 | "DEV.QUEUE.1", |
| 131 | "DEV.QUEUE.2", |
| 132 | "APP.REQUEST", |
| 133 | "APP.REPLY", |
| 134 | "SYSTEM.ADMIN.COMMAND.QUEUE", |
| 135 | "SYSTEM.DEFAULT.LOCAL.QUEUE", |
| 136 | } |
| 137 | |
| 138 | // Simulate response size |
| 139 | return int64(len(queues) * 64), nil |
| 140 | }) |
| 141 | |
| 142 | return queues, err |
| 143 | } |
| 144 | |
| 145 | // GetQueueDetailsBatch returns mock queue details |
| 146 | func (c *Client) GetQueueDetailsBatch(names []string) ([]QueueData, error) { |
| 147 | var data []QueueData |
| 148 | |
| 149 | err := c.metrics.TrackWithSize("GetQueueDetailsBatch", int64(len(names)*32), func() (int64, error) { |
| 150 | if !c.connected { |
| 151 | return 0, fmt.Errorf("not connected") |
| 152 | } |
| 153 | |
| 154 | // Mock data for each queue |
| 155 | for _, name := range names { |
| 156 | qtype := "local" |
| 157 | if name == "APP.REPLY" { |
| 158 | qtype = "remote" |
| 159 | } else if len(name) > 6 && name[:6] == "SYSTEM" { |
| 160 | qtype = "local" |
| 161 | } |
| 162 | |
| 163 | // Generate random but consistent data |
| 164 | base := int64(c.random.Intn(1000)) |
| 165 | |
| 166 | data = append(data, QueueData{ |
| 167 | Name: name, |
| 168 | Type: qtype, |
| 169 | CurrentDepth: base + int64(c.random.Intn(100)), |
| 170 | MaxDepth: 5000, |
| 171 | EnqueueCount: base * 100, |
| 172 | DequeueCount: base * 95, |
| 173 | OpenInputCount: int64(c.random.Intn(5)), |
| 174 | OpenOutputCount: int64(c.random.Intn(3)), |
| 175 | TriggerDepth: 1000, |
| 176 | BackoutThreshold: 3, |
| 177 | HasResetStats: true, |
| 178 | }) |
| 179 | } |
| 180 | |
| 181 | // Simulate response size |
| 182 | return int64(len(data) * 256), nil |
| 183 | }) |
| 184 | |
| 185 | return data, err |
| 186 | } |
| 187 | |
| 188 | // ListChannels returns mock channel names |
| 189 | func (c *Client) ListChannels(pattern string) ([]string, error) { |
| 190 | var channels []string |
| 191 | |
| 192 | err := c.metrics.Track("ListChannels", func() error { |
| 193 | if !c.connected { |
| 194 | return fmt.Errorf("not connected") |
| 195 | } |
| 196 | |
| 197 | // Mock data |
| 198 | channels = []string{ |
| 199 | "SYSTEM.DEF.SVRCONN", |
| 200 | "SYSTEM.ADMIN.SVRCONN", |
| 201 | "APP.CHANNEL.1", |
| 202 | "APP.CHANNEL.2", |
| 203 | } |
| 204 | |
| 205 | return nil |
| 206 | }) |
| 207 | |
| 208 | return channels, err |
| 209 | } |
| 210 | |
| 211 | // GetChannelData returns mock channel details |
| 212 | func (c *Client) GetChannelData(name string) (*ChannelData, error) { |
| 213 | var data *ChannelData |
| 214 | |
| 215 | err := c.metrics.Track("GetChannelData", func() error { |
| 216 | if !c.connected { |
| 217 | return fmt.Errorf("not connected") |
| 218 | } |
| 219 | |
| 220 | // Mock data |
| 221 | statuses := []string{"inactive", "running", "stopped"} |
| 222 | statusName := statuses[c.random.Intn(len(statuses))] |
| 223 | |
| 224 | data = &ChannelData{ |
| 225 | Name: name, |
| 226 | Type: "SVRCONN", |
| 227 | Status: int32(c.random.Intn(7)), |
| 228 | StatusName: statusName, |
| 229 | MessageCount: int64(c.random.Intn(10000)), |
| 230 | BytesSent: int64(c.random.Intn(1000000)), |
| 231 | BytesReceived: int64(c.random.Intn(1000000)), |
| 232 | BatchCount: int64(c.random.Intn(1000)), |
| 233 | } |
| 234 | |
| 235 | return nil |
| 236 | }) |
| 237 | |
| 238 | return data, err |
| 239 | } |
| 240 | |
| 241 | // ListTopics returns mock topic names |
| 242 | func (c *Client) ListTopics(pattern string) ([]string, error) { |
| 243 | var topics []string |
| 244 | |
| 245 | err := c.metrics.Track("ListTopics", func() error { |
| 246 | if !c.connected { |
| 247 | return fmt.Errorf("not connected") |
| 248 | } |
| 249 | |
| 250 | // Mock data |
| 251 | topics = []string{ |
| 252 | "Price/Stock/IBM", |
| 253 | "Price/Stock/MSFT", |
| 254 | "Sports/Football/Results", |
| 255 | } |
| 256 | |
| 257 | return nil |
| 258 | }) |
| 259 | |
| 260 | return topics, err |
| 261 | } |
| 262 | |
| 263 | // GetTopicData returns mock topic details |
| 264 | func (c *Client) GetTopicData(name string) (*TopicData, error) { |
| 265 | var data *TopicData |
| 266 | |
| 267 | err := c.metrics.Track("GetTopicData", func() error { |
| 268 | if !c.connected { |
| 269 | return fmt.Errorf("not connected") |
| 270 | } |
| 271 | |
| 272 | // Mock data |
| 273 | data = &TopicData{ |
| 274 | Name: name, |
| 275 | PublisherCount: int64(c.random.Intn(10)), |
| 276 | SubscriberCount: int64(c.random.Intn(50)), |
| 277 | MessageCount: int64(c.random.Intn(10000)), |
| 278 | } |
| 279 | |
| 280 | return nil |
| 281 | }) |
| 282 | |
| 283 | return data, err |
| 284 | } |