Repository: ambari Updated Branches: refs/heads/trunk 3dd83d6b1 -> 7bd0ad733
AMBARI-15821 Added ability to link optional short Urls to view instances. (Ashwin Rajeev via dipayanb) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/7bd0ad73 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/7bd0ad73 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/7bd0ad73 Branch: refs/heads/trunk Commit: 7bd0ad7338718c0f0554904d57c42c1637617c53 Parents: 3dd83d6 Author: Dipayan Bhowmick <[email protected]> Authored: Thu Apr 14 18:26:59 2016 +0530 Committer: Dipayan Bhowmick <[email protected]> Committed: Thu Apr 14 18:26:59 2016 +0530 ---------------------------------------------------------------------- .../controllers/ambariViews/ViewsEditCtrl.js | 9 +- .../ui/admin-web/app/scripts/i18n.config.js | 1 + .../ui/admin-web/app/scripts/services/View.js | 10 +- .../admin-web/app/views/ambariViews/create.html | 9 ++ .../admin-web/app/views/ambariViews/edit.html | 13 +- .../internal/ViewInstanceResourceProvider.java | 20 +++ .../server/orm/entities/ViewInstanceEntity.java | 24 ++++ .../server/upgrade/UpgradeCatalog240.java | 9 ++ .../ambari/server/view/ViewExtractor.java | 1 - .../apache/ambari/server/view/ViewRegistry.java | 31 ++++- .../view/configuration/InstanceConfig.java | 22 ++++ .../main/resources/Ambari-DDL-Derby-CREATE.sql | 1 + .../main/resources/Ambari-DDL-MySQL-CREATE.sql | 1 + .../main/resources/Ambari-DDL-Oracle-CREATE.sql | 1 + .../resources/Ambari-DDL-Postgres-CREATE.sql | 1 + .../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql | 3 +- .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql | 1 + .../resources/Ambari-DDL-SQLServer-CREATE.sql | 1 + .../ViewInstanceResourceProviderTest.java | 121 +++++++++++++------ .../server/upgrade/UpgradeCatalog240Test.java | 12 +- .../ambari/view/ViewInstanceDefinition.java | 6 + .../app/controllers/main/views_controller.js | 6 +- ambari-web/app/routes/installer.js | 2 +- ambari-web/app/routes/main.js | 4 +- ambari-web/app/routes/view.js | 95 +++++++++++++++ ambari-web/app/routes/views.js | 4 +- 26 files changed, 354 insertions(+), 54 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js index 0d2bdf7..d46a30f 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js @@ -37,7 +37,8 @@ angular.module('ambariAdminConsole') $scope.settings = { 'visible': $scope.instance.ViewInstanceInfo.visible, 'label': $scope.instance.ViewInstanceInfo.label, - 'description': $scope.instance.ViewInstanceInfo.description + 'description': $scope.instance.ViewInstanceInfo.description, + 'shortUrl': $scope.instance.ViewInstanceInfo.short_url }; switch (section) { case "details" : @@ -243,7 +244,8 @@ angular.module('ambariAdminConsole') 'ViewInstanceInfo':{ 'visible': $scope.settings.visible, 'label': $scope.settings.label, - 'description': $scope.settings.description + 'description': $scope.settings.description, + 'short_url': $scope.settings.shortUrl } }; return View.updateInstance($routeParams.viewId, $routeParams.version, $routeParams.instanceId, data) @@ -266,7 +268,8 @@ angular.module('ambariAdminConsole') $scope.settings = { 'visible': $scope.instance.ViewInstanceInfo.visible, 'label': $scope.instance.ViewInstanceInfo.label, - 'description': $scope.instance.ViewInstanceInfo.description + 'description': $scope.instance.ViewInstanceInfo.description, + 'shortUrl': $scope.instance.ViewInstanceInfo.short_url }; $scope.editDetailsSettingsDisabled = true; $scope.settingsForm.$setPristine(); http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js index 2a31b39..e95ebdb 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js @@ -185,6 +185,7 @@ angular.module('ambariAdminConsole') 'advanced': 'Advanced', 'visible': 'Visible', 'description': 'Description', + 'shortUrl':'Short URL', 'instanceDescription': 'Instance Description', 'clusterConfiguration': 'Cluster Configuration', 'localCluster': 'Local Ambari Managed Cluster', http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js index 7bf1672..cbe11e4 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js @@ -63,7 +63,7 @@ angular.module('ambariAdminConsole') if(version.ViewVersionInfo.status === 'DEPLOYED'){ // if atelast one version is deployed self.canCreateInstance = true; } - + angular.forEach(version.instances, function(instance) { instance.label = instance.ViewInstanceInfo.label || version.ViewVersionInfo.label || instance.ViewInstanceInfo.view_name; }); @@ -137,7 +137,7 @@ angular.module('ambariAdminConsole') return deferred.promise; }; - + View.getVersions = function(viewName) { var deferred = $q.defer(); @@ -168,7 +168,8 @@ angular.module('ambariAdminConsole') visible: instanceInfo.visible, icon_path: instanceInfo.icon_path, icon64_path: instanceInfo.icon64_path, - description: instanceInfo.description + description: instanceInfo.description, + short_url:instanceInfo.shortUrl }; angular.forEach(instanceInfo.properties, function(property) { @@ -189,7 +190,8 @@ angular.module('ambariAdminConsole') $http({ method: 'POST', - url: Settings.baseUrl + '/views/' + instanceInfo.view_name +'/versions/'+instanceInfo.version + '/instances/'+instanceInfo.instance_name, + url: Settings.baseUrl + '/views/' + instanceInfo.view_name + +'/versions/'+instanceInfo.version + '/instances/'+instanceInfo.instance_name, data:{ 'ViewInstanceInfo' : data } http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/create.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/create.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/create.html index b9bd609..20ccadb 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/create.html +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/create.html @@ -76,6 +76,15 @@ </div> </div> </div> + + <div class="form-group" ng-class="{'has-error' : form.instanceCreateForm.submitted }"> + <label for="" class="control-label col-sm-3">{{'views.shortUrl' | translate}}</label> + <div class="col-sm-9"> + <input type="text" class="form-control" name="short_url" ng-model="instance.shortUrl" maxlength="200"> + </div> + </div> + + <div class="form-group"> <div class="col-sm-10 col-sm-offset-3"> <div class="checkbox"> http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html index 85e4e44..b41abc8 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html @@ -77,6 +77,17 @@ </div> </div> </div> + + + <div class="form-group" ng-class="{'has-error' : form.instanceCreateForm.submitted }"> + <label for="" class="control-label col-sm-3">{{'views.shortUrl' | translate}}</label> + <div class="col-sm-9"> + <input type="text" class="form-control" name="short_url" ng-model="settings.shortUrl" maxlength="200"> + + </div> + </div> + + <div class="form-group"> <div class="col-sm-offset-3 col-sm-10"> <div class="checkbox"> @@ -198,7 +209,7 @@ <p> </p> <div class="checkbox"> <label> - <input type="radio" + <input type="radio" ng-model="$parent.isLocalCluster" ng-disabled="editConfigurationDisabled" ng-value="false" http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java index 750a347..abdda7f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java @@ -18,6 +18,7 @@ package org.apache.ambari.server.controller.internal; +import com.google.common.base.Strings; import com.google.inject.persist.Transactional; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.DuplicateResourceException; @@ -70,6 +71,7 @@ public class ViewInstanceResourceProvider extends AbstractAuthorizedResourceProv public static final String CONTEXT_PATH_PROPERTY_ID = "ViewInstanceInfo/context_path"; public static final String STATIC_PROPERTY_ID = "ViewInstanceInfo/static"; public static final String CLUSTER_HANDLE_PROPERTY_ID = "ViewInstanceInfo/cluster_handle"; + public static final String SHORT_URL_PROPERTY_ID = "ViewInstanceInfo/short_url"; // validation properties public static final String VALIDATION_RESULT_PROPERTY_ID = "ViewInstanceInfo/validation_result"; @@ -109,6 +111,7 @@ public class ViewInstanceResourceProvider extends AbstractAuthorizedResourceProv propertyIds.add(CONTEXT_PATH_PROPERTY_ID); propertyIds.add(STATIC_PROPERTY_ID); propertyIds.add(CLUSTER_HANDLE_PROPERTY_ID); + propertyIds.add(SHORT_URL_PROPERTY_ID); propertyIds.add(VALIDATION_RESULT_PROPERTY_ID); propertyIds.add(PROPERTY_VALIDATION_RESULTS_PROPERTY_ID); } @@ -239,6 +242,7 @@ public class ViewInstanceResourceProvider extends AbstractAuthorizedResourceProv setResourceProperty(resource, VISIBLE_PROPERTY_ID, viewInstanceEntity.isVisible(), requestedIds); setResourceProperty(resource, STATIC_PROPERTY_ID, viewInstanceEntity.isXmlDriven(), requestedIds); setResourceProperty(resource, CLUSTER_HANDLE_PROPERTY_ID, viewInstanceEntity.getClusterHandle(), requestedIds); + setResourceProperty(resource, SHORT_URL_PROPERTY_ID, viewInstanceEntity.getShortUrl(), requestedIds); // only allow an admin to access the view properties if (ViewRegistry.getInstance().checkAdmin()) { @@ -340,6 +344,11 @@ public class ViewInstanceResourceProvider extends AbstractAuthorizedResourceProv viewInstanceEntity.setClusterHandle((String) properties.get(CLUSTER_HANDLE_PROPERTY_ID)); } + if (properties.containsKey(SHORT_URL_PROPERTY_ID)) { + viewInstanceEntity.setShortUrl((String) properties.get(SHORT_URL_PROPERTY_ID)); + } + + Map<String, String> instanceProperties = new HashMap<String, String>(); boolean isUserAdmin = viewRegistry.checkAdmin(); @@ -393,6 +402,11 @@ public class ViewInstanceResourceProvider extends AbstractAuthorizedResourceProv throw new IllegalStateException("The view " + viewName + " is not loaded."); } + if(!Strings.isNullOrEmpty(instanceEntity.getShortUrl()) && viewRegistry.duplicatedShortUrl(instanceEntity)){ + throw new DuplicateResourceException("The short url " + instanceEntity.getShortUrl() + " already exists for "+ instanceEntity.getViewEntity().getCommonName() + + " and version "+instanceEntity.getViewEntity().getVersion()); + } + if (viewRegistry.instanceExists(instanceEntity)) { throw new DuplicateResourceException("The instance " + instanceEntity.getName() + " already exists."); } @@ -414,10 +428,16 @@ public class ViewInstanceResourceProvider extends AbstractAuthorizedResourceProv @Transactional @Override public Void invoke() throws AmbariException { + ViewRegistry viewRegistry = ViewRegistry.getInstance(); ViewInstanceEntity instance = toEntity(properties, true); ViewEntity view = instance.getViewEntity(); + if(!Strings.isNullOrEmpty(instance.getShortUrl()) && viewRegistry.duplicatedShortUrl(instance)){ + throw new DuplicateResourceException("The short url " + instance.getShortUrl() + " already exists for "+ instance.getViewEntity().getCommonName() + + " and version "+instance.getViewEntity().getVersion()); + } + if (includeInstance(view.getCommonName(), view.getVersion(), instance.getInstanceName(), false)) { try { ViewRegistry.getInstance().updateViewInstance(instance); http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java index 5044267..2555f93 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java @@ -130,6 +130,11 @@ public class ViewInstanceEntity implements ViewInstanceDefinition { @Basic private String icon; + + @Column(name = "short_url") + @Basic + private String shortUrl; + /** * The big icon path. */ @@ -234,6 +239,7 @@ public class ViewInstanceEntity implements ViewInstanceDefinition { this.clusterHandle = null; this.visible = instanceConfig.isVisible() ? 'Y' : 'N'; this.alterNames = 1; + this.shortUrl = instanceConfig.getShortUrl(); String label = instanceConfig.getLabel(); this.label = (label == null || label.length() == 0) ? view.getLabel() : label; @@ -272,6 +278,7 @@ public class ViewInstanceEntity implements ViewInstanceDefinition { this.visible = 'Y'; this.alterNames = 1; this.label = label; + this.shortUrl = null; } @@ -337,6 +344,14 @@ public class ViewInstanceEntity implements ViewInstanceDefinition { return clusterHandle; } + + @Override + public String getShortUrl() { + return shortUrl; + } + + + @Override public boolean isVisible() { return visible == 'y' || visible == 'Y'; @@ -372,6 +387,15 @@ public class ViewInstanceEntity implements ViewInstanceDefinition { this.viewName = viewName; } + + /** + * Set the short URL + * @param shortUrl + */ + public void setShortUrl(String shortUrl) { + this.shortUrl = shortUrl; + } + /** * Get the name of this instance. * http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java index 31af5e3..daec571 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java @@ -96,6 +96,8 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog { public static final String SETTING_DATA_COL = "setting_data"; public static final String ID = "id"; public static final String BLUEPRINT_TABLE = "blueprint"; + public static final String VIEWINSTANCE_TABLE = "viewinstance"; + public static final String SHORT_URL_COLUMN = "short_url"; @Inject PermissionDAO permissionDAO; @@ -160,6 +162,13 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog { updateAlertCurrentTable(); createBlueprintSettingTable(); updateHostRoleCommandTableDDL(); + updateViewInstanceEntityTable(); + + } + + private void updateViewInstanceEntityTable() throws SQLException { + dbAccessor.addColumn(VIEWINSTANCE_TABLE, + new DBColumnInfo(SHORT_URL_COLUMN, String.class, 255, null, true)); } private void updateClusterTableDDL() throws SQLException { http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-server/src/main/java/org/apache/ambari/server/view/ViewExtractor.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewExtractor.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewExtractor.java index 3350726..3550f98 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewExtractor.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewExtractor.java @@ -15,7 +15,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.ambari.server.view; import org.apache.ambari.server.orm.entities.ViewEntity; http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java index 037d1e5..7379f37 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java @@ -18,6 +18,7 @@ package org.apache.ambari.server.view; +import com.google.common.base.Strings; import com.google.common.collect.Sets; import com.google.common.eventbus.AllowConcurrentEvents; import com.google.common.eventbus.Subscribe; @@ -25,7 +26,6 @@ import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.persist.Transactional; - import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.api.resources.ResourceInstanceFactoryImpl; import org.apache.ambari.server.api.resources.SubResourceDefinition; @@ -80,17 +80,17 @@ import org.apache.ambari.server.view.configuration.PropertyConfig; import org.apache.ambari.server.view.configuration.ResourceConfig; import org.apache.ambari.server.view.configuration.ViewConfig; import org.apache.ambari.server.view.validation.ValidationException; -import org.apache.ambari.view.ViewInstanceDefinition; -import org.apache.ambari.view.cluster.Cluster; -import org.apache.ambari.view.validation.Validator; import org.apache.ambari.view.Masker; import org.apache.ambari.view.SystemException; import org.apache.ambari.view.View; import org.apache.ambari.view.ViewContext; import org.apache.ambari.view.ViewDefinition; +import org.apache.ambari.view.ViewInstanceDefinition; import org.apache.ambari.view.ViewResourceHandler; +import org.apache.ambari.view.cluster.Cluster; import org.apache.ambari.view.events.Event; import org.apache.ambari.view.events.Listener; +import org.apache.ambari.view.validation.Validator; import org.apache.log4j.PropertyConfigurator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -98,7 +98,6 @@ import org.slf4j.LoggerFactory; import javax.inject.Inject; import javax.inject.Provider; import javax.inject.Singleton; - import java.beans.IntrospectionException; import java.io.File; import java.net.URL; @@ -461,6 +460,7 @@ public class ViewRegistry { public Set<SubResourceDefinition> getSubResourceDefinitions( String viewName, String version) { + viewName = ViewEntity.getViewName(viewName, version); return subResourceDefinitionsMap.get(viewName); @@ -496,6 +496,25 @@ public class ViewRegistry { (getInstanceDefinition(viewEntity.getCommonName(), viewEntity.getVersion(), instanceEntity.getName()) != null); } + + public boolean duplicatedShortUrl(ViewInstanceEntity instanceEntity) { + ViewEntity viewEntity = getDefinition(instanceEntity.getViewName()); + Map<String, ViewInstanceEntity> viewInstanceDefinitionMap = + viewInstanceDefinitions.get(getDefinition(viewEntity.getCommonName(), viewEntity.getVersion())); + + if(viewInstanceDefinitionMap != null){ + for (ViewInstanceEntity viewInstanceEntity : viewInstanceDefinitionMap.values()) { + String shortUrl = viewInstanceEntity.getShortUrl(); + // check if there is a view for the same version with the same shortUrl + if (!Strings.isNullOrEmpty(shortUrl) && shortUrl.equals(instanceEntity.getShortUrl())) + return true; + } + } + + return false; + } + + /** * Install the given view instance with its associated view. * @@ -1360,6 +1379,7 @@ public class ViewRegistry { private void syncViewInstance(ViewInstanceEntity instance1, ViewInstanceEntity instance2) { instance1.setLabel(instance2.getLabel()); instance1.setDescription(instance2.getDescription()); + instance1.setShortUrl(instance2.getShortUrl()); instance1.setVisible(instance2.isVisible()); instance1.setResource(instance2.getResource()); instance1.setViewInstanceId(instance2.getViewInstanceId()); @@ -1801,6 +1821,7 @@ public class ViewRegistry { + /** * Module for stand alone view registry. */ http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/InstanceConfig.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/InstanceConfig.java b/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/InstanceConfig.java index 0087446..65b36df 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/InstanceConfig.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/view/configuration/InstanceConfig.java @@ -45,6 +45,12 @@ public class InstanceConfig { private String description; /** + * An optional short url for this instance + */ + private String shortUrl; + + + /** * Indicates whether or not the instance should be visible. */ private boolean visible = true; @@ -131,4 +137,20 @@ public class InstanceConfig { public List<PropertyConfig> getProperties() { return properties == null ? Collections.<PropertyConfig>emptyList() : properties; } + + /** + * Get the short URL + * @return short URL + */ + public String getShortUrl() { + return shortUrl; + } + + /** + * Set the short URL + * @param shortUrl + */ + public void setShortUrl(String shortUrl) { + this.shortUrl = shortUrl; + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql index 81b97bb..f90ac96 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql @@ -474,6 +474,7 @@ CREATE TABLE viewinstance ( xml_driven CHAR(1), alter_names SMALLINT NOT NULL DEFAULT 1, cluster_handle VARCHAR(255), + short_url VARCHAR (255), PRIMARY KEY(view_instance_id)); CREATE TABLE viewinstanceproperty ( http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql index 021d2b8..2b214c4 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql @@ -483,6 +483,7 @@ CREATE TABLE viewinstance ( xml_driven CHAR(1), alter_names TINYINT(1) NOT NULL DEFAULT 1, cluster_handle VARCHAR(255), + short_url VARCHAR (255), PRIMARY KEY(view_instance_id)); CREATE TABLE viewinstanceproperty ( http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql index 0320178..fc93372 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql @@ -473,6 +473,7 @@ CREATE TABLE viewinstance ( xml_driven CHAR(1), alter_names NUMBER(1) DEFAULT 1 NOT NULL, cluster_handle VARCHAR(255), + short_url VARCHAR (255), PRIMARY KEY(view_instance_id)); CREATE TABLE viewinstanceproperty ( http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql index 585cdce..870a8e8 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql @@ -475,6 +475,7 @@ CREATE TABLE viewinstance ( xml_driven CHAR(1), alter_names SMALLINT NOT NULL DEFAULT 1, cluster_handle VARCHAR(255), + short_url VARCHAR (255), PRIMARY KEY(view_instance_id)); CREATE TABLE viewinstanceproperty ( http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql index b546865..71d4813 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql @@ -473,7 +473,7 @@ CREATE TABLE ambari.blueprint_setting ( id BIGINT NOT NULL, blueprint_name varchar(255) NOT NULL, setting_name varchar(255) NOT NULL, - setting_data TEXT NOT NULL, + setting_data TEXT NOT NULL, CONSTRAINT PK_blueprint_setting PRIMARY KEY (id), CONSTRAINT UQ_blueprint_setting_name UNIQUE(blueprint_name,setting_name), CONSTRAINT FK_blueprint_setting_name FOREIGN KEY (blueprint_name) REFERENCES ambari.blueprint(blueprint_name)); @@ -529,6 +529,7 @@ CREATE TABLE ambari.viewinstance ( xml_driven CHAR(1), alter_names SMALLINT NOT NULL DEFAULT 1, cluster_handle VARCHAR(255), + short_url VARCHAR (255), PRIMARY KEY(view_instance_id)); CREATE TABLE ambari.viewinstanceproperty ( http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql index 8bfd9dd..6e600c7 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql @@ -472,6 +472,7 @@ CREATE TABLE viewinstance ( xml_driven CHAR(1), alter_names BIT NOT NULL DEFAULT 1, cluster_handle VARCHAR(255), + short_url VARCHAR (255), PRIMARY KEY(view_instance_id)); CREATE TABLE viewinstanceproperty ( http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql index 57ab922..a3ea10d 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql @@ -548,6 +548,7 @@ CREATE TABLE viewinstance ( xml_driven CHAR(1), alter_names BIT NOT NULL DEFAULT 1, cluster_handle VARCHAR(255), + short_url VARCHAR (255), PRIMARY KEY CLUSTERED (view_instance_id) ); http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProviderTest.java index 4b6700d..b384b8a 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProviderTest.java @@ -18,6 +18,8 @@ package org.apache.ambari.server.controller.internal; +import org.apache.ambari.server.AmbariException; +import org.apache.ambari.server.DuplicateResourceException; import org.apache.ambari.server.controller.spi.Predicate; import org.apache.ambari.server.controller.spi.Resource; import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException; @@ -51,15 +53,15 @@ import static org.junit.Assert.assertEquals; public class ViewInstanceResourceProviderTest { - private static final ViewRegistry singleton = createMock(ViewRegistry.class); + private static final ViewRegistry viewregistry = createMock(ViewRegistry.class); static { - ViewRegistry.initInstance(singleton); + ViewRegistry.initInstance(viewregistry); } @Before public void before() { - reset(singleton); + reset(viewregistry); } @After @@ -86,12 +88,12 @@ public class ViewInstanceResourceProviderTest { expect(viewInstanceEntity.getData()).andReturn(Collections.<ViewInstanceDataEntity>emptyList()).anyTimes(); - expect(singleton.checkAdmin()).andReturn(true); - expect(singleton.checkAdmin()).andReturn(false); + expect(viewregistry.checkAdmin()).andReturn(true); + expect(viewregistry.checkAdmin()).andReturn(false); expect(viewInstanceEntity.getClusterHandle()).andReturn("c1"); - replay(singleton, viewEntity, viewInstanceEntity); + replay(viewregistry, viewEntity, viewInstanceEntity); // as admin Resource resource = provider.toResource(viewInstanceEntity, propertyIds); @@ -114,7 +116,7 @@ public class ViewInstanceResourceProviderTest { props = properties.get("ViewInstanceInfo/properties"); assertNull(props); - verify(singleton, viewEntity, viewInstanceEntity); + verify(viewregistry, viewEntity, viewInstanceEntity); } @Test @@ -156,24 +158,24 @@ public class ViewInstanceResourceProviderTest { viewInstanceEntity.setViewEntity(viewEntity); viewInstanceEntity2.setViewEntity(viewEntity); - expect(singleton.instanceExists(viewInstanceEntity)).andReturn(false); - expect(singleton.instanceExists(viewInstanceEntity2)).andReturn(false); - expect(singleton.getDefinition("V1", "1.0.0")).andReturn(viewEntity).anyTimes(); - expect(singleton.getDefinition("V1", null)).andReturn(viewEntity).anyTimes(); + expect(viewregistry.instanceExists(viewInstanceEntity)).andReturn(false); + expect(viewregistry.instanceExists(viewInstanceEntity2)).andReturn(false); + expect(viewregistry.getDefinition("V1", "1.0.0")).andReturn(viewEntity).anyTimes(); + expect(viewregistry.getDefinition("V1", null)).andReturn(viewEntity).anyTimes(); Capture<Map<String, String>> captureProperties = new Capture<Map<String, String>>(); - singleton.setViewInstanceProperties(eq(viewInstanceEntity), capture(captureProperties), + viewregistry.setViewInstanceProperties(eq(viewInstanceEntity), capture(captureProperties), anyObject(ViewConfig.class), anyObject(ClassLoader.class)); Capture<ViewInstanceEntity> instanceEntityCapture = new Capture<ViewInstanceEntity>(); - singleton.installViewInstance(capture(instanceEntityCapture)); + viewregistry.installViewInstance(capture(instanceEntityCapture)); expectLastCall().anyTimes(); - expect(singleton.checkAdmin()).andReturn(true); - expect(singleton.checkAdmin()).andReturn(false); + expect(viewregistry.checkAdmin()).andReturn(true); + expect(viewregistry.checkAdmin()).andReturn(false); - replay(singleton); + replay(viewregistry); SecurityContextHolder.getContext().setAuthentication(authentication); @@ -190,7 +192,7 @@ public class ViewInstanceResourceProviderTest { props = viewInstanceEntity2.getPropertyMap(); assertTrue(props.isEmpty()); - verify(singleton); + verify(viewregistry); } @Test @@ -217,13 +219,13 @@ public class ViewInstanceResourceProviderTest { viewInstanceEntity.setViewEntity(viewEntity); - expect(singleton.instanceExists(viewInstanceEntity)).andReturn(true); - expect(singleton.getDefinition("V1", "1.0.0")).andReturn(viewEntity).anyTimes(); - expect(singleton.getDefinition("V1", null)).andReturn(viewEntity); + expect(viewregistry.instanceExists(viewInstanceEntity)).andReturn(true); + expect(viewregistry.getDefinition("V1", "1.0.0")).andReturn(viewEntity).anyTimes(); + expect(viewregistry.getDefinition("V1", null)).andReturn(viewEntity); - expect(singleton.checkAdmin()).andReturn(true); + expect(viewregistry.checkAdmin()).andReturn(true); - replay(singleton); + replay(viewregistry); SecurityContextHolder.getContext().setAuthentication(TestAuthenticationFactory.createAdministrator()); @@ -234,7 +236,7 @@ public class ViewInstanceResourceProviderTest { // expected } - verify(singleton); + verify(viewregistry); } @Test @@ -259,12 +261,12 @@ public class ViewInstanceResourceProviderTest { viewInstanceEntity.setName("I1"); viewInstanceEntity.setViewEntity(viewEntity); - expect(singleton.getDefinition("V1", "1.0.0")).andReturn(viewEntity).anyTimes(); - expect(singleton.getDefinition("V1", null)).andReturn(viewEntity); + expect(viewregistry.getDefinition("V1", "1.0.0")).andReturn(viewEntity).anyTimes(); + expect(viewregistry.getDefinition("V1", null)).andReturn(viewEntity); - expect(singleton.checkAdmin()).andReturn(true); + expect(viewregistry.checkAdmin()).andReturn(true); - replay(singleton); + replay(viewregistry); SecurityContextHolder.getContext().setAuthentication(TestAuthenticationFactory.createAdministrator()); @@ -275,9 +277,60 @@ public class ViewInstanceResourceProviderTest { // expected } - verify(singleton); + verify(viewregistry); } + + @Test + public void testCreateWithShortUrlValidations() throws Exception { + + ViewInstanceResourceProvider provider = new ViewInstanceResourceProvider(); + + Set<Map<String, Object>> properties = new HashSet<Map<String, Object>>(); + + Map<String, Object> propertyMap = new HashMap<String, Object>(); + + propertyMap.put(ViewInstanceResourceProvider.VIEW_NAME_PROPERTY_ID, "V1"); + propertyMap.put(ViewInstanceResourceProvider.VIEW_VERSION_PROPERTY_ID, "1.0.0"); + propertyMap.put(ViewInstanceResourceProvider.INSTANCE_NAME_PROPERTY_ID, "I1"); + propertyMap.put(ViewInstanceResourceProvider.SHORT_URL_PROPERTY_ID, "testUrl"); + + properties.add(propertyMap); + + ViewInstanceEntity viewInstanceEntity = new ViewInstanceEntity(); + viewInstanceEntity.setViewName("V1{1.0.0}"); + viewInstanceEntity.setName("I1"); + viewInstanceEntity.setShortUrl("testUrl"); + + ViewEntity viewEntity = new ViewEntity(); + viewEntity.setStatus(ViewDefinition.ViewStatus.DEPLOYED); + viewEntity.setName("V1{1.0.0}"); + + viewInstanceEntity.setViewEntity(viewEntity); + + expect(viewregistry.duplicatedShortUrl(viewInstanceEntity)).andReturn(true); + expect(viewregistry.getDefinition("V1", "1.0.0")).andReturn(viewEntity).anyTimes(); + expect(viewregistry.getDefinition("V1", null)).andReturn(viewEntity); + + expect(viewregistry.checkAdmin()).andReturn(true); + + replay(viewregistry); + + SecurityContextHolder.getContext().setAuthentication(TestAuthenticationFactory.createAdministrator()); + + try { + provider.createResources(PropertyHelper.getCreateRequest(properties, null)); + fail("Expected ResourceAlreadyExistsException."); + } catch (ResourceAlreadyExistsException e) { + // expected + } + + verify(viewregistry); + + + } + + @Test public void testUpdateResources_viewNotLoaded() throws Exception { ViewInstanceResourceProvider provider = new ViewInstanceResourceProvider(); @@ -301,9 +354,9 @@ public class ViewInstanceResourceProviderTest { viewInstanceEntity.setName("I1"); viewInstanceEntity.setViewEntity(viewEntity); - expect(singleton.getDefinitions()).andReturn(Collections.singleton(viewEntity)); + expect(viewregistry.getDefinitions()).andReturn(Collections.singleton(viewEntity)); - replay(singleton); + replay(viewregistry); SecurityContextHolder.getContext().setAuthentication(TestAuthenticationFactory.createAdministrator()); @@ -311,7 +364,7 @@ public class ViewInstanceResourceProviderTest { Assert.assertNull(viewInstanceEntity.getIcon()); - verify(singleton); + verify(viewregistry); } @Test @@ -339,13 +392,13 @@ public class ViewInstanceResourceProviderTest { viewInstanceEntity.setName("I1"); viewInstanceEntity.setViewEntity(viewEntity); - expect(singleton.getDefinitions()).andReturn(Collections.singleton(viewEntity)); + expect(viewregistry.getDefinitions()).andReturn(Collections.singleton(viewEntity)); - replay(singleton); + replay(viewregistry); SecurityContextHolder.getContext().setAuthentication(authentication); provider.deleteResources(predicate); - verify(singleton); + verify(viewregistry); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java index 59f9f91..90024a1 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java @@ -211,6 +211,10 @@ public class UpgradeCatalog240Test { Capture<DBAccessor.DBColumnInfo> hostRoleCommandOriginalStartTimeColumnInfo = newCapture(); dbAccessor.addColumn(eq(UpgradeCatalog240.HOST_ROLE_COMMAND_TABLE), capture(hostRoleCommandOriginalStartTimeColumnInfo)); + Capture<DBAccessor.DBColumnInfo> viewInstanceShortUrlInfo = newCapture(); + dbAccessor.addColumn(eq(UpgradeCatalog240.VIEWINSTANCE_TABLE), capture(viewInstanceShortUrlInfo)); + + replay(dbAccessor, configuration, connection, statement, resultSet); Module module = new Module() { @@ -220,7 +224,7 @@ public class UpgradeCatalog240Test { binder.bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class)); binder.bind(EntityManager.class).toInstance(entityManager); } - }; + }; Injector injector = Guice.createInjector(module); UpgradeCatalog240 upgradeCatalog240 = injector.getInstance(UpgradeCatalog240.class); @@ -346,6 +350,12 @@ public class UpgradeCatalog240Test { Assert.assertEquals(Long.class, originalStartTimeInfo.getType()); Assert.assertEquals(-1L, originalStartTimeInfo.getDefaultValue()); + // Verify host_role_command column + DBAccessor.DBColumnInfo viewInstanceEntityUrlColInfoValue = viewInstanceShortUrlInfo.getValue(); + Assert.assertNotNull(viewInstanceEntityUrlColInfoValue); + Assert.assertEquals("short_url", viewInstanceEntityUrlColInfoValue.getName()); + Assert.assertEquals(String.class, viewInstanceEntityUrlColInfoValue.getType()); + verify(dbAccessor); } http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-views/src/main/java/org/apache/ambari/view/ViewInstanceDefinition.java ---------------------------------------------------------------------- diff --git a/ambari-views/src/main/java/org/apache/ambari/view/ViewInstanceDefinition.java b/ambari-views/src/main/java/org/apache/ambari/view/ViewInstanceDefinition.java index d694459..62f9657 100644 --- a/ambari-views/src/main/java/org/apache/ambari/view/ViewInstanceDefinition.java +++ b/ambari-views/src/main/java/org/apache/ambari/view/ViewInstanceDefinition.java @@ -62,6 +62,12 @@ public interface ViewInstanceDefinition { public String getClusterHandle(); /** + * Get the short URL + * @return + */ + public String getShortUrl(); + + /** * Indicates whether or not the view instance should be visible. * * @return true if the view instance should be visible; false otherwise http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-web/app/controllers/main/views_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/views_controller.js b/ambari-web/app/controllers/main/views_controller.js index ed7cc23..e2e9281 100644 --- a/ambari-web/app/controllers/main/views_controller.js +++ b/ambari-web/app/controllers/main/views_controller.js @@ -85,6 +85,7 @@ App.MainViewsController = Em.Controller.extend({ version: instance.ViewInstanceInfo.version, description: instance.ViewInstanceInfo.description || Em.I18n.t('views.main.instance.noDescription'), viewName: instance.ViewInstanceInfo.view_name, + shortUrl:instance.ViewInstanceInfo.short_url, instanceName: instance.ViewInstanceInfo.instance_name, href: instance.ViewInstanceInfo.context_path + "/" }); @@ -105,7 +106,10 @@ App.MainViewsController = Em.Controller.extend({ setView: function (event) { if (event.context) { + if(event.context.shortUrl){ + App.router.route('main/view/' + event.context.viewName + '/' + event.context.shortUrl); + } else { App.router.route('main/views/' + event.context.viewName + '/' + event.context.version + '/' + event.context.instanceName); - } + }} } }); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-web/app/routes/installer.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/routes/installer.js b/ambari-web/app/routes/installer.js index 4c89e4c..f280049 100644 --- a/ambari-web/app/routes/installer.js +++ b/ambari-web/app/routes/installer.js @@ -463,7 +463,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, { unroutePath: function (router, context) { // exclusion for transition to Admin view or Views view if (context === '/adminView' || - context === '/main/views.index') { + context === '/main/views.index' || context === '/main/view.index') { this._super(router, context); } else { return false; http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-web/app/routes/main.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/routes/main.js b/ambari-web/app/routes/main.js index 9e4bde4..c9f8590 100644 --- a/ambari-web/app/routes/main.js +++ b/ambari-web/app/routes/main.js @@ -52,7 +52,7 @@ module.exports = Em.Route.extend(App.RouterRedirections, { Em.run.next(function () { App.clusterStatus.updateFromServer().complete(function () { var currentClusterStatus = App.clusterStatus.get('value'); - if (router.get('currentState.parentState.name') !== 'views' + if (router.get('currentState.parentState.name') !== 'views' && router.get('currentState.parentState.name') !== 'view' && currentClusterStatus && self.get('installerStatuses').contains(currentClusterStatus.clusterState)) { if (App.isAuthorized('AMBARI.ADD_DELETE_CLUSTERS')) { self.redirectToInstaller(router, currentClusterStatus, false); @@ -185,6 +185,8 @@ module.exports = Em.Route.extend(App.RouterRedirections, { }), views: require('routes/views'), + view: require('routes/view'), + hosts: Em.Route.extend({ route: '/hosts', http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-web/app/routes/view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/routes/view.js b/ambari-web/app/routes/view.js new file mode 100644 index 0000000..752f14d --- /dev/null +++ b/ambari-web/app/routes/view.js @@ -0,0 +1,95 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var App = require('app'); + +module.exports = Em.Route.extend({ + route: '/view', + enter: function (router) { + router.get('mainViewsController').loadAmbariViews(); + }, + index: Em.Route.extend({ + route: '/', + connectOutlets: function (router) { + router.get('mainViewsController').dataLoading().done(function() { + router.get('mainController').connectOutlet('mainViews'); + }); + } + }), + + shortViewDetails: Em.Route.extend({ + route: '/:viewName/:shortName', + connectOutlets: function (router, params) { + var viewPath = this.parseViewPath(window.location.href.slice(window.location.href.indexOf('?'))); + var slicedShortName = params.shortName; + if (viewPath) { + slicedShortName = this._getSlicedShortName(params.shortName); + if (slicedShortName === params.shortName) { + viewPath = ''; + } + + if (viewPath.charAt(0) === '/') viewPath = viewPath.slice(1); + } + + router.get('mainViewsController').dataLoading().done(function() { + var content = App.router.get('mainViewsController.ambariViews').filterProperty('viewName', params.viewName).findProperty('shortUrl', slicedShortName) + if (content) content.set('viewPath', viewPath); + router.get('mainController').connectOutlet('mainViewsDetails', content); + }); + + }, + + /** + * parse the short name and slice if needed + * + * @param {string} + * @returns {string} + * @private + */ + _getSlicedShortName: function (instanceName) { + if (instanceName.lastIndexOf('?') > -1) { + return instanceName.slice(0, instanceName.lastIndexOf('?')); + } + + return instanceName; + }, + + /** + * parse internal view path + * "viewPath" - used as a key of additional path + * Example: + * origin URL: viewName?viewPath=%2Fuser%2Fadmin%2Faddress&foo=bar&count=1 + * should be translated to + * view path: /user/admin/address?foo=bar&count=1 + * + * @param {string} instanceName + * @returns {string} + */ + parseViewPath: function (instanceName) { + var path = ''; + if (instanceName.contains('?')) { + path = instanceName.slice(instanceName.indexOf('?')); + if (path.contains('viewPath')) { + path = decodeURIComponent(path.slice((path.lastIndexOf('?viewPath=') + 10))).replace('&', '?'); + } + } + return path; + } + + }) +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/7bd0ad73/ambari-web/app/routes/views.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/routes/views.js b/ambari-web/app/routes/views.js index 08396eb..c50690c 100644 --- a/ambari-web/app/routes/views.js +++ b/ambari-web/app/routes/views.js @@ -31,11 +31,13 @@ module.exports = Em.Route.extend({ }); } }), + + viewDetails: Em.Route.extend({ + route: '/:viewName/:version/:instanceName', connectOutlets: function (router, params) { // find and set content for `mainViewsDetails` and associated controller - var href = ['/views', params.viewName, params.version, params.instanceName + "/"].join('/'); var viewPath = this.parseViewPath(window.location.href.slice(window.location.href.indexOf('?'))); if (viewPath) {
