github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/ui/app/serializers/volume.js (about)

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