github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/ui/app/serializers/volume.js (about) 1 import { set, get } from '@ember/object'; 2 import ApplicationSerializer from './application'; 3 4 export default class VolumeSerializer extends ApplicationSerializer { 5 attrs = { 6 externalId: 'ExternalID', 7 }; 8 9 embeddedRelationships = ['writeAllocations', 'readAllocations']; 10 11 // Volumes treat Allocations as embedded records. Ember has an 12 // EmbeddedRecords mixin, but it assumes an application is using 13 // the REST serializer and Nomad does not. 14 normalize(typeHash, hash) { 15 hash.NamespaceID = hash.Namespace; 16 17 hash.PlainId = hash.ID; 18 19 // TODO These shouldn't hardcode `csi/` as part of the IDs, 20 // but it is necessary to make the correct find requests and the 21 // payload does not contain the required information to derive 22 // this identifier. 23 hash.ID = JSON.stringify([`csi/${hash.ID}`, hash.NamespaceID || 'default']); 24 hash.PluginID = `csi/${hash.PluginID}`; 25 26 // Populate read/write allocation lists from aggregate allocation list 27 const readAllocs = hash.ReadAllocs || {}; 28 const writeAllocs = hash.WriteAllocs || {}; 29 30 hash.ReadAllocations = []; 31 hash.WriteAllocations = []; 32 33 if (hash.Allocations) { 34 hash.Allocations.forEach(function(alloc) { 35 const id = alloc.ID; 36 if (id in readAllocs) { 37 hash.ReadAllocations.push(alloc); 38 } 39 if (id in writeAllocs) { 40 hash.WriteAllocations.push(alloc); 41 } 42 }); 43 delete hash.Allocations; 44 } 45 46 const normalizedHash = super.normalize(typeHash, hash); 47 return this.extractEmbeddedRecords(this, this.store, typeHash, normalizedHash); 48 } 49 50 keyForRelationship(attr, relationshipType) { 51 //Embedded relationship attributes don't end in IDs 52 if (this.embeddedRelationships.includes(attr)) return attr.capitalize(); 53 return super.keyForRelationship(attr, relationshipType); 54 } 55 56 // Convert the embedded relationship arrays into JSONAPI included records 57 extractEmbeddedRecords(serializer, store, typeHash, partial) { 58 partial.included = partial.included || []; 59 60 this.embeddedRelationships.forEach(embed => { 61 const relationshipMeta = typeHash.relationshipsByName.get(embed); 62 const relationship = get(partial, `data.relationships.${embed}.data`); 63 64 if (!relationship) return; 65 66 // Create a sidecar relationships array 67 const hasMany = new Array(relationship.length); 68 69 // For each embedded allocation, normalize the allocation JSON according 70 // to the allocation serializer. 71 relationship.forEach((alloc, idx) => { 72 const { data, included } = this.normalizeEmbeddedRelationship( 73 store, 74 relationshipMeta, 75 alloc 76 ); 77 78 // In JSONAPI, embedded records go in the included array. 79 partial.included.push(data); 80 if (included) { 81 partial.included.push(...included); 82 } 83 84 // In JSONAPI, the main payload value is an array of IDs that 85 // map onto the objects in the included array. 86 hasMany[idx] = { id: data.id, type: data.type }; 87 }); 88 89 // Set the JSONAPI relationship value to the sidecar. 90 const relationshipJson = { data: hasMany }; 91 set(partial, `data.relationships.${embed}`, relationshipJson); 92 }); 93 94 return partial; 95 } 96 97 normalizeEmbeddedRelationship(store, relationshipMeta, relationshipHash) { 98 const modelName = relationshipMeta.type; 99 const modelClass = store.modelFor(modelName); 100 const serializer = store.serializerFor(modelName); 101 102 return serializer.normalize(modelClass, relationshipHash, null); 103 } 104 }