Skip to content

Commit 5551fa5

Browse files
committed
Updated for Ignition 8.3
1 parent 9c41538 commit 5551fa5

42 files changed

Lines changed: 9174 additions & 222 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,10 @@
33
**/*.iml
44
IgnitionNodeRED-build/target/*
55
IgnitionNodeRED-gateway/target/*
6+
.gradle
7+
.idea
8+
build/
9+
IgnitionNodeRED-web/node_modules/
10+
IgnitionNodeRED-web/.gradle
11+
IgnitionNodeRED-web/build
12+
*.DS_Store

IgnitionNodeRED-build/pom.xml

Lines changed: 0 additions & 67 deletions
This file was deleted.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
plugins {
2+
`java-library`
3+
}
4+
5+
java {
6+
toolchain {
7+
languageVersion.set(org.gradle.jvm.toolchain.JavaLanguageVersion.of(17))
8+
}
9+
}
10+
11+
dependencies {
12+
// add common scoped dependencies here
13+
compileOnly("com.inductiveautomation.ignitionsdk:ignition-common:${rootProject.extra["sdk_version"]}")
14+
compileOnly("com.inductiveautomation.ignitionsdk:gateway-api:${rootProject.extra["sdk_version"]}")
15+
compileOnly("org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jetty-server:12.0.27")
16+
modlImplementation(projects.ignitionNodeREDWeb)
17+
}

IgnitionNodeRED-gateway/src/main/java/org/imdc/nodered/GatewayHook.java

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,61 @@
11
package org.imdc.nodered;
22

3-
import com.google.common.collect.Lists;
43
import com.inductiveautomation.ignition.common.BundleUtil;
54
import com.inductiveautomation.ignition.common.licensing.LicenseState;
5+
import com.inductiveautomation.ignition.common.resourcecollection.ResourceType;
6+
import com.inductiveautomation.ignition.gateway.config.ResourceTypeMeta;
7+
import com.inductiveautomation.ignition.gateway.config.migration.IdbMigrationStrategy;
8+
import com.inductiveautomation.ignition.gateway.config.migration.NamedRecordMigrationStrategy;
69
import com.inductiveautomation.ignition.gateway.model.AbstractGatewayModuleHook;
710
import com.inductiveautomation.ignition.gateway.model.GatewayContext;
8-
import com.inductiveautomation.ignition.gateway.web.models.ConfigCategory;
9-
import com.inductiveautomation.ignition.gateway.web.models.IConfigTab;
11+
import com.inductiveautomation.ignition.gateway.web.systemjs.SystemJsModule;
1012
import org.imdc.nodered.servlet.NodeREDServlet;
1113
import org.imdc.nodered.servlet.NodeREDWebSocketServlet;
1214
import org.slf4j.Logger;
1315
import org.slf4j.LoggerFactory;
1416

15-
import java.sql.SQLException;
1617
import java.util.List;
18+
import java.util.Optional;
1719

1820
public class GatewayHook extends AbstractGatewayModuleHook {
1921

22+
public static final String MODULE_ID = "org.imdc.nodered.IgnitionNodeRED";
23+
public static final String MODULE_NAME = "Node-RED";
24+
public static final String PREFIX = "nodered";
25+
26+
public static final ResourceType TOKEN_RESOURCE_TYPE =
27+
new ResourceType(MODULE_ID, "token");
28+
29+
public static final ResourceTypeMeta<NodeREDAPITokenResource> TOKEN_RESOURCE_TYPE_META =
30+
ResourceTypeMeta.newBuilder(NodeREDAPITokenResource.class)
31+
.resourceType(TOKEN_RESOURCE_TYPE)
32+
.categoryName("Token")
33+
.buildRouteDelegate(routes -> routes
34+
.configSchema(NodeREDAPITokenResource.class)
35+
.openApiGroupName(MODULE_NAME)
36+
.openApiTagName("token")
37+
).build();
38+
39+
public static SystemJsModule jsModule =
40+
new SystemJsModule(MODULE_ID,
41+
"/res/" + PREFIX + "/ignitionnodered.js");
42+
2043
private final Logger logger = LoggerFactory.getLogger(getClass());
2144
private GatewayContext gatewayContext;
2245

2346
@Override
2447
public void setup(GatewayContext gatewayContext) {
2548
this.gatewayContext = gatewayContext;
2649

27-
try {
28-
gatewayContext.getSchemaUpdater().updatePersistentRecords(NodeREDAPITokens.META);
29-
} catch (SQLException e) {
30-
logger.error("Error verifying schemas.", e);
31-
}
50+
gatewayContext.getWebResourceManager().getNavigationModel().getConnections().addCategory(PREFIX, cat -> cat
51+
.label(MODULE_NAME)
52+
.addPage("Tokens", page -> page
53+
.position(1)
54+
.mount("/nodered/tokens", "Tokens", jsModule)
55+
)
56+
);
57+
58+
gatewayContext.getConfigurationManager().getResourceTypeMetaRegistry().register(TOKEN_RESOURCE_TYPE_META);
3259

3360
BundleUtil.get().addBundle("NodeRED", GatewayHook.class, "NodeRED");
3461
}
@@ -47,13 +74,18 @@ public void shutdown() {
4774
}
4875

4976
@Override
50-
public List<? extends IConfigTab> getConfigPanels() {
51-
return Lists.newArrayList(NodeREDAPITokenManagerPage.MENU_ENTRY);
77+
public List<IdbMigrationStrategy> getRecordMigrationStrategies() {
78+
return List.of(new NamedRecordMigrationStrategy(NodeREDAPITokens.META, TOKEN_RESOURCE_TYPE));
79+
}
80+
81+
@Override
82+
public Optional<String> getMountedResourceFolder() {
83+
return Optional.of("mounted");
5284
}
5385

5486
@Override
55-
public List<ConfigCategory> getConfigCategories() {
56-
return Lists.newArrayList(NodeREDAPITokenManagerPage.CONFIG_CATEGORY);
87+
public Optional<String> getMountPathAlias() {
88+
return Optional.of(PREFIX);
5789
}
5890

5991
@Override

IgnitionNodeRED-gateway/src/main/java/org/imdc/nodered/NodeREDAPITokenManagerPage.java

Lines changed: 0 additions & 69 deletions
This file was deleted.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package org.imdc.nodered;
2+
3+
import com.inductiveautomation.ignition.gateway.dataroutes.openapi.annotations.Description;
4+
import com.inductiveautomation.ignition.gateway.model.GatewayContext;
5+
import com.inductiveautomation.ignition.gateway.secrets.Plaintext;
6+
import com.inductiveautomation.ignition.gateway.secrets.Secret;
7+
import com.inductiveautomation.ignition.gateway.secrets.SecretConfig;
8+
9+
import java.nio.charset.StandardCharsets;
10+
11+
public record NodeREDAPITokenResource(
12+
@Description("16 character alphanumeric API token") String APIToken,
13+
@Description("The secret (password) paired with the API token") SecretConfig Secret,
14+
@Description("The name of the audit profile that tag write actions will log to") String AuditProfile,
15+
@Description("A comma separated list of security levels to impersonate. If specified, security levels take precedence over roles and zones.") String SecurityLevels,
16+
@Description("A comma separated list of roles to impersonate") String Roles,
17+
@Description("A comma separated list of zones to impersonate") String Zones) {
18+
19+
public String getSecret(GatewayContext context) throws Exception {
20+
SecretConfig secretConfig = this.Secret();
21+
if (secretConfig != null) {
22+
Secret<?> secret = com.inductiveautomation.ignition.gateway.secrets.Secret.create(context, secretConfig);
23+
Plaintext plaintext = secret.getPlaintext();
24+
String password;
25+
try {
26+
password = plaintext.getAsString(StandardCharsets.UTF_8);
27+
} finally {
28+
plaintext.clear();
29+
}
30+
return password;
31+
}
32+
33+
throw new Exception("Secret configuration is empty");
34+
}
35+
}

IgnitionNodeRED-gateway/src/main/java/org/imdc/nodered/NodeREDAPITokens.java

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.inductiveautomation.ignition.gateway.audit.AuditProfileRecord;
44
import com.inductiveautomation.ignition.gateway.localdb.persistence.*;
5-
import com.inductiveautomation.ignition.gateway.web.components.editors.PasswordEditorSource;
65
import org.apache.commons.lang3.StringUtils;
76
import simpleorm.dataset.SFieldFlags;
87
import simpleorm.dataset.SFieldMeta;
@@ -88,30 +87,6 @@ public void onValidate(SFieldMeta field, SRecordInstance instance) throws SExcep
8887

8988
public static final BooleanField Enabled = new BooleanField(META, "Enabled").setDefault(true);
9089

91-
public static final Category SettingsCategory = new Category("NodeRED.Settings", 125).include(Name, APIToken, Secret, AuditProfile, Enabled);
92-
93-
public static final Category ImpersonateCategory = new Category("NodeRED.Impersonate", 126).include(SecurityLevels, Roles, Zones);
94-
95-
static {
96-
Name.getFormMeta().setFieldNameKey("NodeRED.Name.Name");
97-
Name.getFormMeta().setFieldDescriptionKey("NodeRED.Name.Desc");
98-
APIToken.getFormMeta().setFieldNameKey("NodeRED.APIToken.Name");
99-
APIToken.getFormMeta().setFieldDescriptionKey("NodeRED.APIToken.Desc");
100-
Secret.getFormMeta().setFieldNameKey("NodeRED.Secret.Name");
101-
Secret.getFormMeta().setFieldDescriptionKey("NodeRED.Secret.Desc");
102-
Secret.getFormMeta().setEditorSource(PasswordEditorSource.getSharedInstance());
103-
AuditProfile.getFormMeta().setFieldNameKey("NodeRED.AuditProfile.Name");
104-
AuditProfile.getFormMeta().setFieldDescriptionKey("NodeRED.AuditProfile.Desc");
105-
SecurityLevels.getFormMeta().setFieldNameKey("NodeRED.SecurityLevels.Name");
106-
SecurityLevels.getFormMeta().setFieldDescriptionKey("NodeRED.SecurityLevels.Desc");
107-
Roles.getFormMeta().setFieldNameKey("NodeRED.Roles.Name");
108-
Roles.getFormMeta().setFieldDescriptionKey("NodeRED.Roles.Desc");
109-
Zones.getFormMeta().setFieldNameKey("NodeRED.Zones.Name");
110-
Zones.getFormMeta().setFieldDescriptionKey("NodeRED.Zones.Desc");
111-
Enabled.getFormMeta().setFieldNameKey("NodeRED.Enabled.Name");
112-
Enabled.getFormMeta().setFieldDescriptionKey("NodeRED.Enabled.Desc");
113-
}
114-
11590
@Override
11691
public RecordMeta<?> getMeta() {
11792
return META;

0 commit comments

Comments
 (0)