• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

WindhoverLabs / phoebus / #80

07 Sep 2023 10:27PM UTC coverage: 16.562% (-0.001%) from 16.563%
#80

push

lorenzo-gomez-windhover
-Various improvements to ParameterExport App (Better reporting, cleanup of resources, etc).
-TODO: Figure out memory leak.

7 of 7 new or added lines in 1 file covered. (100.0%)

17767 of 107277 relevant lines covered (16.56%)

0.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

49.46
/core/commander-core/src/main/java/com/windhoverlabs/yamcs/core/CMDR_YamcsInstance.java
1
package com.windhoverlabs.yamcs.core;
2

3
import com.windhoverlabs.pv.yamcs.YamcsPV;
4
import com.windhoverlabs.pv.yamcs.YamcsSubscriptionService;
5
import java.time.Duration;
6
import java.time.Instant;
7
import java.util.ArrayList;
8
import java.util.HashMap;
9
import java.util.List;
10
import java.util.concurrent.ExecutionException;
11
import java.util.function.Consumer;
12
import java.util.logging.Logger;
13
import javafx.collections.FXCollections;
14
import javafx.collections.ObservableList;
15
import org.yamcs.client.EventSubscription;
16
import org.yamcs.client.LinkSubscription;
17
import org.yamcs.client.Page;
18
import org.yamcs.client.YamcsClient;
19
import org.yamcs.client.archive.ArchiveClient;
20
import org.yamcs.client.mdb.MissionDatabaseClient.ListOptions;
21
import org.yamcs.client.processor.ProcessorClient;
22
import org.yamcs.protobuf.CreateEventRequest;
23
import org.yamcs.protobuf.GetServerInfoResponse;
24
import org.yamcs.protobuf.GetServerInfoResponse.CommandOptionInfo;
25
import org.yamcs.protobuf.Mdb.ParameterInfo;
26
import org.yamcs.protobuf.Pvalue.ParameterValue;
27
import org.yamcs.protobuf.SubscribeEventsRequest;
28
import org.yamcs.protobuf.links.LinkInfo;
29
import org.yamcs.protobuf.links.SubscribeLinksRequest;
30

31
// import org.yamcs.protobuf.Event;
32

33
public class CMDR_YamcsInstance extends YamcsObject<YamcsObject<?>> {
34
  public static final Logger logger = Logger.getLogger(CMDR_YamcsInstance.class.getPackageName());
1✔
35
  public static String OBJECT_TYPE = "instance";
1✔
36
  private ProcessorClient yamcsProcessor = null;
1✔
37
  private YamcsSubscriptionService paramSubscriptionService;
38
  private EventSubscription eventSubscription;
39
  private LinkSubscription linkSubscription;
40
  private MissionDatabase missionDatabase;
41
  //  private EventSubscription eventSubscription;
42
  private ArchiveClient yamcsArchiveClient;
43
  private CMDR_YamcsInstanceState instanceState;
44

45
  // TODO:Not sure if we want to have this on every instance and their server...just want it to work
46
  // for now.
47
  // Useful for "special" command link arguments such as cop1Bypass
48
  private HashMap<String, CommandOptionInfo> extraCommandArgs =
1✔
49
      new HashMap<String, CommandOptionInfo>();
50

51
  private ObservableList<CommandOption> optionsList = FXCollections.observableArrayList();
1✔
52
  private ObservableList<CMDR_Event> events = FXCollections.observableArrayList();
1✔
53
  private ObservableList<LinkInfo> links = FXCollections.observableArrayList();
1✔
54

55
  private HashMap<String, LinkInfo> linksMap = new HashMap<String, LinkInfo>();
1✔
56

57
  public HashMap<String, LinkInfo> getLinksMap() {
58
    return linksMap;
×
59
  }
60

61
  private HashMap<String, Boolean> activeInLinks = new HashMap<String, Boolean>();
1✔
62

63
  private HashMap<String, Instant> LastUpdateLinks = new HashMap<String, Instant>();
1✔
64

65
  public HashMap<String, Boolean> getActiveInLinks() {
66
    return activeInLinks;
×
67
  }
68

69
  private HashMap<String, Boolean> activeOutLinks = new HashMap<String, Boolean>();
1✔
70

71
  public ObservableList<LinkInfo> getLinks() {
72
    return links;
×
73
  }
74

75
  public CMDR_YamcsInstanceState getInstanceState() {
76
    return instanceState;
×
77
  }
78

79
  // Make this class generic?
80
  public class CommandOption {
81
    private String id;
82
    private String value;
83

84
    public CommandOption(String newId, String value) {
×
85
      this.id = newId;
×
86
      this.value = value;
×
87
    }
×
88

89
    public String getValue() {
90
      return this.value;
×
91
    }
92

93
    public String getId() {
94
      return this.id;
×
95
    }
96

97
    public void setValue(String newValue) {
98
      this.value = newValue;
×
99
    }
×
100
  }
101

102
  public ObservableList<CommandOption> getOptionsList() {
103
    return optionsList;
×
104
  }
105

106
  public HashMap<String, CommandOptionInfo> getExtraCommandArgs() {
107
    return extraCommandArgs;
×
108
  }
109

110
  public ArchiveClient getYamcsArchiveClient() {
111
    return yamcsArchiveClient;
1✔
112
  }
113

114
  public ObservableList<CMDR_Event> getEvents() {
115
    return events;
1✔
116
  }
117

118
  public ProcessorClient getYamcsProcessor() {
119
    return yamcsProcessor;
1✔
120
  }
121

122
  public CMDR_YamcsInstance(String name) {
123
    super(name);
1✔
124
  }
1✔
125

126
  @Override
127
  public ObservableList<YamcsObject<?>> getItems() {
128
    return FXCollections.emptyObservableList();
1✔
129
  }
130

131
  @Override
132
  public void createAndAddChild(String name) {
133
    throw new IllegalStateException("CMDR_YamcsInstance does not allow child items");
1✔
134
  }
135

136
  @Override
137
  public String getObjectType() {
138
    return OBJECT_TYPE;
1✔
139
  }
140

141
  protected void initProcessorClient(YamcsClient yamcsClient) {
142
    yamcsProcessor = yamcsClient.createProcessorClient(getName(), "realtime");
1✔
143
    //    yamcsClient.listProcessors(OBJECT_TYPE)
144
  }
1✔
145

146
  protected void initYamcsSubscriptionService(
147
      YamcsClient yamcsClient, String serverName, String procesor) {
148
    paramSubscriptionService =
1✔
149
        new YamcsSubscriptionService(
150
            yamcsClient.createParameterSubscription(), serverName, this.getName(), procesor);
1✔
151
  }
1✔
152

153
  protected void initLinkSubscription(YamcsClient yamcsClient, String serverName) {
154
    linkSubscription = yamcsClient.createLinkSubscription();
1✔
155
    linkSubscription.addMessageListener(
1✔
156
        linkEvent -> {
157
          switch (linkEvent.getType()) {
1✔
158
            case REGISTERED:
159
            case UPDATED:
160
              {
161
                var link = linkEvent.getLinkInfo();
1✔
162
                LinkInfo linkFromList = null;
1✔
163

164
                LastUpdateLinks.put(link.getName(), Instant.now());
1✔
165

166
                linksMap.put(link.getName(), link);
1✔
167

168
                boolean linkExistsInlList = false;
1✔
169

170
                for (var l : links) {
1✔
171
                  if (l != null) {
1✔
172
                    if (l.getName().equals(link.getName())) {
1✔
173
                      linkFromList = l;
×
174
                      linkExistsInlList = true;
×
175
                    }
176
                  }
177
                }
1✔
178

179
                if (linkExistsInlList) {
1✔
180
                  links.remove(linkFromList);
×
181
                }
182
                links.add(linksMap.get(link.getName()));
1✔
183
              }
184

185
              break;
1✔
186
            case UNREGISTERED:
187
              //               TODO but not currently sent by Yamcs
188
          }
189
        });
1✔
190

191
    linkSubscription.sendMessage(SubscribeLinksRequest.newBuilder().setInstance(getName()).build());
1✔
192
  }
1✔
193

194
  protected void initEventSubscription(YamcsClient yamcsClient, String serverName) {
195
    eventSubscription = yamcsClient.createEventSubscription();
1✔
196
    eventSubscription.addMessageListener(
1✔
197
        event -> {
198
          events.add(
×
199
              new CMDR_Event(
200
                  event.getMessage(),
×
201
                  Instant.ofEpochSecond(
×
202
                      event.getGenerationTime().getSeconds(), event.getGenerationTime().getNanos()),
×
203
                  event.getSeverity(),
×
204
                  event.getType(),
×
205
                  Instant.ofEpochSecond(
×
206
                      event.getReceptionTime().getSeconds(), event.getReceptionTime().getNanos()),
×
207
                  event.getSource(),
×
208
                  this.getName()));
×
209
        });
×
210

211
    yamcsArchiveClient = yamcsClient.createArchiveClient(getName());
1✔
212

213
    eventSubscription.sendMessage(
1✔
214
        SubscribeEventsRequest.newBuilder().setInstance(getName()).build());
1✔
215
  }
1✔
216

217
  private MissionDatabase loadMissionDatabase(YamcsClient client) {
218
    var missionDatabase = new MissionDatabase();
1✔
219

220
    var mdbClient = client.createMissionDatabaseClient(getName());
1✔
221
    try {
222
      var page = mdbClient.listParameters(ListOptions.limit(500)).get();
1✔
223
      page.iterator().forEachRemaining(missionDatabase::addParameter);
1✔
224
      while (page.hasNextPage()) {
1✔
225
        page = page.getNextPage().get();
×
226
        page.iterator().forEachRemaining(missionDatabase::addParameter);
×
227
      }
228

229
      var commandPage = mdbClient.listCommands(ListOptions.limit(200)).get();
1✔
230
      commandPage.iterator().forEachRemaining(missionDatabase::addCommand);
1✔
231
      while (commandPage.hasNextPage()) {
1✔
232
        commandPage = commandPage.getNextPage().get();
1✔
233
        commandPage.iterator().forEachRemaining(missionDatabase::addCommand);
1✔
234
      }
235
    } catch (Exception e) {
×
236
      e.printStackTrace();
×
237
      //          throw new Exception("Failed to load mission database", e);
238
    }
1✔
239
    return missionDatabase;
1✔
240
  }
241

242
  protected void initMDBParameterRDequest(YamcsClient yamcsClient, String serverName) {
243
    var mdb = yamcsClient.createMissionDatabaseClient(getName()).listParameters();
1✔
244
    Page<ParameterInfo> paramsPage = null;
1✔
245
    try {
246
      paramsPage = mdb.get();
1✔
247
    } catch (InterruptedException | ExecutionException e) {
×
248
      // TODO Auto-generated catch block
249
      e.printStackTrace();
×
250
    }
1✔
251
    var it = paramsPage.iterator();
1✔
252
    it.forEachRemaining(
1✔
253
        p -> {
254
          //          System.out.println("p-->" + p.getQualifiedName());
255

256
          for (var m : p.getType().getMemberList()) {
1✔
257
            //            System.out.println("p member-->" + m.getName());
258
          }
1✔
259
        });
1✔
260
    while (paramsPage.hasNextPage()) {
1✔
261
      //      var it = paramsPage.iterator();
262
      try {
263
        paramsPage = paramsPage.getNextPage().get();
×
264
      } catch (InterruptedException | ExecutionException e) {
×
265
        // TODO Auto-generated catch block
266
        e.printStackTrace();
×
267
      }
×
268
      it = paramsPage.iterator();
×
269
      it.forEachRemaining(
×
270
          p -> {
271
            //            System.out.println("p-->" + p.getQualifiedName());
272

273
            for (var m : p.getType().getMemberList()) {
×
274
              //              System.out.println("p member-->" + m.getName());
275
            }
×
276
          });
×
277
    }
278
  }
1✔
279

280
  /**
281
   * Initializes all of the subscriptions to the servers such as event and parameter subscriptions.
282
   * Always call this AFTER the websocket connection to YAMCS has been established. Ideally inside
283
   * the connected() method of a org.yamcs.client.ConnectionListener. Otherwise, one might cause a
284
   * race between the time we "connect" via the websocket and the time we create these
285
   * subscriptions.
286
   *
287
   * @param yamcsClient
288
   * @param serverName
289
   */
290
  // TODO:This shoud return whether or not the instance activated successfully.
291
  public void activate(YamcsClient yamcsClient, String serverName) {
292
    initProcessorClient(yamcsClient);
1✔
293
    initYamcsSubscriptionService(yamcsClient, serverName, "realtime");
1✔
294
    initEventSubscription(yamcsClient, serverName);
1✔
295
    initLinkSubscription(yamcsClient, serverName);
1✔
296
    initMDBParameterRDequest(yamcsClient, serverName);
1✔
297
    missionDatabase = loadMissionDatabase(yamcsClient);
1✔
298

299
    try {
300
      initCommandOptions(yamcsClient);
1✔
301
    } catch (InterruptedException e) {
×
302
      // TODO Auto-generated catch block
303
      e.printStackTrace();
×
304
      return;
×
305
    } catch (ExecutionException e) {
×
306
      // TODO Auto-generated catch block
307
      e.printStackTrace();
×
308
      return;
×
309
    }
1✔
310
    instanceState = CMDR_YamcsInstanceState.ACTIVATED;
1✔
311
  }
1✔
312

313
  public MissionDatabase getMissionDatabase() {
314
    return missionDatabase;
×
315
  }
316

317
  private void initCommandOptions(YamcsClient yamcsClient)
318
      throws InterruptedException, ExecutionException {
319
    GetServerInfoResponse info = yamcsClient.getServerInfo().get();
1✔
320
    System.out.println("initCommandOptions-->1");
1✔
321
    for (CommandOptionInfo o : info.getCommandOptionsList()) {
1✔
322
      extraCommandArgs.put(o.getId(), o);
×
323

324
      // Eventually check the type and create Commandoption accordingly
325
      optionsList.add(new CommandOption(o.getId(), ""));
×
326
      System.out.println("initCommandOptions-->2" + optionsList);
×
327
    }
×
328
    System.out.println("initCommandOptions-->3");
1✔
329
  }
1✔
330

331
  public void deActivate(YamcsClient yamcsClient, String serverName) {
332
    // TODO:unInit resources...
333
    instanceState = CMDR_YamcsInstanceState.DEACTIVATED;
1✔
334
    if (eventSubscription != null) {
1✔
335
      eventSubscription.cancel(true);
1✔
336
      paramSubscriptionService.destroy();
1✔
337
    }
338
  }
1✔
339

340
  public EventSubscription getEventSubscription() {
341
    return eventSubscription;
1✔
342
  }
343

344
  public void subscribePV(YamcsPV pv) {
345
    // TODO:Have to let the caller know whether were able to successfully subscribe
346
    // to this pv or not.
347
    paramSubscriptionService.register(pv);
×
348
  }
×
349

350
  /** Creates and publishes an event to YAMCS instance. */
351
  public void publishEvent(String message, YamcsClient yamcsClient) {
352
    yamcsClient.createEvent(
×
353
        CreateEventRequest.newBuilder()
×
354
            .setInstance(getName())
×
355
            .setMessage(message)
×
356
            .setSource("Commander")
×
357
            .build());
×
358
  }
×
359

360
  public ArrayList<String> getProcessors(YamcsClient yamcsClient) {
361

362
    ArrayList<String> processors = new ArrayList<String>();
×
363
    try {
364
      yamcsClient
×
365
          .listProcessors(getName())
×
366
          .get()
×
367
          .forEach(
×
368
              p -> {
369
                processors.add(p.getName());
×
370
              });
×
371
    } catch (InterruptedException | ExecutionException e) {
×
372
      // TODO Auto-generated catch block
373
      e.printStackTrace();
×
374
    }
×
375

376
    return processors;
×
377
  }
378

379
  public void switchProcessor(YamcsClient yamcsClient, String serverName, String processorName) {
380
    //          This seems redundant....
381
    paramSubscriptionService.destroy();
×
382
    initYamcsSubscriptionService(yamcsClient, serverName, processorName);
×
383
  }
×
384

385
  public void getParameters(
386
      YamcsClient yamcsClient,
387
      List<String> parameters,
388
      Instant start,
389
      Instant end,
390
      Consumer<ArrayList<Page<ParameterValue>>> consumer) {
391

392
    //    this.getYamcsArchiveClient().streamValues(parameters, consumer, start, end);
393
    ArrayList<Page<ParameterValue>> pages = new ArrayList<Page<ParameterValue>>();
×
394
    for (var p : parameters) {
×
395
      try {
396
        pages.add(this.getYamcsArchiveClient().listValues(p, start, end).get());
×
397
      } catch (InterruptedException | ExecutionException e) {
×
398
        // TODO Auto-generated catch block
399
        e.printStackTrace();
×
400
      }
×
401
    }
×
402

403
    consumer.accept(pages);
×
404
  }
×
405

406
  public void getParameter(
407
      YamcsClient yamcsClient,
408
      String parameter,
409
      Instant start,
410
      Instant end,
411
      Consumer<ArrayList<Page<ParameterValue>>> consumer) {
412

413
    //    this.getYamcsArchiveClient().streamValues(parameters, consumer, start, end);
414
    ArrayList<Page<ParameterValue>> pages = new ArrayList<Page<ParameterValue>>();
×
415
    try {
416
      pages.add(this.getYamcsArchiveClient().listValues(parameter, start, end).get());
×
417
    } catch (InterruptedException | ExecutionException e) {
×
418
      // TODO Auto-generated catch block
419
      e.printStackTrace();
×
420
    }
×
421

422
    consumer.accept(pages);
×
423
  }
×
424

425
  public boolean isLinkActive(String linkName) {
426
    return Duration.between(Instant.now(), LastUpdateLinks.get(linkName)).toMillis() < 1000;
×
427
  }
428
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc