github.com/hernad/nomad@v1.6.112/ui/app/serializers/volume.js (about)

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