33import static com .google .common .base .Preconditions .checkNotNull ;
44import static com .google .common .base .Preconditions .checkState ;
55import static com .google .daq .mqtt .util .ConfigUtil .UDMI_VERSION ;
6+ import static com .google .udmi .util .Common .UNKNOWN_DEVICE_ID_PREFIX ;
7+ import static com .google .udmi .util .Common .generateColonKey ;
68import static com .google .udmi .util .Common .removeNextArg ;
79import static com .google .udmi .util .GeneralUtils .catchToNull ;
810import static com .google .udmi .util .JsonUtil .isoConvert ;
2123import com .google .daq .mqtt .util .CloudIotManager ;
2224import com .google .daq .mqtt .util .ConfigUtil ;
2325import com .google .udmi .util .Common ;
24- import com .google .udmi .util .JsonUtil ;
2526import com .google .udmi .util .SiteModel ;
2627import java .io .File ;
2728import java .util .ArrayList ;
3334import java .util .Map ;
3435import java .util .Map .Entry ;
3536import java .util .Set ;
37+ import java .util .concurrent .atomic .AtomicInteger ;
3638import udmi .schema .CloudModel ;
3739import udmi .schema .CloudModel .ModelOperation ;
3840import udmi .schema .DiscoveryConfig ;
4143import udmi .schema .Envelope .SubFolder ;
4244import udmi .schema .ExecutionConfiguration ;
4345import udmi .schema .FamilyDiscoveryConfig ;
46+ import udmi .schema .FamilyLocalnetModel ;
4447import udmi .schema .GatewayModel ;
48+ import udmi .schema .LocalnetModel ;
4549import udmi .schema .Metadata ;
4650import udmi .schema .SystemModel ;
4751
@@ -60,6 +64,8 @@ public class MappingAgent {
6064 private SiteModel siteModel ;
6165 private Date generationDate ;
6266
67+ private AtomicInteger suffixToStart = new AtomicInteger (1 );
68+
6369 /**
6470 * Create an agent given the configuration.
6571 */
@@ -98,7 +104,7 @@ void process(List<String> argsList) {
98104 switch (mappingCommand ) {
99105 case "provision" -> setupProvision ();
100106 case "discover" -> initiateDiscover ();
101- case "reconcile " -> reconcileDiscovery ();
107+ case "map " -> mapDiscoveredDevices ();
102108 default -> throw new RuntimeException ("Unknown mapping command " + mappingCommand );
103109 }
104110 System .err .printf ("Completed mapper %s command%n" , mappingCommand );
@@ -141,26 +147,83 @@ private FamilyDiscoveryConfig getFamilyDiscoveryConfig(String family) {
141147 return familyDiscoveryConfig ;
142148 }
143149
144- private void reconcileDiscovery () {
150+ private void mapDiscoveredDevices () {
151+ List <Entry <String , Metadata >> mappedDiscoveredEntries = getMappedDiscoveredEntries ();
152+ Map <String , Metadata > devicesEntriesMap = getDevicesEntries ();
153+ Map <String , String > devicesFamilyAddressMap = getDeviceFamilyAddressMap ();
154+
155+ Set <String > devicesPresent = new HashSet <>();
156+ mappedDiscoveredEntries .forEach (entry -> {
157+
158+ if (devicesEntriesMap .containsKey (entry .getKey ())) {
159+ System .err .println ("Skipping existing device file for family::address = " + entry .getKey ());
160+ devicesPresent .add (devicesFamilyAddressMap .get (entry .getKey ()));
161+ //TODO: update the existing device
162+ } else {
163+ String newDeviceId = getNextDeviceId ();
164+ while (devicesPresent .contains (newDeviceId )) {
165+ newDeviceId = getNextDeviceId ();
166+ }
167+ devicesPresent .add (newDeviceId );
168+ siteModel .createNewDevice (newDeviceId , entry .getValue ());
169+ }
170+ });
171+
172+ updateProxyIdsForDiscoveryNode (devicesPresent );
173+ }
174+
175+ private Map <String , String > getDeviceFamilyAddressMap () {
176+ Map <String , String > devicesFamilyAddressMap = new HashMap <>();
177+
178+ for (String device : siteModel .allMetadata ().keySet ()) {
179+ Metadata deviceMetadata = siteModel .allMetadata ().get (device );
180+ if (deviceMetadata .localnet == null || deviceMetadata .localnet .families == null ) {
181+ continue ;
182+ }
183+ Map <String , FamilyLocalnetModel > deviceFamilies = deviceMetadata .localnet .families ;
184+ for (String familyName : deviceFamilies .keySet ()) {
185+ devicesFamilyAddressMap .put (generateColonKey (familyName ,
186+ deviceFamilies .get (familyName ).addr ), device );
187+ }
188+ }
189+
190+ return devicesFamilyAddressMap ;
191+ }
192+
193+ private String getNextDeviceId () {
194+ return UNKNOWN_DEVICE_ID_PREFIX + suffixToStart .getAndIncrement ();
195+ }
196+
197+ private List <Entry <String , Metadata >> getMappedDiscoveredEntries () {
145198 File extrasDir = siteModel .getExtrasDir ();
146199 File [] extras = extrasDir .listFiles ();
147200 if (extras == null || extras .length == 0 ) {
148201 throw new RuntimeException ("No extras found to reconcile" );
149202 }
150- List <Entry <String , Metadata >> entries = Arrays .stream (extras ).map (this ::convertExtra )
203+ List <Entry <String , Metadata >> mappedDiscoveredEntries = Arrays .stream (extras )
204+ .map (this ::convertExtraDiscoveredEvents )
151205 .filter (entry -> !entry .getKey ().equals (NO_DISCOVERY )).toList ();
152- entries .forEach (entry -> {
153- File metadataFile = siteModel .getDeviceFile (entry .getKey (), METADATA_JSON );
154- if (metadataFile .exists ()) {
155- System .err .println ("Skipping existing device file " + metadataFile );
156- } else {
157- System .err .println ("Writing device metadata file " + metadataFile );
158- metadataFile .getParentFile ().mkdirs ();
159- JsonUtil .writeFile (entry .getValue (), metadataFile );
206+ return mappedDiscoveredEntries ;
207+ }
208+
209+ private Map <String , Metadata > getDevicesEntries () {
210+ Map <String , Metadata > devicesEntriesMap = new HashMap <>();
211+
212+ for (Metadata deviceMetadata : siteModel .allMetadata ().values ()) {
213+ if (deviceMetadata .localnet == null || deviceMetadata .localnet .families == null ) {
214+ continue ;
160215 }
161- });
216+ Map <String , FamilyLocalnetModel > deviceFamilies = deviceMetadata .localnet .families ;
217+ for (String familyName : deviceFamilies .keySet ()) {
218+ devicesEntriesMap .put (generateColonKey (familyName ,
219+ deviceFamilies .get (familyName ).addr ), deviceMetadata );
220+ }
221+ }
222+
223+ return devicesEntriesMap ;
224+ }
162225
163- List <String > proxyIds = entries . stream (). map ( Entry :: getKey ). toList ();
226+ private void updateProxyIdsForDiscoveryNode ( Set <String > proxyIds ) {
164227 File gatewayMetadata = siteModel .getDeviceFile (deviceId , METADATA_JSON );
165228 Metadata metadata = loadFileStrictRequired (Metadata .class , gatewayMetadata );
166229 List <String > idList = ofNullable (metadata .gateway .proxy_ids ).orElse (ImmutableList .of ());
@@ -173,20 +236,34 @@ private void reconcileDiscovery() {
173236 writeFile (metadata , gatewayMetadata );
174237 }
175238
176- private Entry <String , Metadata > convertExtra (File file ) {
239+ private Entry <String , Metadata > convertExtraDiscoveredEvents (File file ) {
177240 DiscoveryEvents discoveryEvents = loadFileStrict (DiscoveryEvents .class ,
178241 new File (file , "cloud_metadata/udmi_discovered_with.json" ));
179- if (discoveryEvents == null ) {
242+ boolean isInvalidDiscoveryEvent = false ;
243+ if (discoveryEvents .family == null || discoveryEvents .addr == null ) {
244+ System .err .println ("Invalid discovery event, family or address not present" );
245+ isInvalidDiscoveryEvent = true ;
246+ }
247+ if (discoveryEvents == null || isInvalidDiscoveryEvent ) {
180248 return Map .entry (NO_DISCOVERY , new Metadata ());
181249 }
182250 Metadata metadata = new Metadata ();
183251 metadata .version = UDMI_VERSION ;
184252 metadata .timestamp = new Date ();
185253 metadata .system = new SystemModel ();
186254 metadata .gateway = new GatewayModel ();
255+ populateMetadataLocalnet (discoveryEvents , metadata );
187256 metadata .gateway .gateway_id = deviceId ;
188- String deviceName = (String ) discoveryEvents .system .ancillary .get ("device-name" );
189- return Map .entry (deviceName , metadata );
257+ return Map .entry (generateColonKey (discoveryEvents .family ,
258+ discoveryEvents .addr ), metadata );
259+ }
260+
261+ private static void populateMetadataLocalnet (DiscoveryEvents discoveryEvents , Metadata metadata ) {
262+ metadata .localnet = new LocalnetModel ();
263+ metadata .localnet .families = new HashMap <>();
264+ FamilyLocalnetModel familyLocalnetModel = new FamilyLocalnetModel ();
265+ familyLocalnetModel .addr = discoveryEvents .addr ;
266+ metadata .localnet .families .put (discoveryEvents .family , familyLocalnetModel );
190267 }
191268
192269 private void initialize () {
0 commit comments