2026-03-17 13:31:18 -07:00

593 lines
25 KiB
Java

/*
* Decompiled with CFR 0.152.
*/
package com.tridium.sys.metrics;
import com.tridium.sys.metrics.GlobalGroup;
import com.tridium.sys.metrics.Group;
import com.tridium.sys.metrics.IMetricResource;
import com.tridium.sys.metrics.SubGroup;
import com.tridium.sys.resource.ResourceReport;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.TreeSet;
import javax.baja.collection.BIList;
import javax.baja.license.Feature;
import javax.baja.naming.BOrd;
import javax.baja.security.BICredentials;
import javax.baja.security.BPassword;
import javax.baja.spy.Spy;
import javax.baja.spy.SpyWriter;
import javax.baja.sys.BAbsTime;
import javax.baja.sys.BComplex;
import javax.baja.sys.BLink;
import javax.baja.sys.BObject;
import javax.baja.sys.BString;
import javax.baja.sys.Property;
import javax.baja.sys.SlotCursor;
import javax.baja.sys.Sys;
import javax.baja.sys.Type;
import javax.baja.util.BNotification;
import javax.baja.util.BTypeSpec;
public final class Metrics {
private static final DecimalFormat DF = new DecimalFormat("###,###,###");
private static Object lock = new Object();
private static Type scheduleType;
private static String recountLastRun;
private static String recountLastFail;
private static String recountLastFailReason;
private static GlobalGroup global;
private static Set subGroups;
private static Map moduleGroups;
private static int historyExtCount;
public static final String HISTORY_FAULT_CAUSE = "Exceeded Global Capacity history limit.";
/*
* WARNING - Removed try catching itself - possible behaviour change.
* Enabled aggressive block sorting
* Enabled unnecessary exception pruning
* Enabled aggressive exception aggregation
*/
public static final String incrementNetwork(BComplex bComplex) {
Object object = lock;
synchronized (object) {
return Metrics.incrementNetwork(bComplex, global, moduleGroups);
}
}
private static final String incrementNetwork(BComplex bComplex, GlobalGroup globalGroup, Map map) {
boolean bl = false;
if (globalGroup.excludedNetworks.contains((Object)bComplex.getType().getModule().getModuleName())) {
bl = true;
} else {
++globalGroup.networks.used;
}
Group group = Metrics.findSubGroup(bComplex, map);
if (group == null) {
return !bl && globalGroup.networks.used > globalGroup.networks.limit ? globalGroup.featureName : null;
}
++group.networks.used;
if (globalGroup.networks.used > globalGroup.networks.limit) {
return group.networks.used > group.networks.limit ? globalGroup.featureName + ',' + group.featureName : globalGroup.featureName;
}
return group.networks.used > group.networks.limit ? group.featureName : null;
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
* Enabled aggressive block sorting
* Enabled unnecessary exception pruning
* Enabled aggressive exception aggregation
*/
public static final String incrementDevice(BComplex bComplex) {
Object object = lock;
synchronized (object) {
return Metrics.incrementDevice(bComplex, global, moduleGroups);
}
}
private static final String incrementDevice(BComplex bComplex, GlobalGroup globalGroup, Map map) {
boolean bl = false;
if (globalGroup.excludedDevices.contains((Object)bComplex.getType().getModule().getModuleName())) {
bl = true;
} else {
++globalGroup.devices.used;
}
Group group = Metrics.findSubGroup(bComplex, map);
if (group == null) {
return !bl && globalGroup.devices.used > globalGroup.devices.limit ? globalGroup.featureName : null;
}
++group.devices.used;
if (globalGroup.devices.used > globalGroup.devices.limit) {
return group.devices.used > group.devices.limit ? globalGroup.featureName + ',' + group.featureName : globalGroup.featureName;
}
return group.devices.used > group.devices.limit ? group.featureName : null;
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
* Enabled aggressive block sorting
* Enabled unnecessary exception pruning
* Enabled aggressive exception aggregation
*/
public static final String incrementPoint(BComplex bComplex) {
Object object = lock;
synchronized (object) {
return Metrics.incrementPoint(bComplex, global, moduleGroups);
}
}
private static final String incrementPoint(BComplex bComplex, GlobalGroup globalGroup, Map map) {
boolean bl = false;
if (globalGroup.excludedPoints.contains((Object)bComplex.getType().getModule().getModuleName())) {
bl = true;
} else {
++globalGroup.points.used;
}
Group group = Metrics.findSubGroup(bComplex, map);
if (group == null) {
return !bl && globalGroup.points.used > globalGroup.points.limit ? globalGroup.featureName : null;
}
++group.points.used;
if (globalGroup.points.used > globalGroup.points.limit) {
return group.points.used > group.points.limit ? globalGroup.featureName + ',' + group.featureName : globalGroup.featureName;
}
return group.points.used > group.points.limit ? group.featureName : null;
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
* Enabled aggressive block sorting
* Enabled unnecessary exception pruning
* Enabled aggressive exception aggregation
*/
public static final boolean incrementLink() {
Object object = lock;
synchronized (object) {
++Metrics.global.links.used;
if (Metrics.global.links.used == Metrics.global.links.limit + 1 && Sys.getStation() != null) {
BNotification bNotification = new BNotification();
bNotification.add("title", BString.make("Capacity Licensing"));
bNotification.add("message", BString.make("Exceeded Link Limit"));
bNotification.raise(true);
}
boolean bl = false;
if (Metrics.global.links.used > Metrics.global.links.limit) return bl;
return true;
}
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
* Enabled aggressive block sorting
* Enabled unnecessary exception pruning
* Enabled aggressive exception aggregation
*/
public static final boolean incrementHistory() {
Object object = lock;
synchronized (object) {
if (Metrics.global.histories.used < Metrics.global.histories.limit) {
++Metrics.global.histories.used;
return true;
}
return false;
}
}
public static final boolean incrementSchedule(BComplex bComplex) {
return Metrics.incrementSchedule(bComplex, global);
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
* Enabled aggressive block sorting
* Enabled unnecessary exception pruning
* Enabled aggressive exception aggregation
*/
private static final boolean incrementSchedule(BComplex bComplex, GlobalGroup globalGroup) {
Property property = bComplex.getPropertyInParent();
Metrics.ensureScheduleTypeLoaded();
if (!(bComplex instanceof IMetricResource)) {
return true;
}
if (bComplex.getParent() != null && bComplex.getParent().getType().is(scheduleType) && property.isFrozen()) {
return true;
}
Object object = lock;
synchronized (object) {
++globalGroup.schedules.used;
boolean bl = false;
if (globalGroup.schedules.used > globalGroup.schedules.limit) return bl;
return true;
}
}
private static final void ensureScheduleTypeLoaded() {
if (scheduleType == null) {
try {
scheduleType = BTypeSpec.make("schedule", "CompositeSchedule").getResolvedType();
}
catch (Exception exception) {}
}
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
* Enabled aggressive block sorting
* Enabled unnecessary exception pruning
* Enabled aggressive exception aggregation
*/
public static final boolean isUsingCapacityLicensing() {
Object object = lock;
synchronized (object) {
boolean bl = false;
if (Metrics.global.isGlobalEnabled) return true;
if (moduleGroups.size() <= 0) return bl;
return true;
}
}
public static final void writeToResourceReport(ResourceReport resourceReport) {
boolean bl = false;
if (Metrics.global.isGlobalEnabled) {
bl = true;
resourceReport.put("globalCapacity.networks", Metrics.getDisplayUsed(Metrics.global.networks) + " (Limit: " + Metrics.getDisplayLimit(Metrics.global.networks) + ')');
resourceReport.put("globalCapacity.devices", Metrics.getDisplayUsed(Metrics.global.devices) + " (Limit: " + Metrics.getDisplayLimit(Metrics.global.devices) + ')');
resourceReport.put("globalCapacity.points", Metrics.getDisplayUsed(Metrics.global.points) + " (Limit: " + Metrics.getDisplayLimit(Metrics.global.points) + ')');
resourceReport.put("globalCapacity.links", Metrics.getDisplayUsed(Metrics.global.links) + " (Limit: " + Metrics.getDisplayLimit(Metrics.global.links) + ')');
if (Metrics.global.histories.used > historyExtCount) {
resourceReport.put("globalCapacity.histories", Metrics.getDisplayUsed(Metrics.global.histories) + " (Limit: " + Metrics.getDisplayLimit(Metrics.global.histories) + ')');
} else {
resourceReport.put("globalCapacity.histories", DF.format(historyExtCount) + " (Limit: " + Metrics.getDisplayLimit(Metrics.global.histories) + ')');
}
resourceReport.put("globalCapacity.schedules", Metrics.getDisplayUsed(Metrics.global.schedules) + " (Limit: " + Metrics.getDisplayLimit(Metrics.global.schedules) + ')');
}
if (moduleGroups.size() > 0) {
bl = true;
Iterator iterator = subGroups.iterator();
while (iterator.hasNext()) {
SubGroup subGroup = (SubGroup)iterator.next();
resourceReport.put(subGroup.featureName + ".networks", Metrics.getDisplayUsed(subGroup.networks) + " (Limit: " + Metrics.getDisplayLimit(subGroup.networks) + ')');
resourceReport.put(subGroup.featureName + ".devices", Metrics.getDisplayUsed(subGroup.devices) + " (Limit: " + Metrics.getDisplayLimit(subGroup.devices) + ')');
resourceReport.put(subGroup.featureName + ".points", Metrics.getDisplayUsed(subGroup.points) + " (Limit: " + Metrics.getDisplayLimit(subGroup.points) + ')');
}
}
if (bl) {
resourceReport.put("capacityLicensing.recountLastRun", recountLastRun);
resourceReport.put("capacityLicensing.recountLastFail", recountLastFail);
resourceReport.put("capacityLicensing.recountLastFailReason", recountLastFailReason);
}
}
private static final Group findSubGroup(BComplex bComplex, Map map) {
Type type = bComplex.getType();
return (Group)map.get(type.getModule().getModuleName());
}
private static final String getDisplayUsed(Group.Count count) {
return DF.format(count.used);
}
private static final String getDisplayLimit(Group.Count count) {
return count.limit == Integer.MAX_VALUE ? "none" : DF.format(count.limit);
}
private static final void loadSubGroups(Set set, Map map) {
Feature[] featureArray = Sys.getLicenseManager().getFeatures();
int n = 0;
while (n < featureArray.length) {
Feature feature = featureArray[n];
if (feature.getVendorName().toLowerCase().equals("tridium") && feature.getFeatureName().toLowerCase().startsWith("driverCapacity".toLowerCase())) {
SubGroup subGroup = new SubGroup(feature);
set.add(subGroup);
int n2 = 0;
while (n2 < subGroup.modules.length) {
map.put(subGroup.modules[n2], subGroup);
++n2;
}
}
++n;
}
}
static {
recountLastRun = "never";
recountLastFail = "never";
recountLastFailReason = "";
global = new GlobalGroup();
subGroups = new TreeSet();
moduleGroups = new HashMap();
historyExtCount = 0;
Metrics.loadSubGroups(subGroups, moduleGroups);
}
public static final class Recount
extends Thread {
private static final int INTERVAL = 30000;
private static Type NETWORK_TYPE = null;
private static Type DEVICE_TYPE = null;
private static Type POINT_TYPE = null;
private static Set subGroupsBucket = new TreeSet();
private static Map moduleGroupsBucket = new HashMap();
private SlotCursor current;
private BComplex root;
private boolean componentOnly;
private Stack nodeStack;
private GlobalGroup globalBucket;
public final void run() {
if (Metrics.isUsingCapacityLicensing()) {
try {
DEVICE_TYPE = BTypeSpec.make("driver", "Device").getResolvedType();
}
catch (Exception exception) {}
try {
NETWORK_TYPE = BTypeSpec.make("driver", "DeviceNetwork").getResolvedType();
}
catch (Exception exception) {}
try {
POINT_TYPE = BTypeSpec.make("driver", "ProxyExt").getResolvedType();
}
catch (Exception exception) {}
Metrics.ensureScheduleTypeLoaded();
this.globalBucket = new GlobalGroup();
Metrics.loadSubGroups(Recount.subGroupsBucket, Recount.moduleGroupsBucket);
boolean bl = false;
if (this.globalBucket.links.limit == Integer.MAX_VALUE) {
bl = true;
}
this.componentOnly = bl;
while (true) {
try {
Thread.sleep(30000L);
this.root = Sys.getStation();
this.current = null;
this.globalBucket.networks.used = 0;
this.globalBucket.devices.used = 0;
this.globalBucket.points.used = 0;
this.globalBucket.histories.used = 0;
this.globalBucket.links.used = 0;
this.globalBucket.schedules.used = 0;
Iterator iterator = subGroupsBucket.iterator();
while (iterator.hasNext()) {
SubGroup subGroup = (SubGroup)iterator.next();
subGroup.networks.used = 0;
subGroup.devices.used = 0;
subGroup.points.used = 0;
}
this.count();
recountLastRun = BAbsTime.make().toString();
}
catch (Exception exception) {
recountLastFail = BAbsTime.make().toString();
recountLastFailReason = exception.toString();
}
}
}
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
* Enabled aggressive block sorting
* Enabled unnecessary exception pruning
* Enabled aggressive exception aggregation
*/
private final void count() {
BObject bObject;
while (this.nextImpl()) {
bObject = this.get();
if (bObject instanceof BPassword || bObject instanceof BICredentials) continue;
this.checkMatch(bObject);
}
bObject = BOrd.make("history:|bql:select * from sys.histories");
BIList bIList = (BIList)((Object)((BOrd)bObject).resolve().get());
BOrd bOrd = BOrd.make("station:|slot:/|bql:select * from history:HistoryExt where status.isFault AND faultCause like '%Exceeded Global Capacity history limit.%'");
BIList bIList2 = (BIList)((Object)bOrd.resolve().get());
BOrd bOrd2 = BOrd.make("station:|slot:/|bql:select * from driver:HistoryImport where status.isFault and faultCause like '%Exceeded Global Capacity history limit.%'");
BIList bIList3 = (BIList)((Object)bOrd2.resolve().get());
this.globalBucket.histories.used = bIList.size();
historyExtCount = bIList.size() + bIList2.size() + bIList3.size();
Object object = lock;
synchronized (object) {
global.networks.used = this.globalBucket.networks.used;
global.devices.used = this.globalBucket.devices.used;
global.points.used = this.globalBucket.points.used;
if (!this.componentOnly) {
global.links.used = this.globalBucket.links.used;
}
global.schedules.used = this.globalBucket.schedules.used;
global.histories.used = this.globalBucket.histories.used;
Iterator iterator = subGroupsBucket.iterator();
while (iterator.hasNext()) {
SubGroup subGroup = (SubGroup)iterator.next();
Group group = (Group)moduleGroups.get(subGroup.modules[0]);
group.networks.used = subGroup.networks.used;
group.devices.used = subGroup.devices.used;
group.points.used = subGroup.points.used;
}
return;
}
}
private final void checkMatch(BObject bObject) {
if (bObject.getType().is(NETWORK_TYPE)) {
Metrics.incrementNetwork((BComplex)bObject, this.globalBucket, Recount.moduleGroupsBucket);
} else if (bObject.getType().is(DEVICE_TYPE)) {
Metrics.incrementDevice((BComplex)bObject, this.globalBucket, Recount.moduleGroupsBucket);
} else if (bObject.getType().is(POINT_TYPE)) {
Metrics.incrementPoint((BComplex)bObject, this.globalBucket, Recount.moduleGroupsBucket);
} else if (bObject.getType().is(scheduleType)) {
Metrics.incrementSchedule((BComplex)bObject, this.globalBucket);
} else if (bObject instanceof BLink) {
++this.globalBucket.links.used;
}
}
/*
* Unable to fully structure code
*/
private final boolean nextImpl() {
if (this.current == null) {
if (!this.root.isComplex()) {
return false;
}
this.current = this.root.asComplex().getProperties();
if (this.componentOnly) {
return this.current.nextComponent();
}
return this.current.next();
}
var1_1 = null;
var2_2 = null;
var3_3 = false;
if (this.componentOnly != false ? this.current.get().isComponent() != false : this.current.get().isComplex() != false) {
var1_1 = (BComplex)this.current.get();
var2_2 = var1_1.getProperties();
if (this.componentOnly) {
if (var2_2.nextComponent()) {
var3_3 = true;
}
} else if (var2_2.next()) {
var3_3 = true;
}
}
if (!var3_3) ** GOTO lbl30
if (this.nodeStack == null) {
this.nodeStack = new Stack<E>();
}
this.nodeStack.push(this.current);
this.current = var2_2;
return true;
lbl-1000:
// 1 sources
{
if (this.nodeStack == null || this.nodeStack.empty()) {
return false;
}
this.current = (SlotCursor)this.nodeStack.pop();
lbl30:
// 2 sources
** while (!(this.componentOnly != false ? this.current.nextComponent() != false : this.current.next() != false))
}
lbl31:
// 1 sources
return true;
}
private final BObject get() {
return this.current.get();
}
public Recount() {
super("Nre:Metrics.Recount");
this.setDaemon(true);
}
}
public static class MetricSpy
extends Spy {
/*
* WARNING - Removed try catching itself - possible behaviour change.
* Enabled aggressive block sorting
* Enabled unnecessary exception pruning
* Enabled aggressive exception aggregation
*/
public void write(SpyWriter spyWriter) {
Object object = lock;
synchronized (object) {
this.writeRecountTable(spyWriter);
this.writeGroup(spyWriter, global);
Iterator iterator = subGroups.iterator();
while (iterator.hasNext()) {
this.writeGroup(spyWriter, (SubGroup)iterator.next());
}
return;
}
}
private final void writeRecountTable(SpyWriter spyWriter) {
spyWriter.startTable(true);
spyWriter.trTitle("Recount", 3);
spyWriter.w("<tr>");
spyWriter.w("<td>recountLastRun</td>");
spyWriter.w("<td>").w(recountLastRun).w("</td>");
spyWriter.w("</tr>\n");
spyWriter.w("<tr>");
spyWriter.w("<td>recountLastFail</td>");
spyWriter.w("<td>").w(recountLastFail).w("</td>");
spyWriter.w("</tr>\n");
spyWriter.w("<tr>");
spyWriter.w("<td>recountLastFailReason</td>");
spyWriter.w("<td>").w(recountLastFailReason).w("</td>");
spyWriter.w("</tr>\n");
spyWriter.endTable();
spyWriter.w("<p/><p/>");
}
private final void writeGroup(SpyWriter spyWriter, Group group) {
spyWriter.startTable(true);
if (group.isGlobal()) {
spyWriter.trTitle("Global Capacity", 3);
if (((GlobalGroup)group).excludedNetworks.size() > 0) {
spyWriter.trTitle("Excluded Networks: " + ((GlobalGroup)group).excludedNetworks.toString(), 3);
}
if (((GlobalGroup)group).excludedDevices.size() > 0) {
spyWriter.trTitle("Excluded Devices: " + ((GlobalGroup)group).excludedDevices.toString(), 3);
}
if (((GlobalGroup)group).excludedPoints.size() > 0) {
spyWriter.trTitle("Excluded Points: " + ((GlobalGroup)group).excludedPoints.toString(), 3);
}
} else {
String string = group.featureName.substring("driverCapacity".length());
spyWriter.trTitle("Driver Capacity: " + string, 3);
SubGroup subGroup = (SubGroup)group;
String string2 = Arrays.asList(subGroup.modules).toString();
string2 = string2.substring(1, string2.length() - 1);
spyWriter.trTitle("Modules: " + string2, 3);
}
spyWriter.w("<tr>");
spyWriter.w("<th>Type</th>");
spyWriter.w("<th>Limit</th>");
spyWriter.w("<th>Used</th>");
spyWriter.w("</tr>\n");
this.writeRow(spyWriter, "Networks", group.networks);
this.writeRow(spyWriter, "Devices", group.devices);
this.writeRow(spyWriter, "Points", group.points);
if (group.isGlobal()) {
this.writeRow(spyWriter, "Links", ((GlobalGroup)group).links);
if (global.histories.used > historyExtCount) {
this.writeRow(spyWriter, "Histories", ((GlobalGroup)group).histories);
} else {
MetricSpy.writeRow(spyWriter, "Histories", Metrics.getDisplayLimit(((GlobalGroup)group).histories), DF.format(historyExtCount));
}
this.writeRow(spyWriter, "Schedules", ((GlobalGroup)group).schedules);
}
spyWriter.endTable();
spyWriter.w("<p/><p/>");
}
private final void writeRow(SpyWriter spyWriter, String string, Group.Count count) {
String string2 = Metrics.getDisplayLimit(count);
MetricSpy.writeRow(spyWriter, string, string2, Metrics.getDisplayUsed(count));
}
private static final void writeRow(SpyWriter spyWriter, String string, String string2, String string3) {
spyWriter.w("<tr>");
spyWriter.w("<td align='left' nowrap='true'>").w(string).w("</td>");
spyWriter.w("<td align='right' nowrap='true'>").w(string2).w("</td>");
spyWriter.w("<td align='right' nowrap='true'>").w(string3).w("</td>");
spyWriter.w("</tr>\n");
}
}
}