ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rle...@apache.org
Subject [19/50] [abbrv] ambari git commit: AMBARI-22073 UI:VersionTag is no more needed for config creation/update. (atkach)
Date Mon, 02 Oct 2017 20:39:30 GMT
AMBARI-22073 UI:VersionTag is no more needed for config creation/update. (atkach)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/add33d4f
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/add33d4f
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/add33d4f

Branch: refs/heads/branch-feature-AMBARI-20859
Commit: add33d4f1905b91b21db4b4af1b857374fbac5f8
Parents: 9b25914
Author: Andrii Tkach <atkach@apache.org>
Authored: Wed Sep 27 16:54:49 2017 +0300
Committer: Andrii Tkach <atkach@apache.org>
Committed: Thu Sep 28 13:49:27 2017 +0300

----------------------------------------------------------------------
 .../journalNode/progress_controller.js          |  4 +--
 .../highAvailability/progress_controller.js     |  4 +--
 .../main/admin/kerberos/step2_controller.js     |  7 +++--
 ambari-web/app/controllers/main/host/details.js |  2 --
 .../main/service/reassign/step4_controller.js   |  2 --
 .../app/controllers/wizard/step8_controller.js  | 15 ++---------
 .../app/mixins/common/configs/configs_saver.js  | 26 +++---------------
 .../main/service/configs/config_overridable.js  |  1 -
 ambari-web/app/utils/ajax/ajax.js               |  2 --
 .../journalNode/progress_controller_test.js     |  2 --
 .../progress_controller_test.js                 |  3 ---
 .../admin/kerberos/step2_controller_test.js     |  9 +++----
 .../mixins/common/configs/configs_saver_test.js | 28 ++++----------------
 13 files changed, 18 insertions(+), 87 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/add33d4f/ambari-web/app/controllers/main/admin/highAvailability/journalNode/progress_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/journalNode/progress_controller.js
b/ambari-web/app/controllers/main/admin/highAvailability/journalNode/progress_controller.js
index 2959d67..d13e848 100644
--- a/ambari-web/app/controllers/main/admin/highAvailability/journalNode/progress_controller.js
+++ b/ambari-web/app/controllers/main/admin/highAvailability/journalNode/progress_controller.js
@@ -26,19 +26,17 @@ App.ManageJournalNodeProgressPageController = App.ManageJournalNodeWizardControl
   
   /**
    * Prepare object to send to the server to save configs
-   * Split all configs by site names and tag and note
+   * Split all configs by site names and note
    * @param siteNames Array
    * @param data Object
    * @param note String
    */
   reconfigureSites: function(siteNames, data, note) {
-    var tagName = 'version' + App.dateTime();
 
     return siteNames.map(function(_siteName) {
       var config = data.items.findProperty('type', _siteName);
       var configToSave = {
         type: _siteName,
-        tag: tagName,
         properties: config && config.properties,
         service_config_version_note: note || ''
       };

http://git-wip-us.apache.org/repos/asf/ambari/blob/add33d4f/ambari-web/app/controllers/main/admin/highAvailability/progress_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/progress_controller.js
b/ambari-web/app/controllers/main/admin/highAvailability/progress_controller.js
index 9039b9d..b2d19dd 100644
--- a/ambari-web/app/controllers/main/admin/highAvailability/progress_controller.js
+++ b/ambari-web/app/controllers/main/admin/highAvailability/progress_controller.js
@@ -67,18 +67,16 @@ App.HighAvailabilityProgressPageController = App.HighAvailabilityWizardControlle
 
   /**
    * Prepare object to send to the server to save configs
-   * Split all configs by site names and tag and note
+   * Split all configs by site names and note
    * @param siteNames Array
    * @param data Object
    * @param note String
    */
   reconfigureSites: function(siteNames, data, note) {
-    var tagName = App.get('testMode') ? 'version1' : 'version' + (new Date).getTime();
     return siteNames.map(function(_siteName) {
       var config = data.items.findProperty('type', _siteName);
       var configToSave = {
         type: _siteName,
-        tag: tagName,
         properties: config && config.properties,
         service_config_version_note: note || ''
       };

http://git-wip-us.apache.org/repos/asf/ambari/blob/add33d4f/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js b/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
index 258a384..05b0b31 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
@@ -199,13 +199,12 @@ App.KerberosWizardStep2Controller = App.WizardStep7Controller.extend(App.KDCCred
   createConfigurations: function () {
     var service = App.StackService.find().findProperty('serviceName', 'KERBEROS'),
         serviceConfigTags = [],
-        tag = 'version' + (new Date).getTime(),
         allConfigData = [],
         serviceConfigData = [];
 
     Object.keys(service.get('configTypes')).forEach(function (type) {
       if (!serviceConfigTags.someProperty('type', type)) {
-        var obj = this.createKerberosSiteObj(type, tag);
+        var obj = this.createKerberosSiteObj(type);
         obj.service_config_version_note = Em.I18n.t('admin.kerberos.wizard.configuration.note');
         serviceConfigTags.pushObject(obj);
       }
@@ -233,7 +232,7 @@ App.KerberosWizardStep2Controller = App.WizardStep7Controller.extend(App.KDCCred
     });
   },
 
-  createKerberosSiteObj: function (site, tag) {
+  createKerberosSiteObj: function (site) {
     var properties = {};
     var content = this.get('stepConfigs')[0].get('configs');
     var configs = content.filterProperty('filename', site + '.xml');
@@ -253,7 +252,7 @@ App.KerberosWizardStep2Controller = App.WizardStep7Controller.extend(App.KDCCred
     this.tweakKdcTypeValue(properties);
     this.tweakManualKdcProperties(properties);
     this.tweakIpaKdcProperties(properties);
-    return {"type": site, "tag": tag, "properties": properties};
+    return {"type": site, "properties": properties};
   },
 
   tweakKdcTypeValue: function (properties) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/add33d4f/ambari-web/app/controllers/main/host/details.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/host/details.js b/ambari-web/app/controllers/main/host/details.js
index 299a0d8..e3b5471 100644
--- a/ambari-web/app/controllers/main/host/details.js
+++ b/ambari-web/app/controllers/main/host/details.js
@@ -1338,14 +1338,12 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow
     if (groups.length) {
       groups.forEach(function (group) {
         var desiredConfigs = [],
-          tag = 'version' + (new Date).getTime(),
           properties = group.properties;
 
         for (var site in properties) {
           if (!properties.hasOwnProperty(site) || Em.isNone(properties[site])) continue;
           desiredConfigs.push({
             "type": site,
-            "tag": tag,
             "properties": properties[site],
             "properties_attributes": group.properties_attributes[site],
             "service_config_version_note": Em.I18n.t('hosts.host.configs.save.note').format(App.format.role(componentName,
false))

http://git-wip-us.apache.org/repos/asf/ambari/blob/add33d4f/ambari-web/app/controllers/main/service/reassign/step4_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/reassign/step4_controller.js b/ambari-web/app/controllers/main/service/reassign/step4_controller.js
index c610b13..108b3e9 100644
--- a/ambari-web/app/controllers/main/service/reassign/step4_controller.js
+++ b/ambari-web/app/controllers/main/service/reassign/step4_controller.js
@@ -315,11 +315,9 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
    */
   getServiceConfigData: function (configs, attributes) {
     var componentName = this.get('content.reassign.component_name');
-    var tagName = 'version' + (new Date).getTime();
     var configData = Object.keys(configs).map(function (_siteName) {
       return {
         type: _siteName,
-        tag: tagName,
         properties: configs[_siteName],
         properties_attributes: attributes[_siteName] || {},
         service_config_version_note: Em.I18n.t('services.reassign.step4.save.configuration.note').format(App.format.role(componentName,
false))

http://git-wip-us.apache.org/repos/asf/ambari/blob/add33d4f/ambari-web/app/controllers/wizard/step8_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step8_controller.js b/ambari-web/app/controllers/wizard/step8_controller.js
index 39981f7..94139e0 100644
--- a/ambari-web/app/controllers/wizard/step8_controller.js
+++ b/ambari-web/app/controllers/wizard/step8_controller.js
@@ -1459,11 +1459,9 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs,
App.wiz
    * @method createConfigurations
    */
   createConfigurations: function () {
-    var tag = this.getServiceConfigVersion();
-
     if (this.get('isInstaller')) {
       /** add cluster-env **/
-      this.get('serviceConfigTags').pushObject(this.createDesiredConfig('cluster-env', tag,
this.get('configs').filterProperty('filename', 'cluster-env.xml')));
+      this.get('serviceConfigTags').pushObject(this.createDesiredConfig('cluster-env', this.get('configs').filterProperty('filename',
'cluster-env.xml')));
     }
 
     this.get('selectedServices').forEach(function (service) {
@@ -1471,7 +1469,7 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs,
App.wiz
         if (!this.get('serviceConfigTags').someProperty('type', type)) {
           var configs = this.get('configs').filterProperty('filename', App.config.getOriginalFileName(type));
           var serviceConfigNote = this.getServiceConfigNote(type, service.get('displayName'));
-          this.get('serviceConfigTags').pushObject(this.createDesiredConfig(type, tag, configs,
serviceConfigNote));
+          this.get('serviceConfigTags').pushObject(this.createDesiredConfig(type, configs,
serviceConfigNote));
         }
       }, this);
     }, this);
@@ -1479,15 +1477,6 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs,
App.wiz
   },
 
   /**
-   * Get config version tag
-   *
-   * @returns {string}
-   */
-  getServiceConfigVersion: function() {
-    return 'version' + (this.get('isAddService') ? (new Date).getTime() : '1');
-  },
-
-  /**
    * Get config version message
    *
    * @param type

http://git-wip-us.apache.org/repos/asf/ambari/blob/add33d4f/ambari-web/app/mixins/common/configs/configs_saver.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/configs/configs_saver.js b/ambari-web/app/mixins/common/configs/configs_saver.js
index 6b69ca1..33a90a3 100644
--- a/ambari-web/app/mixins/common/configs/configs_saver.js
+++ b/ambari-web/app/mixins/common/configs/configs_saver.js
@@ -405,12 +405,11 @@ App.ConfigsSaverMixin = Em.Mixin.create({
       serviceConfigNote = serviceConfigNote || "";
 
       fileNamesToSave.forEach(function(fName) {
-        var tagVersion = this.getUniqueTag();
 
         if (this.allowSaveSite(fName)) {
           var properties = configsToSave.filterProperty('filename', fName);
           var type = App.config.getConfigTagFromFileName(fName);
-          desired_config.push(this.createDesiredConfig(type, tagVersion, properties, serviceConfigNote,
ignoreVersionNote));
+          desired_config.push(this.createDesiredConfig(type, properties, serviceConfigNote,
ignoreVersionNote));
         }
       }, this);
     }
@@ -418,23 +417,6 @@ App.ConfigsSaverMixin = Em.Mixin.create({
   },
 
   /**
-   * generate unique tag
-   * @returns {string}
-   */
-  getUniqueTag: function() {
-    var timestamp = (new Date).getTime();
-    var tagVersion = "version" + timestamp;
-
-    while(this.get('_timeStamps')[tagVersion]) {
-      timestamp++;
-      tagVersion = "version" + timestamp;
-    }
-    /** @see <code>_timeStamps<code> **/
-    this.get('_timeStamps')[tagVersion] = true;
-    return tagVersion;
-  },
-
-  /**
    * For some file names we have a restriction
    * and can't save them, in this case method will return false
    *
@@ -467,17 +449,15 @@ App.ConfigsSaverMixin = Em.Mixin.create({
   /**
    * generating common JSON object for desired config
    * @param {string} type - file name without '.xml'
-   * @param {string} tagVersion - version + timestamp
    * @param {App.ConfigProperty[]} properties - array of properties from model
    * @param {string} [serviceConfigNote='']
    * @param {boolean} [ignoreVersionNote=false]
    * @returns {{type: string, tag: string, properties: {}, properties_attributes: {}|undefined,
service_config_version_note: string|undefined}}
    */
-  createDesiredConfig: function(type, tagVersion, properties, serviceConfigNote, ignoreVersionNote)
{
-    Em.assert('type and tagVersion should be defined', type && tagVersion);
+  createDesiredConfig: function(type, properties, serviceConfigNote, ignoreVersionNote) {
+    Em.assert('type should be defined', type);
     var desired_config = {
       "type": type,
-      "tag": tagVersion,
       "properties": {}
     };
     if (!ignoreVersionNote) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/add33d4f/ambari-web/app/mixins/main/service/configs/config_overridable.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/main/service/configs/config_overridable.js b/ambari-web/app/mixins/main/service/configs/config_overridable.js
index e7d223d..0e8b7ee 100644
--- a/ambari-web/app/mixins/main/service/configs/config_overridable.js
+++ b/ambari-web/app/mixins/main/service/configs/config_overridable.js
@@ -246,7 +246,6 @@ App.ConfigOverridable = Em.Mixin.create({
           var type = Em.get(cst, 'site') || Em.get(cst, 'type');
           return {
             type: type,
-            tag: 'version' + (new Date).getTime(),
             properties: typeToPropertiesMap[type]
           };
         }),

http://git-wip-us.apache.org/repos/asf/ambari/blob/add33d4f/ambari-web/app/utils/ajax/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js
index 941f5a1..c32d8d4 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -791,7 +791,6 @@ var urls = {
           Clusters: {
             desired_config: {
               "type": data.siteName,
-              "tag": 'version' + (new Date).getTime(),
               "properties": data.properties,
               "service_config_version_note": data.service_config_version_note
 
@@ -1456,7 +1455,6 @@ var urls = {
           Clusters: {
             desired_config: {
               "type": data.siteName,
-              "tag": 'version' + (new Date).getTime(),
               "properties": data.properties
             }
           }

http://git-wip-us.apache.org/repos/asf/ambari/blob/add33d4f/ambari-web/test/controllers/main/admin/highAvailability/journalNode/progress_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/highAvailability/journalNode/progress_controller_test.js
b/ambari-web/test/controllers/main/admin/highAvailability/journalNode/progress_controller_test.js
index 868f832..327a881 100644
--- a/ambari-web/test/controllers/main/admin/highAvailability/journalNode/progress_controller_test.js
+++ b/ambari-web/test/controllers/main/admin/highAvailability/journalNode/progress_controller_test.js
@@ -52,13 +52,11 @@ describe('App.ManageJournalNodeProgressPageController', function () {
           "properties": {},
           "properties_attributes": {},
           "service_config_version_note": "note",
-          "tag": "version1",
           "type": "site1"
         },
         {
           "properties": undefined,
           "service_config_version_note": "note",
-          "tag": "version1",
           "type": "site2"
         }
       ]);

http://git-wip-us.apache.org/repos/asf/ambari/blob/add33d4f/ambari-web/test/controllers/main/admin/highAvailability/progress_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/highAvailability/progress_controller_test.js
b/ambari-web/test/controllers/main/admin/highAvailability/progress_controller_test.js
index 0f1b18d..ccadd6b 100644
--- a/ambari-web/test/controllers/main/admin/highAvailability/progress_controller_test.js
+++ b/ambari-web/test/controllers/main/admin/highAvailability/progress_controller_test.js
@@ -64,7 +64,6 @@ describe('App.HighAvailabilityProgressPageController', function () {
         result: [
           {
             type: "site1",
-            tag: "version1",
             properties: {
               site1_property1: "site1_property1_value",
               site1_property2: "site1_property2_value"
@@ -78,7 +77,6 @@ describe('App.HighAvailabilityProgressPageController', function () {
           },
           {
             type: "site2",
-            tag: "version1",
             properties: {
               site2_property1: "site2_property1_value",
               site2_property2: "site2_property2_value"
@@ -109,7 +107,6 @@ describe('App.HighAvailabilityProgressPageController', function () {
         result: [
           {
             type: "site1",
-            tag: "version1",
             properties: {
               site1_property1: "site1_property1_value",
               site1_property2: "site1_property2_value"

http://git-wip-us.apache.org/repos/asf/ambari/blob/add33d4f/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js b/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
index 78e43f0..794fe4a 100644
--- a/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
+++ b/ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
@@ -632,9 +632,8 @@ describe('App.KerberosWizardStep2Controller', function() {
           filename: 'site.xml'
         }]
       })]);
-      expect(controller.createKerberosSiteObj('site', 'tag')).to.be.eql({
+      expect(controller.createKerberosSiteObj('site')).to.be.eql({
         "type": 'site',
-        "tag": 'tag',
         "properties": {}
       });
     });
@@ -647,9 +646,8 @@ describe('App.KerberosWizardStep2Controller', function() {
           filename: 'site.xml'
         }]
       })]);
-      expect(controller.createKerberosSiteObj('site', 'tag')).to.be.eql({
+      expect(controller.createKerberosSiteObj('site')).to.be.eql({
         "type": 'site',
-        "tag": 'tag',
         "properties": {
           'kdc_hosts': {
             displayType: 'host',
@@ -667,9 +665,8 @@ describe('App.KerberosWizardStep2Controller', function() {
           filename: 'site.xml'
         }]
       })]);
-      expect(controller.createKerberosSiteObj('site', 'tag')).to.be.eql({
+      expect(controller.createKerberosSiteObj('site')).to.be.eql({
         "type": 'site',
-        "tag": 'tag',
         "properties": {
           'n1': {
             name: 'n1',

http://git-wip-us.apache.org/repos/asf/ambari/blob/add33d4f/ambari-web/test/mixins/common/configs/configs_saver_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mixins/common/configs/configs_saver_test.js b/ambari-web/test/mixins/common/configs/configs_saver_test.js
index 855823c..f20a49f 100644
--- a/ambari-web/test/mixins/common/configs/configs_saver_test.js
+++ b/ambari-web/test/mixins/common/configs/configs_saver_test.js
@@ -136,18 +136,16 @@ describe('App.ConfigsSaverMixin', function() {
     });
 
     it('generates config without properties', function() {
-      expect(mixin.createDesiredConfig('type1', 'version1')).to.eql({
+      expect(mixin.createDesiredConfig('type1')).to.eql({
         "type": 'type1',
-        "tag": 'version1',
         "properties": {},
         "service_config_version_note": ""
       })
     });
 
     it('generates config with properties', function() {
-      expect(mixin.createDesiredConfig('type1', 'version1', [Em.Object.create({name: 'p1',
value: 'v1', isRequiredByAgent: true}), Em.Object.create({name: 'p2', value: 'v2', isRequiredByAgent:
true})], "note")).to.eql({
+      expect(mixin.createDesiredConfig('type1', [Em.Object.create({name: 'p1', value: 'v1',
isRequiredByAgent: true}), Em.Object.create({name: 'p2', value: 'v2', isRequiredByAgent: true})],
"note")).to.eql({
         "type": 'type1',
-        "tag": 'version1',
         "properties": {
           "p1": 'v1',
           "p2": 'v2'
@@ -157,9 +155,8 @@ describe('App.ConfigsSaverMixin', function() {
     });
 
     it('generates config with properties and skip isRequiredByAgent', function() {
-      expect(mixin.createDesiredConfig('type1', 'version1', [Em.Object.create({name: 'p1',
value: 'v1', isRequiredByAgent: true}), Em.Object.create({name: 'p2', value: 'v2', isRequiredByAgent:
false})], "note")).to.eql({
+      expect(mixin.createDesiredConfig('type1', [Em.Object.create({name: 'p1', value: 'v1',
isRequiredByAgent: true}), Em.Object.create({name: 'p2', value: 'v2', isRequiredByAgent: false})],
"note")).to.eql({
         "type": 'type1',
-        "tag": 'version1',
         "properties": {
           p1: 'v1'
         },
@@ -168,9 +165,8 @@ describe('App.ConfigsSaverMixin', function() {
     });
 
     it('generates config with properties and skip service_config_version_note', function()
{
-      expect(mixin.createDesiredConfig('type1', 'version1', [Em.Object.create({name: 'p1',
value: 'v1', isRequiredByAgent: true})], "note", true)).to.eql({
+      expect(mixin.createDesiredConfig('type1', [Em.Object.create({name: 'p1', value: 'v1',
isRequiredByAgent: true})], "note", true)).to.eql({
         "type": 'type1',
-        "tag": 'version1',
         "properties": {
           p1: 'v1'
         }
@@ -178,7 +174,7 @@ describe('App.ConfigsSaverMixin', function() {
     });
 
     it('generates config with final, password, user, group, text, additional_user_property,
not_managed_hdfs_path, value_from_property_file', function() {
-      expect(mixin.createDesiredConfig('type1', 'version1', [
+      expect(mixin.createDesiredConfig('type1', [
           Em.Object.create({name: 'p1', value: 'v1', isFinal: true, isRequiredByAgent: true}),
           Em.Object.create({name: 'p2', value: 'v2', isRequiredByAgent: true}),
           Em.Object.create({name: 'p3', value: 'v3', isRequiredByAgent: true, propertyType:
["PASSWORD", "USER", "GROUP"]}),
@@ -188,7 +184,6 @@ describe('App.ConfigsSaverMixin', function() {
           Em.Object.create({name: 'p7', value: 'v7', isRequiredByAgent: true, propertyType:
["PASSWORD"]})
         ], "note")).to.eql({
         "type": 'type1',
-        "tag": 'version1',
         "properties": {
           p1: 'v1',
           p2: 'v2',
@@ -259,19 +254,6 @@ describe('App.ConfigsSaverMixin', function() {
     })
   });
 
-  describe('#getUniqueTag', function() {
-
-    it('should generate unique tags', function() {
-      var tags = [];
-      for (var i = 0; i < 3; i++) {
-        tags.push(mixin.getUniqueTag());
-      }
-      expect(tags[1]).to.not.be.equal(tags[0]);
-      expect(tags[2]).to.not.be.equal(tags[1]);
-      expect(tags[0]).to.not.be.equal(tags[2]);
-    });
-  });
-
   describe('#getModifiedConfigs', function () {
     var configs = [
       Em.Object.create({


Mime
View raw message