diff --git a/.gencode_hash.txt b/.gencode_hash.txt
index fe83115014..a50292c601 100644
--- a/.gencode_hash.txt
+++ b/.gencode_hash.txt
@@ -7,15 +7,15 @@ a65e8177ca59cd51c4a8ff63ecaa194897f7e22b82afb14708d63efbd7b96a84 gencode/docs/c
11b21f73b6a4065102968a4c09979639b8a7ea6efb20e40d52cd21b2a60167bb gencode/docs/configuration_pod.html
b34c136cee32cb88f32a427ff400c3898ed49168f6dcaca1bc9ba65365bc5ae4 gencode/docs/configuration_pubber.html
1057fa40fb7a31a23bb2773d21c38cf4590a935bd8b5ea4218e695c6204f5dd9 gencode/docs/data_template.html
-ea06d489d98f96f8ac0134388fb4172b1fca6d924aba895c6e3119c19b0c7dc0 gencode/docs/events.html
+ffd9325c940b8e832a608a595c8ccc8903b935e899f42219ddc3c79ec65f6202 gencode/docs/events.html
70e57ad6ef39330d958727ebf9dcd61ef6ea30e4c8653eac412bf1867fdb3a70 gencode/docs/events_alarmset.html
-feb4138c5acee9b3626e9c2e541711cec304c0e67c2999e6d713ee2e7144ef53 gencode/docs/events_discovery.html
+e0268db0f292834ad051fba0315cdf0b2c9850fbb4266414041d7d8e10aa312d gencode/docs/events_discovery.html
808ad1cad37e9f4bf08ea3631162a663998ce60fe8935cbd0ca5e548c3b6df2a gencode/docs/events_mapping.html
eafcc3c48189f605f114cde051fea9d13fc5f1a3e395d64fb0a91cb53d4c9aeb gencode/docs/events_pointset.html
cac253f57c5c92ef32e2a5f91b6cec8229e8db1dcffcc96a58f06da068e741e7 gencode/docs/events_system.html
151c1b62db35e84e51d5ff2a7464f61ced4d7fb0c7eb795715c245ee0a1b3436 gencode/docs/events_udmi.html
73dbe799e7943ec20ac58b544998e986a39539d4ef0cb4f5023e92e7634d3124 gencode/docs/events_validation.html
-0af72961d68e952c511f3edff1fb9d7c94ba1aadfa31fbe89128f8dae7f9703c gencode/docs/metadata.html
+cebf265b0c3d3a6e9c9e8c4e6c723ac36bc088dfabbc789e775388c3d2ec83d0 gencode/docs/metadata.html
c86682715d348bd3dd971fa5bd925a8a3d0f3c2944c65a47c4b64fe1a5ccdea2 gencode/docs/monitoring.html
474ca16edc9f3cad2bb3ab40b6993cbced90263f762f66ee6cd246a6c4a0d18f gencode/docs/persistent_device.html
e11595fd11477947a27461f8ef4fb6facb5f60e2abd6212193f7581ab123ff84 gencode/docs/properties.html
@@ -51,7 +51,7 @@ fa94295bc0c97518634c7232e7e55e1c923d7eb42bfa3004651ed183e1ccbb40 gencode/java/u
519ead2ee2fe3e6fe48547266dec9a545521d52d262646f261ebfbbf8500d25f gencode/java/udmi/schema/BuildingTranslation.java
27ca4f61bd43beca0871b465f3906785a1030a4526605f1fa9b10e3adda8df05 gencode/java/udmi/schema/CapabilityValidationState.java
224c6be2cb6d90a47d181fa30ba1418cf6cc5385ec1c010fe112728382a70216 gencode/java/udmi/schema/Category.java
-0101d742dbaa23fb2152b044e5eabd6d219047cddbb973e9626a026946b7ddfc gencode/java/udmi/schema/CloudModel.java
+ed9a4802c21fffdedb27040f74714b2cf467d0e32cd9e3d8d864a4f1836612b5 gencode/java/udmi/schema/CloudModel.java
051b4a7c85a2f1a310787f88f336be2fc9b87c99a94ac2f970955d2fe1daa931 gencode/java/udmi/schema/CloudQuery.java
3e6572b16184bde7557eb67334405e7c5b58446e64802658cf0d5ef3b0018909 gencode/java/udmi/schema/Common.java
153a14dd6f6bb536affe704d114541002adcc4a9768398f8c9f79634559b66a2 gencode/java/udmi/schema/Config.java
@@ -157,7 +157,7 @@ a671f5341703d03200c3a4b4df41f109e587e3723292321998595da60b03e4a2 gencode/java/u
8cc9c88554fc6c9d7d6eba6884279eab3160b4e72d8edfef8155e69ec61c1eec gencode/java/udmi/schema/ValidationState.java
eadc72e31b4796273479967303513b16563af0f946d1e1c7eba1748f9b133d40 gencode/java/udmi/schema/ValidationSummary.java
11f8dab5296d41e86cd623a4ed27b972ae673b141907cb913397d4eb53880c59 gencode/java/udmi/schema/Water.java
-f6e74a51f453f1d198500ed77bd28b668c2317ba84ba93229db928cde55e0877 gencode/presentation/presentation.json
+0d863349462e546bbfad54e75032170d9967f4ed95aa6bd900f36398fba012a4 gencode/presentation/presentation.json
4cf98cbd132cde0cc8813ac35cf3712cb46014154c817c04ad2902c268cdd8fe gencode/python/pyproject.toml
a98b84029d33a421872a08f7bfb1bd2f23f8dc3bebc8d7a1c2a7f1c8596510bf gencode/python/udmi/schema/__init__.py
f9d90861e568b27445bef241f04cce64cc44731c95c8bd9e3f65cef79d42dab0 gencode/python/udmi/schema/_base.py
@@ -218,7 +218,7 @@ a3ea178f98a4993da708e2ec41f5ede74aa92d742ffbe201a77adef803d4143a gencode/python
9577d11c5110af169aafd0e083d115c849ce17dfdc2b6b23b7186c69c1c333db gencode/python/udmi/schema/metadata.py
cd81df64d7db21ab06f84cdbd07a808a641612c7c1124f9f2d928a898c3c767e gencode/python/udmi/schema/model_alarmset.py
b80b7f580fd7527da0c2caff063218488cf5bbd091daa64a6a5f9a5d45b135c2 gencode/python/udmi/schema/model_alarmset_alarm.py
-bb3e28f8ae3b43ddd3b99fbc96a2a3cfd7103e0742fb9427c2191b3674ccea90 gencode/python/udmi/schema/model_cloud.py
+6d19eb94063acbc8e5432b9827e8b20f4f8cd02efa6ae760fabe60652c69542d gencode/python/udmi/schema/model_cloud.py
670ea1a72ade3d9af0df00c694cbd755f3a2748022c99b90f3b86a017b7424a9 gencode/python/udmi/schema/model_cloud_config.py
798ee0ee5094d1c3e4681626832d16428df26e752e0e0425d61178f6e231efa6 gencode/python/udmi/schema/model_discovery.py
f33f0b5a048fc50d03811f81256b920d954307ad80f2dcc57fb2d882317447b0 gencode/python/udmi/schema/model_discovery_family.py
diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml
index 71203ea386..732395de23 100644
--- a/.github/workflows/testing.yml
+++ b/.github/workflows/testing.yml
@@ -248,8 +248,8 @@ jobs:
run: |
bin/start_local sites/udmi_site_model //mqtt/localhost
bin/pull_messages //mqtt/localhost > out/message_capture.log 2>&1 &
- - name: bin/test_etcd
- run: bin/test_etcd
+ - name: bin/test_etcd_prerun
+ run: bin/test_etcd_prerun
- name: bin/test_mosquitto
run: bin/test_mosquitto
- name: bin/test_regclean
@@ -260,6 +260,8 @@ jobs:
run: bin/test_sequencer local full //mqtt/localhost $(< etc/local_tests.txt)
- name: bin/test_udmis
run: bin/test_udmis
+ - name: bin/test_etcd_postrun
+ run: bin/test_etcd_postrun
- name: mosquitto debug
if: ${{ !cancelled() }}
run: |
diff --git a/bin/test_etcd_postrun b/bin/test_etcd_postrun
new file mode 100755
index 0000000000..40d3d37267
--- /dev/null
+++ b/bin/test_etcd_postrun
@@ -0,0 +1,24 @@
+#!/bin/bash -e
+set -x
+
+ROOT=$(dirname $0)/..
+cd $ROOT
+
+source etc/shell_common.sh
+
+# Print everything for debug
+udmis/bin/etcdctl get --prefix ""
+more sites/udmi_site_model/devices/AHU-1/* | cat
+
+echo "Verifying key in etcd..."
+GOT_KEY=$(udmis/bin/etcdctl get /r/ZZ-TRI-FECTA/d/AHU-1:auth_key --print-value-only)
+WANT_KEY=$(cat sites/udmi_site_model/devices/AHU-1/rsa_public.pem)
+
+
+if [[ "$WANT_KEY" == "$GOT_KEY" ]]; then
+ echo "SUCCESS: Public key correctly found in etcd at /r/TEST_REG/d/DEV-1:auth_key"
+else
+ echo "FAILURE: Public key NOT found or incorrect in etcd.\n\n GOT: '$GOT_KEY' \nWANT '$WANT_KEY'"
+ exit 1
+fi
+
diff --git a/bin/test_etcd b/bin/test_etcd_prerun
similarity index 100%
rename from bin/test_etcd
rename to bin/test_etcd_prerun
diff --git a/gencode/docs/events.html b/gencode/docs/events.html
index 337a590403..c70fd2beb3 100644
--- a/gencode/docs/events.html
+++ b/gencode/docs/events.html
@@ -7835,6 +7835,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
Type: string
+
+
+
+
+
+
+
@@ -9786,6 +9840,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
Type: string
+
+
+
+
+
+
+
@@ -21957,6 +22065,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
Type: string
+
+
+
+
+
+
+
diff --git a/gencode/docs/events_discovery.html b/gencode/docs/events_discovery.html
index 212c2cc3fe..ae6d12e5e7 100644
--- a/gencode/docs/events_discovery.html
+++ b/gencode/docs/events_discovery.html
@@ -3646,6 +3646,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
Type: string
+
+
+
+
+
+
+
@@ -5373,6 +5420,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
Type: string
+
+
+
+
+
+
+
@@ -16263,6 +16357,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
Type: string
+
+
+
+
+
+
+
diff --git a/gencode/docs/metadata.html b/gencode/docs/metadata.html
index 40c3713763..6acb6da076 100644
--- a/gencode/docs/metadata.html
+++ b/gencode/docs/metadata.html
@@ -1292,6 +1292,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
Type: string
+
+
+
+
+
+
+
@@ -24250,6 +24290,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
Type: string
+
+
+
+
+
+
+
@@ -26425,6 +26526,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
Type: string
+
+
+
+
+
+
+
@@ -39877,6 +40039,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
Type: string
+
+
+
+
+
+
+
diff --git a/gencode/java/udmi/schema/CloudModel.java b/gencode/java/udmi/schema/CloudModel.java
index 819f4ad03d..f838e21176 100644
--- a/gencode/java/udmi/schema/CloudModel.java
+++ b/gencode/java/udmi/schema/CloudModel.java
@@ -31,6 +31,7 @@
"config",
"blocked",
"detail",
+ "password",
"credentials",
"updated_time",
"last_event_time",
@@ -110,6 +111,8 @@ public class CloudModel {
public Boolean blocked;
@JsonProperty("detail")
public java.lang.String detail;
+ @JsonProperty("password")
+ public java.lang.String password;
@JsonProperty("credentials")
public List
credentials;
@JsonProperty("updated_time")
@@ -166,6 +169,7 @@ public int hashCode() {
result = ((result* 31)+((this.resource_type == null)? 0 :this.resource_type.hashCode()));
result = ((result* 31)+((this.num_id == null)? 0 :this.num_id.hashCode()));
result = ((result* 31)+((this.version == null)? 0 :this.version.hashCode()));
+ result = ((result* 31)+((this.password == null)? 0 :this.password.hashCode()));
result = ((result* 31)+((this.blocked == null)? 0 :this.blocked.hashCode()));
result = ((result* 31)+((this.last_error_time == null)? 0 :this.last_error_time.hashCode()));
result = ((result* 31)+((this.metadata_str == null)? 0 :this.metadata_str.hashCode()));
@@ -188,7 +192,7 @@ public boolean equals(Object other) {
return false;
}
CloudModel rhs = ((CloudModel) other);
- return (((((((((((((((((((((((this.updated_time == rhs.updated_time)||((this.updated_time!= null)&&this.updated_time.equals(rhs.updated_time)))&&((this.auth_type == rhs.auth_type)||((this.auth_type!= null)&&this.auth_type.equals(rhs.auth_type))))&&((this.device_key == rhs.device_key)||((this.device_key!= null)&&this.device_key.equals(rhs.device_key))))&&((this.metadata == rhs.metadata)||((this.metadata!= null)&&this.metadata.equals(rhs.metadata))))&&((this.last_event_time == rhs.last_event_time)||((this.last_event_time!= null)&&this.last_event_time.equals(rhs.last_event_time))))&&((this.last_config_time == rhs.last_config_time)||((this.last_config_time!= null)&&this.last_config_time.equals(rhs.last_config_time))))&&((this.credentials == rhs.credentials)||((this.credentials!= null)&&this.credentials.equals(rhs.credentials))))&&((this.last_state_time == rhs.last_state_time)||((this.last_state_time!= null)&&this.last_state_time.equals(rhs.last_state_time))))&&((this.functions_ver == rhs.functions_ver)||((this.functions_ver!= null)&&this.functions_ver.equals(rhs.functions_ver))))&&((this.resource_type == rhs.resource_type)||((this.resource_type!= null)&&this.resource_type.equals(rhs.resource_type))))&&((this.num_id == rhs.num_id)||((this.num_id!= null)&&this.num_id.equals(rhs.num_id))))&&((this.version == rhs.version)||((this.version!= null)&&this.version.equals(rhs.version))))&&((this.blocked == rhs.blocked)||((this.blocked!= null)&&this.blocked.equals(rhs.blocked))))&&((this.last_error_time == rhs.last_error_time)||((this.last_error_time!= null)&&this.last_error_time.equals(rhs.last_error_time))))&&((this.metadata_str == rhs.metadata_str)||((this.metadata_str!= null)&&this.metadata_str.equals(rhs.metadata_str))))&&((this.detail == rhs.detail)||((this.detail!= null)&&this.detail.equals(rhs.detail))))&&((this.device_ids == rhs.device_ids)||((this.device_ids!= null)&&this.device_ids.equals(rhs.device_ids))))&&((this.config == rhs.config)||((this.config!= null)&&this.config.equals(rhs.config))))&&((this.last_config_ack == rhs.last_config_ack)||((this.last_config_ack!= null)&&this.last_config_ack.equals(rhs.last_config_ack))))&&((this.operation == rhs.operation)||((this.operation!= null)&&this.operation.equals(rhs.operation))))&&((this.gateway == rhs.gateway)||((this.gateway!= null)&&this.gateway.equals(rhs.gateway))))&&((this.timestamp == rhs.timestamp)||((this.timestamp!= null)&&this.timestamp.equals(rhs.timestamp))));
+ return ((((((((((((((((((((((((this.updated_time == rhs.updated_time)||((this.updated_time!= null)&&this.updated_time.equals(rhs.updated_time)))&&((this.auth_type == rhs.auth_type)||((this.auth_type!= null)&&this.auth_type.equals(rhs.auth_type))))&&((this.device_key == rhs.device_key)||((this.device_key!= null)&&this.device_key.equals(rhs.device_key))))&&((this.metadata == rhs.metadata)||((this.metadata!= null)&&this.metadata.equals(rhs.metadata))))&&((this.last_event_time == rhs.last_event_time)||((this.last_event_time!= null)&&this.last_event_time.equals(rhs.last_event_time))))&&((this.last_config_time == rhs.last_config_time)||((this.last_config_time!= null)&&this.last_config_time.equals(rhs.last_config_time))))&&((this.credentials == rhs.credentials)||((this.credentials!= null)&&this.credentials.equals(rhs.credentials))))&&((this.last_state_time == rhs.last_state_time)||((this.last_state_time!= null)&&this.last_state_time.equals(rhs.last_state_time))))&&((this.functions_ver == rhs.functions_ver)||((this.functions_ver!= null)&&this.functions_ver.equals(rhs.functions_ver))))&&((this.resource_type == rhs.resource_type)||((this.resource_type!= null)&&this.resource_type.equals(rhs.resource_type))))&&((this.num_id == rhs.num_id)||((this.num_id!= null)&&this.num_id.equals(rhs.num_id))))&&((this.version == rhs.version)||((this.version!= null)&&this.version.equals(rhs.version))))&&((this.password == rhs.password)||((this.password!= null)&&this.password.equals(rhs.password))))&&((this.blocked == rhs.blocked)||((this.blocked!= null)&&this.blocked.equals(rhs.blocked))))&&((this.last_error_time == rhs.last_error_time)||((this.last_error_time!= null)&&this.last_error_time.equals(rhs.last_error_time))))&&((this.metadata_str == rhs.metadata_str)||((this.metadata_str!= null)&&this.metadata_str.equals(rhs.metadata_str))))&&((this.detail == rhs.detail)||((this.detail!= null)&&this.detail.equals(rhs.detail))))&&((this.device_ids == rhs.device_ids)||((this.device_ids!= null)&&this.device_ids.equals(rhs.device_ids))))&&((this.config == rhs.config)||((this.config!= null)&&this.config.equals(rhs.config))))&&((this.last_config_ack == rhs.last_config_ack)||((this.last_config_ack!= null)&&this.last_config_ack.equals(rhs.last_config_ack))))&&((this.operation == rhs.operation)||((this.operation!= null)&&this.operation.equals(rhs.operation))))&&((this.gateway == rhs.gateway)||((this.gateway!= null)&&this.gateway.equals(rhs.gateway))))&&((this.timestamp == rhs.timestamp)||((this.timestamp!= null)&&this.timestamp.equals(rhs.timestamp))));
}
diff --git a/gencode/presentation/presentation.json b/gencode/presentation/presentation.json
index eaf51d5a2d..3fbe159045 100644
--- a/gencode/presentation/presentation.json
+++ b/gencode/presentation/presentation.json
@@ -768,6 +768,12 @@
"section": "cloud",
"type": "string"
},
+ "cloud.password": {
+ "display": "show",
+ "style": "bold",
+ "section": "cloud",
+ "type": "string"
+ },
"cloud.updated_time": {
"display": "show",
"style": "bold",
diff --git a/gencode/python/udmi/schema/model_cloud.py b/gencode/python/udmi/schema/model_cloud.py
index abf4c6ef48..b215254de3 100644
--- a/gencode/python/udmi/schema/model_cloud.py
+++ b/gencode/python/udmi/schema/model_cloud.py
@@ -70,6 +70,7 @@ class CloudModel(DataModel):
config: Optional[ConfigCloudModel] = None
blocked: Optional[bool] = None
detail: Optional[str] = None
+ password: Optional[str] = None
credentials: Optional[List[Credential]] = None
updated_time: Optional[str] = None
last_event_time: Optional[str] = None
diff --git a/misc/bambi/presentation.gld.json b/misc/bambi/presentation.gld.json
index eaf51d5a2d..3fbe159045 100644
--- a/misc/bambi/presentation.gld.json
+++ b/misc/bambi/presentation.gld.json
@@ -768,6 +768,12 @@
"section": "cloud",
"type": "string"
},
+ "cloud.password": {
+ "display": "show",
+ "style": "bold",
+ "section": "cloud",
+ "type": "string"
+ },
"cloud.updated_time": {
"display": "show",
"style": "bold",
diff --git a/schema/model_cloud.json b/schema/model_cloud.json
index 5ea71eb010..6e929cb5b8 100644
--- a/schema/model_cloud.json
+++ b/schema/model_cloud.json
@@ -82,6 +82,13 @@
"style": "bold"
}
},
+ "password": {
+ "type": "string",
+ "$presentation": {
+ "display": "show",
+ "style": "bold"
+ }
+ },
"credentials": {
"type": "array",
"items": {
diff --git a/udmis/src/main/java/com/google/bos/udmi/service/access/ImplicitIotAccessProvider.java b/udmis/src/main/java/com/google/bos/udmi/service/access/ImplicitIotAccessProvider.java
index d43ef01f3d..f0dbbb5f0a 100644
--- a/udmis/src/main/java/com/google/bos/udmi/service/access/ImplicitIotAccessProvider.java
+++ b/udmis/src/main/java/com/google/bos/udmi/service/access/ImplicitIotAccessProvider.java
@@ -80,6 +80,8 @@ public class ImplicitIotAccessProvider extends IotAccessBase {
private static final String CLIENT_ID_FORMAT = "/r/%s/d/%s";
private static final String CLIENT_PREFIX = "/r";
private static final String AUTH_PASSWORD_PROPERTY = "auth_pass";
+ private static final String AUTH_KEY_PROPERTY = "auth_key";
+ private static final String AUTH_TYPE_PROPERTY = "auth_type";
private static final String LAST_CONFIG_ACKED = "last_config_ack";
private static final String CONFIG_SUFFIX = "/config";
private static final String METADATA_STR_KEY = "metadata_str";
@@ -208,15 +210,23 @@ private Map toDeviceMap(CloudModel cloudModel, String createdAt)
ofNullable(cloudModel.resource_type).orElse(DIRECT).toString());
requireNull(cloudModel.metadata_str, "unexpected metadata_str content");
properties.put(METADATA_STR_KEY, stringifyTerse(cloudModel.metadata));
+ ifNotNullThen(ifNotNullGet(cloudModel.metadata, metadata -> metadata.get("key_bytes")),
+ keyBytes -> properties.put(AUTH_KEY_PROPERTY, keyBytes));
properties.put(BLOCKED_PROPERTY, booleanString(cloudModel.blocked));
ifNotNullThen(cloudModel.num_id, id -> properties.put(NUM_ID_PROPERTY, id));
+ ifNotNullThen(cloudModel.auth_type,
+ authType -> properties.put(AUTH_TYPE_PROPERTY, authType.value()));
ifNotNullThen(cloudModel.credentials, creds -> ifNotTrueThen(creds.isEmpty(), () -> {
checkState(creds.size() == 1, "only one credential supported");
Credential cred = creds.get(0);
- checkState(cred.key_format == Key_format.PASSWORD,
- "key type not supported: " + cred.key_format);
- properties.put(AUTH_PASSWORD_PROPERTY, cred.key_data);
+ checkState(cred.key_format != Key_format.PASSWORD,
+ "key type PASSWORD should be in the password field, not credentials");
+ properties.put(AUTH_KEY_PROPERTY, cred.key_data);
+ properties.put(AUTH_TYPE_PROPERTY, cred.key_format.value());
}));
+ ifNotNullThen(cloudModel.password, password -> {
+ properties.put(AUTH_PASSWORD_PROPERTY, password);
+ });
return properties;
}
@@ -265,6 +275,23 @@ public CloudModel fetchDevice(String registryId, String deviceId) {
cloudModel.metadata = ifNotNullGet(cloudModel.metadata_str, JsonUtil::toStringMapStr);
cloudModel.metadata_str = null;
+ String authType = properties.get(AUTH_TYPE_PROPERTY);
+ if (authType != null) {
+ cloudModel.auth_type = CloudModel.Auth_type.fromValue(authType);
+ }
+
+ String authKey = properties.get(AUTH_KEY_PROPERTY);
+ if (authKey != null) {
+ Credential credential = new Credential();
+ credential.key_data = authKey;
+ if (cloudModel.auth_type != null) {
+ credential.key_format = Key_format.fromValue(cloudModel.auth_type.value());
+ }
+ cloudModel.credentials = List.of(credential);
+ }
+
+ cloudModel.password = properties.get(AUTH_PASSWORD_PROPERTY);
+
cloudModel.gateway = new GatewayModel();
cloudModel.gateway.proxy_ids =
listBoundDevices(registryId, deviceId).keySet().stream().toList();
diff --git a/validator/src/main/java/com/google/daq/mqtt/util/CloudDeviceSettings.java b/validator/src/main/java/com/google/daq/mqtt/util/CloudDeviceSettings.java
index 07c286c7bb..bf4bb79f8a 100644
--- a/validator/src/main/java/com/google/daq/mqtt/util/CloudDeviceSettings.java
+++ b/validator/src/main/java/com/google/daq/mqtt/util/CloudDeviceSettings.java
@@ -9,6 +9,7 @@
public class CloudDeviceSettings {
public List credentials;
+ public String password;
public String metadata;
public String deviceNumId;
public List proxyDevices;
diff --git a/validator/src/main/java/com/google/daq/mqtt/util/CloudIotManager.java b/validator/src/main/java/com/google/daq/mqtt/util/CloudIotManager.java
index cb12773081..3d80733e81 100644
--- a/validator/src/main/java/com/google/daq/mqtt/util/CloudIotManager.java
+++ b/validator/src/main/java/com/google/daq/mqtt/util/CloudIotManager.java
@@ -229,17 +229,16 @@ public boolean registerDevice(String deviceId, CloudDeviceSettings settings) {
}
private void coerceCredentialsToPassword(String deviceId, CloudDeviceSettings settings) {
- // TODO: Make this less ugly/hacky. Ick.
- settings.credentials.forEach(credential -> {
+ if (settings.credentials != null && !settings.credentials.isEmpty()) {
+ Credential credential = settings.credentials.get(0);
try {
String prefix = getCredentialPrefix(credential.key_format);
- credential.key_format = Key_format.PASSWORD;
File privateKey = new File(siteModel, format(PRIVATE_KEY_BYTES_FMT, deviceId, prefix));
- credential.key_data = makePassword(readAllBytes(privateKey.toPath()));
+ settings.password = makePassword(readAllBytes(privateKey.toPath()));
} catch (Exception e) {
- throw new RuntimeException("While coercing credential for " + deviceId, e);
+ throw new RuntimeException("While generating password for " + deviceId, e);
}
- });
+ }
}
private String getCredentialPrefix(Key_format keyFormat) {
@@ -290,6 +289,7 @@ private CloudModel makeDevice(CloudDeviceSettings settings, CloudModel oldDevice
CloudModel cloudModel = new CloudModel();
cloudModel.resource_type = gatewayIfTrue(settings.proxyDevices != null);
cloudModel.credentials = getCredentials(settings);
+ cloudModel.password = settings.password;
cloudModel.metadata = metadataMap;
cloudModel.num_id = settings.deviceNumId;
cloudModel.blocked = settings.blocked;