Skip to content

Commit d760a67

Browse files
committed
WIP 1233: document adding buildings/rooms/racks; customize-freshservice
1 parent b618578 commit d760a67

1 file changed

Lines changed: 265 additions & 0 deletions

File tree

docs/integration/external-integrations/freshservice-integration/customize-freshservice.mdx

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,3 +774,268 @@ If you want Device42 to update `asset_state` values, set `skip-update` to `"fals
774774
</field>
775775
```
776776
</details>
777+
778+
### Example 4: How To Sync Buildings, Rooms, and Racks From Device42 to Freshservice
779+
780+
By default, the `mapping.xml` file does not sync building, room, or rack data from Device42 to Freshservice. The following steps are based on version 6.0 of the default `mapping.xml` file and cover how to:
781+
782+
1. Create `Building`, `Room`, and `Rack` as custom asset types in Freshservice
783+
2. Sync buildings
784+
3. Sync rooms
785+
4. Sync racks
786+
5. Sync relationships between rooms and buildings
787+
6. Sync relationships between racks and rooms
788+
7. Delete buildings that no longer exist in Device42
789+
8. Delete rooms that no longer exist in Device42
790+
9. Delete racks that no longer exist in Device42
791+
10. Delete relationships between rooms and buildings that no longer exist in Device42
792+
11. Delete relationships between racks and rooms that no longer exist in Device42
793+
794+
**Step 1:** Create `Building`, `Room`, and `Rack` as custom asset types in Freshservice.
795+
796+
<!-- TODO: Add steps for creating asset types in Freshservice -->
797+
798+
**Step 2:** Add the following `<task>` element to your `mapping.xml` file before the `Delete assets from Freshservice that do not exist in Device42` cleanup task to sync buildings.
799+
800+
The DOQL query fetches data from `view_building_v1`. The [`<mapping>` element](#the-task-element-elements) maps the returned fields to the `Building` asset type in Freshservice, grouping them under the **General** and **Building** sections.
801+
802+
<details>
803+
<summary>Click to expand the Building task</summary>
804+
805+
```xml
806+
<task enable="true" name="D42 Building to Freshservice Building" type="asset" description="Copy Building from Device42 to Freshservice">
807+
<api>
808+
<target/>
809+
<resource doql="
810+
select
811+
b.name,
812+
format('Building-%s', b.building_pk) as device42_id,
813+
'Building' as asset_type,
814+
b.address,
815+
b.contact_name,
816+
b.contact_phone,
817+
b.notes,
818+
b.tags,
819+
b.latitude,
820+
b.longitude
821+
from view_building_v1 b
822+
"/>
823+
</api>
824+
<matching>
825+
<source-1 device42-id="device42_id" name="name"/>
826+
</matching>
827+
<mapping key="name" doql-suffix=" where b.last_changed >'%s'">
828+
<field resource="device42_id" source-type="string" target="device42_id" target-type="string" target-header="General"/>
829+
<field resource="name" source-type="string" target="name" target-type="string" target-header="General" min-length="1" max-length="248" escape="true"/>
830+
<field resource="address" source-type="string" target="address" target-type="string" target-header="Building" min-length="1" max-length="60000"/>
831+
<field resource="contact_name" source-type="string" target="contact_name" target-type="string" target-header="Building" min-length="1" max-length="255"/>
832+
<field resource="contact_phone" source-type="string" target="contact_phone" target-type="string" target-header="Building" min-length="1" max-length="255"/>
833+
<field resource="notes" source-type="string" target="description" target-header="General" min-length="1" max-length="60000"/>
834+
<field resource="tags" source-type="string" target="tags" target-type="string" target-header="Building" min-length="1" max-length="255"/>
835+
<field resource="latitude" source-type="float" target="latitude" target-type="float" target-header="Building"/>
836+
<field resource="longitude" source-type="float" target="longitude" target-type="float" target-header="Building"/>
837+
</mapping>
838+
</task>
839+
```
840+
841+
</details>
842+
843+
**Step 3:** Add the following `<task>` element after the Building task to sync rooms.
844+
845+
The DOQL query fetches data from `view_room_v1`. The `<mapping>` element maps the returned fields to the `Room` asset type in Freshservice, grouping them under the **General** and **Room** sections.
846+
847+
<details>
848+
<summary>Click to expand the Room task</summary>
849+
850+
```xml
851+
<task enable="true" name="D42 Room to Freshservice Room" type="asset" description="Copy Room from Device42 to Freshservice">
852+
<api>
853+
<target/>
854+
<resource doql="
855+
select
856+
r.name,
857+
format('Room-%s', r.room_pk) as device42_id,
858+
'Room' as asset_type,
859+
r.notes,
860+
r.raised_floor,
861+
r.tags
862+
from view_room_v1 r
863+
"/>
864+
</api>
865+
<matching>
866+
<source-1 device42-id="device42_id" name="name"/>
867+
</matching>
868+
<mapping key="name" doql-suffix=" where r.last_changed >'%s'">
869+
<field resource="device42_id" source-type="string" target="device42_id" target-type="string" target-header="General"/>
870+
<field resource="name" source-type="string" target="name" target-type="string" target-header="General" min-length="1" max-length="248" escape="true"/>
871+
<field resource="notes" source-type="string" target="description" target-header="General" min-length="1" max-length="60000"/>
872+
<field resource="raised_floor" source-type="boolean" target="raised_floor" target-type="boolean" target-header="Room"/>
873+
<field resource="tags" source-type="string" target="tags" target-type="string" target-header="Room" min-length="1" max-length="255"/>
874+
</mapping>
875+
</task>
876+
```
877+
878+
</details>
879+
880+
**Step 4:** Add the following `<task>` element after the Room task to sync racks.
881+
882+
The DOQL query fetches data from `view_rack_v1`. The `<mapping>` element maps the returned fields to the `Rack` asset type in Freshservice, grouping them under the **General** and **Rack** sections.
883+
884+
<details>
885+
<summary>Click to expand the Rack task</summary>
886+
887+
```xml
888+
<task enable="true" name="D42 Rack to Freshservice Rack" type="asset" description="Copy Rack from Device42 to Freshservice">
889+
<api>
890+
<target/>
891+
<resource doql="
892+
select
893+
r.name,
894+
format('Rack-%s', r.rack_pk) as device42_id,
895+
'Rack' as asset_type,
896+
r.notes,
897+
r.asset_no,
898+
r.tags,
899+
ven.name maker_name
900+
from view_rack_v1 r LEFT JOIN view_vendor_v1 ven ON r.vendor_fk=ven.vendor_pk
901+
"/>
902+
</api>
903+
<matching>
904+
<source-1 device42-id="device42_id" name="name"/>
905+
</matching>
906+
<mapping key="name" doql-suffix=" where r.last_changed >'%s'">
907+
<field resource="device42_id" source-type="string" target="device42_id" target-type="string" target-header="General"/>
908+
<field resource="name" source-type="string" target="name" target-type="string" target-header="General" min-length="1" max-length="248" escape="true"/>
909+
<field resource="asset_no" source-type="string" target="asset_no" target-type="string" target-header="Rack" min-length="1" max-length="255"/>
910+
<field resource="tags" source-type="string" target="tags" target-type="string" target-header="Rack" min-length="1" max-length="255"/>
911+
<field resource="maker_name" source-type="string" target="maker_name" target-type="string" target-header="Rack" min-length="1" max-length="255"/>
912+
<field resource="notes" source-type="string" target="description" target-header="General" min-length="1" max-length="60000"/>
913+
</mapping>
914+
</task>
915+
```
916+
917+
</details>
918+
919+
:::note
920+
Before syncing relationships, confirm that the **Located In** and **Houses** relationship types are available in your Freshservice instance. <!-- TODO: SME to verify whether these relationship types exist by default in Freshservice or need to be created manually -->
921+
:::
922+
923+
**Step 5:** Add the following `<task>` element after the three asset tasks above to sync relationships between rooms and buildings. The DOQL query joins `view_room_v1` and `view_building_v1`. The `<mapping>` element uses `downstream-relationship` and `upstream-relationship` attributes to define the **Located In / Houses** relationship type between each room and its parent building.
924+
925+
<details>
926+
<summary>Click to expand the Room to Building relationship task</summary>
927+
928+
```xml
929+
<task enable="true" name="Room to Building" type="asset_relationship" description="Create Relationship from Room to Building">
930+
<api>
931+
<target/>
932+
<resource doql="
933+
select
934+
r.name as room_name,
935+
format('Room-%s', r.room_pk) as room_device42_id,
936+
b.name as building_name,
937+
format('Building-%s', b.building_pk) as building_device42_id
938+
from view_room_v1 r
939+
inner join view_building_v1 b on r.building_fk = b.building_pk
940+
"/>
941+
</api>
942+
<matching>
943+
<source-1 device42-id="room_device42_id"/>
944+
<source-2 device42-id="building_device42_id"/>
945+
</matching>
946+
<mapping key="room_name" downstream-relationship="Located In" upstream-relationship="Houses" target-key="building_name"></mapping>
947+
</task>
948+
```
949+
950+
</details>
951+
952+
**Step 6:** Add the following `<task>` element after the Room to Building task to sync relationships between racks and rooms. The DOQL query joins `view_rack_v1` and `view_room_v1`, and the `<mapping>` element follows the same pattern as Step 5 — `downstream-relationship="Located In"` on the rack side and `upstream-relationship="Houses"` on the room side.
953+
954+
<details>
955+
<summary>Click to expand the Rack to Room relationship task</summary>
956+
957+
```xml
958+
<task enable="true" name="Rack to Room" type="asset_relationship" description="Create Relationship from Rack to Room">
959+
<api>
960+
<target/>
961+
<resource doql="
962+
select
963+
rk.name as rack_name,
964+
format('Rack-%s', rk.rack_pk) as rack_device42_id,
965+
rm.name as room_name,
966+
format('Room-%s', rm.room_pk) as room_device42_id
967+
from view_rack_v1 rk
968+
inner join view_room_v1 rm on rk.room_fk = rm.room_pk
969+
"/>
970+
</api>
971+
<matching>
972+
<source-1 device42-id="rack_device42_id"/>
973+
<source-2 device42-id="room_device42_id"/>
974+
</matching>
975+
<mapping key="rack_name" downstream-relationship="Located In" upstream-relationship="Houses" target-key="room_name"></mapping>
976+
</task>
977+
```
978+
979+
</details>
980+
981+
**Steps 7–9:** To delete buildings, rooms, and racks that no longer exist in Device42, locate the `Delete assets from Freshservice that do not exist in Device42` cleanup task near the bottom of your `mapping.xml` file (see [The `mapping.xml` File Tasks](#the-mappingxml-file-tasks) for an overview of how cleanup tasks work). Add the following `UNION` clauses to the end of its DOQL query, before the closing `"`. Each clause selects the Device42 IDs of all existing buildings, rooms, and racks so Freshservice can identify and remove any that have been deleted.
982+
983+
<details>
984+
<summary>Click to expand the code block</summary>
985+
986+
```sql
987+
union
988+
989+
select
990+
format('Building-%s', b.building_pk) as device42_id
991+
from view_building_v1 b
992+
993+
union
994+
995+
select
996+
format('Room-%s', r.room_pk) as device42_id
997+
from view_room_v1 r
998+
999+
union
1000+
1001+
select
1002+
format('Rack-%s', r.rack_pk) as device42_id
1003+
from view_rack_v1 r
1004+
```
1005+
1006+
</details>
1007+
1008+
**Steps 10–11:** To delete relationships between rooms and buildings, and between racks and rooms, that no longer exist in Device42, update both `Delete asset relationships from Freshservice that do not exist in Device42` tasks. The `mapping.xml` file contains two versions of this task for [version compatibility](#the-task-element-attributes) — one with `d42_min_version="19.05.00"` and one with `d42_max_version="19.04.99"`. Add the following `UNION` clauses to the end of each task's DOQL query, before the closing `"`. Each clause selects the current room-to-building and rack-to-room relationships in Device42 so Freshservice can identify and remove any that no longer exist.
1009+
1010+
<details>
1011+
<summary>Click to expand the code block</summary>
1012+
1013+
```sql
1014+
union
1015+
1016+
select
1017+
r.name as dependent_device_name,
1018+
format('Room-%s', r.room_pk) as dependent_device_device42_id,
1019+
'Located In' as downstream_relationship,
1020+
b.name as dependency_device_name,
1021+
format('Building-%s', b.building_pk) as dependency_device_device42_id,
1022+
'Houses' as upstream_relationship
1023+
from view_room_v1 r
1024+
inner join view_building_v1 b on r.building_fk = b.building_pk
1025+
1026+
union
1027+
1028+
select
1029+
rk.name as dependent_device_name,
1030+
format('Rack-%s', rk.rack_pk) as dependent_device_device42_id,
1031+
'Located In' as downstream_relationship,
1032+
rm.name as dependency_device_name,
1033+
format('Room-%s', rm.room_pk) as dependency_device_device42_id,
1034+
'Houses' as upstream_relationship
1035+
from view_rack_v1 rk
1036+
inner join view_room_v1 rm on rk.room_fk = rm.room_pk
1037+
```
1038+
1039+
</details>
1040+
1041+
Save the file and [reupload it to Freshservice](#reupload-the-mappingxml-file) using the **Upload Custom Mapping** button, then run a [full sync](index.mdx#run-the-data-synchronization) to populate the new building, room, and rack assets in Freshservice.

0 commit comments

Comments
 (0)