ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nc...@apache.org
Subject ambari git commit: AMBARI-18557. Create Component to Repo Version db associations (ncole)
Date Mon, 10 Oct 2016 20:22:07 GMT
Repository: ambari
Updated Branches:
  refs/heads/branch-dev-patch-upgrade 784c7e456 -> b31c6c285


AMBARI-18557. Create Component to Repo Version db associations (ncole)


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

Branch: refs/heads/branch-dev-patch-upgrade
Commit: b31c6c28563096419ae53e1584c4aa103262e6de
Parents: 784c7e4
Author: Nate Cole <ncole@hortonworks.com>
Authored: Fri Oct 7 15:13:00 2016 -0400
Committer: Nate Cole <ncole@hortonworks.com>
Committed: Mon Oct 10 14:26:41 2016 -0400

----------------------------------------------------------------------
 .../dao/ServiceComponentDesiredStateDAO.java    |  23 ++-
 .../ServiceComponentDesiredStateEntity.java     |  24 +++
 .../entities/ServiceComponentVersionEntity.java | 159 +++++++++++++++++++
 .../server/upgrade/UpgradeCatalog300.java       |  41 +++++
 .../main/resources/Ambari-DDL-Derby-CREATE.sql  |  15 +-
 .../main/resources/Ambari-DDL-MySQL-CREATE.sql  |  14 +-
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql |  12 ++
 .../resources/Ambari-DDL-Postgres-CREATE.sql    |  14 +-
 .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql |  12 ++
 .../resources/Ambari-DDL-SQLServer-CREATE.sql   |  14 +-
 .../src/main/resources/META-INF/persistence.xml |   1 +
 .../server/state/ServiceComponentTest.java      | 140 ++++++++++++++--
 .../server/upgrade/UpgradeCatalog300Test.java   |  99 ++++++++++++
 13 files changed, 553 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/b31c6c28/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceComponentDesiredStateDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceComponentDesiredStateDAO.java
b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceComponentDesiredStateDAO.java
index cdaa6f0..987e44f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceComponentDesiredStateDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ServiceComponentDesiredStateDAO.java
@@ -28,6 +28,7 @@ import javax.persistence.TypedQuery;
 import org.apache.ambari.server.orm.RequiresSession;
 import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
 import org.apache.ambari.server.orm.entities.ServiceComponentHistoryEntity;
+import org.apache.ambari.server.orm.entities.ServiceComponentVersionEntity;
 
 import com.google.inject.Inject;
 import com.google.inject.Provider;
@@ -175,7 +176,27 @@ public class ServiceComponentDesiredStateDAO {
     query.setParameter("serviceName", serviceName);
     query.setParameter("componentName", componentName);
 
-    ServiceComponentDesiredStateEntity entity = null;
     return daoUtils.selectList(query);
   }
+
+  /**
+   * @param clusterId     the cluster id
+   * @param serviceName   the service name
+   * @param componentName the component name
+   * @return the list of repository versions for a component
+   */
+  @RequiresSession
+  public List<ServiceComponentVersionEntity> findVersions(long clusterId, String serviceName,
+      String componentName) {
+    EntityManager entityManager = entityManagerProvider.get();
+    TypedQuery<ServiceComponentVersionEntity> query = entityManager.createNamedQuery(
+        "ServiceComponentVersionEntity.findByComponent", ServiceComponentVersionEntity.class);
+
+    query.setParameter("clusterId", clusterId);
+    query.setParameter("serviceName", serviceName);
+    query.setParameter("componentName", componentName);
+
+    return daoUtils.selectList(query);
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/b31c6c28/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
index 61c053d..9b93517 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentDesiredStateEntity.java
@@ -117,6 +117,9 @@ public class ServiceComponentDesiredStateEntity {
       cascade = { CascadeType.ALL })
   private Collection<ServiceComponentHistoryEntity> serviceComponentHistory;
 
+  @OneToMany(mappedBy = "m_serviceComponentDesiredStateEntity", cascade = { CascadeType.ALL
})
+  private Collection<ServiceComponentVersionEntity> serviceComponentVersion;
+
   public Long getId() {
     return id;
   }
@@ -195,6 +198,27 @@ public class ServiceComponentDesiredStateEntity {
     return serviceComponentHistory;
   }
 
+
+  /**
+   * @param versionEntry the version to add
+   */
+  public void addVersion(ServiceComponentVersionEntity versionEntry) {
+    if (null == serviceComponentVersion) {
+      serviceComponentVersion = new ArrayList<>();
+    }
+
+    serviceComponentVersion.add(versionEntry);
+    versionEntry.setServiceComponentDesiredState(this);
+  }
+
+  /**
+   * @return the collection of versions for the component
+   */
+  public Collection<ServiceComponentVersionEntity> getVersions() {
+    return serviceComponentVersion;
+  }
+
+
   public boolean isRecoveryEnabled() {
     return recoveryEnabled != 0;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/b31c6c28/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentVersionEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentVersionEntity.java
b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentVersionEntity.java
new file mode 100644
index 0000000..5085d18
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceComponentVersionEntity.java
@@ -0,0 +1,159 @@
+/**
+ * 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.
+ */
+package org.apache.ambari.server.orm.entities;
+
+import java.util.Objects;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+
+import org.apache.ambari.server.state.RepositoryVersionState;
+
+/**
+ * The {@link ServiceComponentVersionEntity} class is used to represent the
+ * association of a component and repository version.
+ */
+@Entity
+@Table(name = "servicecomponent_version")
+@TableGenerator(
+    name = "servicecomponent_version_id_generator",
+    table = "ambari_sequences",
+    pkColumnName = "sequence_name",
+    valueColumnName = "sequence_value",
+    pkColumnValue = "servicecomponent_version_id_seq",
+    initialValue = 0)
+@NamedQueries({ @NamedQuery(
+    name = "ServiceComponentVersionEntity.findByComponent",
+    query = "SELECT version FROM ServiceComponentVersionEntity version WHERE version.m_serviceComponentDesiredStateEntity.clusterId
= :clusterId AND version.m_serviceComponentDesiredStateEntity.serviceName = :serviceName AND
version.m_serviceComponentDesiredStateEntity.componentName = :componentName") })
+public class ServiceComponentVersionEntity {
+
+  @Id
+  @GeneratedValue(
+      strategy = GenerationType.TABLE,
+      generator = "servicecomponent_version_id_generator")
+  @Column(name = "id", nullable = false, updatable = false)
+  private long m_id;
+
+  @ManyToOne(optional = false, cascade = { CascadeType.MERGE })
+  @JoinColumn(name = "component_id", referencedColumnName = "id", nullable = false)
+  private ServiceComponentDesiredStateEntity m_serviceComponentDesiredStateEntity;
+
+  @ManyToOne
+  @JoinColumn(name = "repo_version_id", referencedColumnName = "repo_version_id", nullable
= false)
+  private RepositoryVersionEntity m_repositoryVersion;
+
+  @Column(name = "state", nullable = false, insertable = true, updatable = true)
+  @Enumerated(value = EnumType.STRING)
+  private RepositoryVersionState m_state = RepositoryVersionState.CURRENT;
+
+  @Column(name = "user_name", nullable = false, insertable=true, updatable=true)
+  private String userName;
+
+
+  /**
+   * @return the associated component
+   */
+  public ServiceComponentDesiredStateEntity getServiceComponentDesiredState() {
+    return m_serviceComponentDesiredStateEntity;
+  }
+
+  /**
+   * @param serviceComponentDesiredStateEntity  the associated component (not {@code null})
+   */
+  public void setServiceComponentDesiredState(ServiceComponentDesiredStateEntity serviceComponentDesiredStateEntity)
{
+    m_serviceComponentDesiredStateEntity = serviceComponentDesiredStateEntity;
+  }
+
+  /**
+   * @param repositoryVersion the repository
+   */
+  public void setRepositoryVersion(RepositoryVersionEntity repositoryVersion) {
+    m_repositoryVersion = repositoryVersion;
+  }
+
+  /**
+   * @return the id
+   */
+  public long getId() {
+    return m_id;
+  }
+
+  /**
+   * @return the state of the repository
+   */
+  public RepositoryVersionState getState() {
+    return m_state;
+  }
+
+  /**
+   * @param state the state of the repository
+   */
+  public void setState(RepositoryVersionState state) {
+    m_state = state;
+  }
+
+  /**
+   * @return the user name
+   */
+  public String getUserName() {
+    return userName;
+  }
+
+  /**
+   * @param name  the user name
+   */
+  public void setUserName(String name) {
+    userName = name;
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(m_id, m_repositoryVersion, m_serviceComponentDesiredStateEntity,
m_state);
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj) {
+      return true;
+    }
+
+    if (obj == null || getClass() != obj.getClass()) {
+      return false;
+    }
+
+    final ServiceComponentVersionEntity other = (ServiceComponentVersionEntity) obj;
+
+    return Objects.equals(m_id, other.m_id)
+        && Objects.equals(m_repositoryVersion, other.m_repositoryVersion)
+        && Objects.equals(m_serviceComponentDesiredStateEntity, other.m_serviceComponentDesiredStateEntity)
+        && Objects.equals(m_state, other.m_state);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/b31c6c28/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
index 64c98b7..01510ad 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
@@ -19,10 +19,13 @@ package org.apache.ambari.server.upgrade;
 
 
 import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.orm.DBAccessor.DBColumnInfo;
 import org.apache.ambari.server.orm.dao.DaoUtils;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
@@ -41,9 +44,16 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
    */
   private static final Logger LOG = LoggerFactory.getLogger(UpgradeCatalog300.class);
 
+  public static final String COMPONENT_TABLE = "servicecomponentdesiredstate";
+  public static final String COMPONENT_VERSION_TABLE = "servicecomponent_version";
+  public static final String COMPONENT_VERSION_PK = "PK_sc_version";
+  public static final String COMPONENT_VERSION_FK_COMPONENT = "FK_scv_component_id";
+  public static final String COMPONENT_VERSION_FK_REPO_VERSION = "FK_scv_repo_version_id";
+
   @Inject
   DaoUtils daoUtils;
 
+
   // ----- Constructors ------------------------------------------------------
 
   /**
@@ -83,6 +93,8 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
    */
   @Override
   protected void executeDDLUpdates() throws AmbariException, SQLException {
+
+    createComponentVersionTable();
   }
 
   /**
@@ -122,5 +134,34 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
 
   }
 
+  /**
+   * Creates the servicecomponent_version table
+   * @throws SQLException
+   */
+  private void createComponentVersionTable() throws SQLException {
+
+    List<DBColumnInfo> columns = new ArrayList<>();
+
+    // Add extension link table
+    LOG.info("Creating {} table", COMPONENT_VERSION_TABLE);
+
+    columns.add(new DBColumnInfo("id", Long.class, null, null, false));
+    columns.add(new DBColumnInfo("component_id", Long.class, null, null, false));
+    columns.add(new DBColumnInfo("repo_version_id", Long.class, null, null, false));
+    columns.add(new DBColumnInfo("state", String.class, 32, null, false));
+    columns.add(new DBColumnInfo("user_name", String.class, 255, null, false));
+    dbAccessor.createTable(COMPONENT_VERSION_TABLE, columns, (String[]) null);
+
+    dbAccessor.addPKConstraint(COMPONENT_VERSION_TABLE, COMPONENT_VERSION_PK, "id");
+
+    dbAccessor.addFKConstraint(COMPONENT_VERSION_TABLE, COMPONENT_VERSION_FK_COMPONENT, "component_id",
+        COMPONENT_TABLE, "id", false);
+
+    dbAccessor.addFKConstraint(COMPONENT_VERSION_TABLE, COMPONENT_VERSION_FK_REPO_VERSION,
"repo_version_id",
+        "repo_version", "id", false);
+
+    addSequence("servicecomponent_version_id_seq", 0L, false);
+  }
+
 
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/b31c6c28/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 c2c965d..0df6ea6 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
@@ -872,6 +872,17 @@ CREATE TABLE servicecomponent_history(
   CONSTRAINT FK_sc_history_to_stack_id FOREIGN KEY (to_stack_id) REFERENCES stack (stack_id)
 );
 
+CREATE TABLE servicecomponent_version(
+  id BIGINT NOT NULL,
+  component_id BIGINT NOT NULL,
+  repo_version_id BIGINT NOT NULL,
+  state VARCHAR(32) NOT NULL,
+  user_name VARCHAR(255) NOT NULL,
+  CONSTRAINT PK_sc_version PRIMARY KEY (id),
+  CONSTRAINT FK_scv_component_id FOREIGN KEY (component_id) REFERENCES servicecomponentdesiredstate
(id),
+  CONSTRAINT FK_scv_repo_version_id FOREIGN KEY (repo_version_id) REFERENCES repo_version
(id)
+);
+
 CREATE TABLE ambari_operation_history(
   id BIGINT NOT NULL,
   from_version VARCHAR(255) NOT NULL,
@@ -1142,7 +1153,9 @@ INSERT INTO ambari_sequences (sequence_name, sequence_value)
   union all
   select 'remote_cluster_id_seq', 0 FROM SYSIBM.SYSDUMMY1
   union all
-  select 'remote_cluster_service_id_seq', 0 FROM SYSIBM.SYSDUMMY1;
+  select 'remote_cluster_service_id_seq', 0 FROM SYSIBM.SYSDUMMY
+  union all
+  select 'servicecomponent_version_id_seq', 0 FROM SYSIBM.SYSDUMMY1;
 
 
 INSERT INTO adminresourcetype (resource_type_id, resource_type_name)

http://git-wip-us.apache.org/repos/asf/ambari/blob/b31c6c28/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 1c17e1a..adea903 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -879,6 +879,17 @@ CREATE TABLE servicecomponent_history(
   CONSTRAINT FK_sc_history_to_stack_id FOREIGN KEY (to_stack_id) REFERENCES stack (stack_id)
 );
 
+CREATE TABLE servicecomponent_version(
+  id BIGINT NOT NULL,
+  component_id BIGINT NOT NULL,
+  repo_version_id BIGINT NOT NULL,
+  state VARCHAR(32) NOT NULL,
+  user_name VARCHAR(255) NOT NULL,
+  CONSTRAINT PK_sc_version PRIMARY KEY (id),
+  CONSTRAINT FK_scv_component_id FOREIGN KEY (component_id) REFERENCES servicecomponentdesiredstate
(id),
+  CONSTRAINT FK_scv_repo_version_id FOREIGN KEY (repo_version_id) REFERENCES repo_version
(id)
+);
+
 CREATE TABLE ambari_operation_history(
   id BIGINT NOT NULL,
   from_version VARCHAR(255) NOT NULL,
@@ -1097,7 +1108,8 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) VALUES
   ('blueprint_setting_id_seq', 0),
   ('ambari_operation_history_id_seq', 0),
   ('remote_cluster_id_seq', 0),
-  ('remote_cluster_service_id_seq', 0);
+  ('remote_cluster_service_id_seq', 0),
+  ('servicecomponent_version_id_seq', 0);
 
 INSERT INTO adminresourcetype (resource_type_id, resource_type_name) VALUES
   (1, 'AMBARI'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/b31c6c28/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 49f3e2f..4225bf1 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -869,6 +869,17 @@ CREATE TABLE servicecomponent_history(
   CONSTRAINT FK_sc_history_to_stack_id FOREIGN KEY (to_stack_id) REFERENCES stack (stack_id)
 );
 
+CREATE TABLE servicecomponent_version(
+  id NUMBER(19) NOT NULL,
+  component_id NUMBER(19) NOT NULL,
+  repo_version_id NUMBER(19) NOT NULL,
+  state VARCHAR2(32) NOT NULL,
+  user_name VARCHAR2(255) NOT NULL,
+  CONSTRAINT PK_sc_version PRIMARY KEY (id),
+  CONSTRAINT FK_scv_component_id FOREIGN KEY (component_id) REFERENCES servicecomponentdesiredstate
(id),
+  CONSTRAINT FK_scv_repo_version_id FOREIGN KEY (repo_version_id) REFERENCES repo_version
(id)
+);
+
 CREATE TABLE ambari_operation_history(
   id NUMBER(19) NOT NULL,
   from_version VARCHAR2(255) NOT NULL,
@@ -1088,6 +1099,7 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('blueprint_s
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('ambari_operation_history_id_seq',
0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('remote_cluster_id_seq',
0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('remote_cluster_service_id_seq',
0);
+INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('servicecomponent_version_id_seq',
0);
 
 INSERT INTO metainfo("metainfo_key", "metainfo_value") values ('version', '${ambariSchemaVersion}');
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/b31c6c28/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 7aa52ef..107a1ca 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -871,6 +871,17 @@ CREATE TABLE servicecomponent_history(
   CONSTRAINT FK_sc_history_to_stack_id FOREIGN KEY (to_stack_id) REFERENCES stack (stack_id)
 );
 
+CREATE TABLE servicecomponent_version(
+  id BIGINT NOT NULL,
+  component_id BIGINT NOT NULL,
+  repo_version_id BIGINT NOT NULL,
+  state VARCHAR(32) NOT NULL,
+  user_name VARCHAR(255) NOT NULL,
+  CONSTRAINT PK_sc_version PRIMARY KEY (id),
+  CONSTRAINT FK_scv_component_id FOREIGN KEY (component_id) REFERENCES servicecomponentdesiredstate
(id),
+  CONSTRAINT FK_scv_repo_version_id FOREIGN KEY (repo_version_id) REFERENCES repo_version
(id)
+);
+
 CREATE TABLE ambari_operation_history(
   id BIGINT NOT NULL,
   from_version VARCHAR(255) NOT NULL,
@@ -1088,7 +1099,8 @@ INSERT INTO ambari_sequences (sequence_name, sequence_value) VALUES
   ('blueprint_setting_id_seq', 0),
   ('ambari_operation_history_id_seq', 0),
   ('remote_cluster_id_seq', 0),
-  ('remote_cluster_service_id_seq', 0);
+  ('remote_cluster_service_id_seq', 0),
+  ('servicecomponent_version_id_seq', 0);
 
 INSERT INTO adminresourcetype (resource_type_id, resource_type_name) VALUES
   (1, 'AMBARI'),

http://git-wip-us.apache.org/repos/asf/ambari/blob/b31c6c28/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 0c95471..786cbe4 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
@@ -868,6 +868,17 @@ CREATE TABLE servicecomponent_history(
   CONSTRAINT FK_sc_history_to_stack_id FOREIGN KEY (to_stack_id) REFERENCES stack (stack_id)
 );
 
+CREATE TABLE servicecomponent_version(
+  id NUMERIC(19) NOT NULL,
+  component_id NUMERIC(19) NOT NULL,
+  repo_version_id NUMERIC(19) NOT NULL,
+  state VARCHAR(32) NOT NULL,
+  user_name VARCHAR(255) NOT NULL,
+  CONSTRAINT PK_sc_version PRIMARY KEY (id),
+  CONSTRAINT FK_scv_component_id FOREIGN KEY (component_id) REFERENCES servicecomponentdesiredstate
(id),
+  CONSTRAINT FK_scv_repo_version_id FOREIGN KEY (repo_version_id) REFERENCES repo_version
(id)
+);
+
 CREATE TABLE ambari_operation_history(
   id NUMERIC(19) NOT NULL,
   from_version VARCHAR(255) NOT NULL,
@@ -1087,6 +1098,7 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('blueprint_s
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('ambari_operation_history_id_seq',
0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('remote_cluster_id_seq',
0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('remote_cluster_service_id_seq',
0);
+INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('servicecomponent_version_id_seq',
0);
 
 insert into adminresourcetype (resource_type_id, resource_type_name)
   select 1, 'AMBARI'

http://git-wip-us.apache.org/repos/asf/ambari/blob/b31c6c28/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 631b5c4..f0c023d 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -889,6 +889,17 @@ CREATE TABLE servicecomponent_history(
   CONSTRAINT FK_sc_history_to_stack_id FOREIGN KEY (to_stack_id) REFERENCES stack (stack_id)
 );
 
+CREATE TABLE servicecomponent_version(
+  id BIGINT NOT NULL,
+  component_id BIGINT NOT NULL,
+  repo_version_id BIGINT NOT NULL,
+  state VARCHAR(32) NOT NULL,
+  user_name VARCHAR(255) NOT NULL,
+  CONSTRAINT PK_sc_version PRIMARY KEY (id),
+  CONSTRAINT FK_scv_component_id FOREIGN KEY (component_id) REFERENCES servicecomponentdesiredstate
(id),
+  CONSTRAINT FK_scv_repo_version_id FOREIGN KEY (repo_version_id) REFERENCES repo_version
(id)
+);
+
 CREATE TABLE ambari_operation_history(
   id BIGINT NOT NULL,
   from_version VARCHAR(255) NOT NULL,
@@ -1112,7 +1123,8 @@ BEGIN TRANSACTION
     ('blueprint_setting_id_seq', 0),
     ('ambari_operation_history_id_seq', 0),
     ('remote_cluster_id_seq', 0),
-    ('remote_cluster_service_id_seq', 0);
+    ('remote_cluster_service_id_seq', 0),
+    ('servicecomponent_version_id_seq', 0);
 
   insert into adminresourcetype (resource_type_id, resource_type_name)
   values

http://git-wip-us.apache.org/repos/asf/ambari/blob/b31c6c28/ambari-server/src/main/resources/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/META-INF/persistence.xml b/ambari-server/src/main/resources/META-INF/persistence.xml
index 2bc3282..0375650 100644
--- a/ambari-server/src/main/resources/META-INF/persistence.xml
+++ b/ambari-server/src/main/resources/META-INF/persistence.xml
@@ -67,6 +67,7 @@
     <class>org.apache.ambari.server.orm.entities.RoleSuccessCriteriaEntity</class>
     <class>org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity</class>
     <class>org.apache.ambari.server.orm.entities.ServiceComponentHistoryEntity</class>
+    <class>org.apache.ambari.server.orm.entities.ServiceComponentVersionEntity</class>
     <class>org.apache.ambari.server.orm.entities.ServiceConfigEntity</class>
     <class>org.apache.ambari.server.orm.entities.ServiceDesiredStateEntity</class>
     <class>org.apache.ambari.server.orm.entities.StackEntity</class>

http://git-wip-us.apache.org/repos/asf/ambari/blob/b31c6c28/ambari-server/src/test/java/org/apache/ambari/server/state/ServiceComponentTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/ServiceComponentTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/state/ServiceComponentTest.java
index b043da1..0bf21f9 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/ServiceComponentTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/ServiceComponentTest.java
@@ -18,10 +18,14 @@
 
 package org.apache.ambari.server.state;
 
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.persist.PersistService;
-import junit.framework.Assert;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.controller.ServiceComponentResponse;
@@ -31,14 +35,17 @@ import org.apache.ambari.server.orm.OrmTestHelper;
 import org.apache.ambari.server.orm.dao.HostComponentDesiredStateDAO;
 import org.apache.ambari.server.orm.dao.HostComponentStateDAO;
 import org.apache.ambari.server.orm.dao.HostDAO;
+import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
 import org.apache.ambari.server.orm.dao.ServiceComponentDesiredStateDAO;
 import org.apache.ambari.server.orm.dao.UpgradeDAO;
 import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntity;
 import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntityPK;
 import org.apache.ambari.server.orm.entities.HostComponentStateEntity;
 import org.apache.ambari.server.orm.entities.HostEntity;
+import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
 import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
 import org.apache.ambari.server.orm.entities.ServiceComponentHistoryEntity;
+import org.apache.ambari.server.orm.entities.ServiceComponentVersionEntity;
 import org.apache.ambari.server.orm.entities.UpgradeEntity;
 import org.apache.ambari.server.state.stack.upgrade.Direction;
 import org.apache.ambari.server.state.stack.upgrade.UpgradeType;
@@ -46,13 +53,11 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
+import junit.framework.Assert;
 
 public class ServiceComponentTest {
 
@@ -510,6 +515,7 @@ public class ServiceComponentTest {
     ServiceComponentDesiredStateEntity serviceComponentDesiredStateEntity = serviceComponentDesiredStateDAO.findByName(
         cluster.getClusterId(), serviceName, componentName);
 
+
     Assert.assertNotNull(serviceComponentDesiredStateEntity);
 
     UpgradeEntity upgradeEntity = createUpgradeEntity("2.2.0.0", "2.2.0.1");
@@ -551,6 +557,119 @@ public class ServiceComponentTest {
     assertEquals(0, componentHistoryList.size());
   }
 
+  @Test
+  public void testVersionCreation() throws Exception {
+    ServiceComponentDesiredStateDAO serviceComponentDesiredStateDAO = injector.getInstance(
+        ServiceComponentDesiredStateDAO.class);
+
+    String componentName = "NAMENODE";
+    ServiceComponent component = serviceComponentFactory.createNew(service, componentName);
+    service.addServiceComponent(component);
+    component.persist();
+
+    ServiceComponent sc = service.getServiceComponent(componentName);
+    Assert.assertNotNull(sc);
+
+    sc.setDesiredState(State.INSTALLED);
+    Assert.assertEquals(State.INSTALLED, sc.getDesiredState());
+
+    sc.setDesiredStackVersion(new StackId("HDP-2.2.0"));
+    StackId stackId = sc.getDesiredStackVersion();
+    Assert.assertEquals(new StackId("HDP", "2.2.0"), stackId);
+
+    Assert.assertEquals("HDP-2.2.0", sc.getDesiredStackVersion().getStackId());
+
+    ServiceComponentDesiredStateEntity serviceComponentDesiredStateEntity = serviceComponentDesiredStateDAO.findByName(
+        cluster.getClusterId(), serviceName, componentName);
+
+    Assert.assertNotNull(serviceComponentDesiredStateEntity);
+
+    RepositoryVersionEntity rve = new RepositoryVersionEntity(
+        serviceComponentDesiredStateEntity.getDesiredStack(), "HDP-2.2.0", "2.2.0.1-1111",
"[]");
+
+    RepositoryVersionDAO repositoryDAO = injector.getInstance(RepositoryVersionDAO.class);
+    repositoryDAO.create(rve);
+
+    ServiceComponentVersionEntity version = new ServiceComponentVersionEntity();
+    version.setState(RepositoryVersionState.CURRENT);
+    version.setRepositoryVersion(rve);
+    version.setUserName("user");
+    serviceComponentDesiredStateEntity.addVersion(version);
+
+    serviceComponentDesiredStateEntity = serviceComponentDesiredStateDAO.merge(
+        serviceComponentDesiredStateEntity);
+
+    serviceComponentDesiredStateEntity = serviceComponentDesiredStateDAO.findByName(
+        cluster.getClusterId(), serviceName, componentName);
+
+    assertEquals(1, serviceComponentDesiredStateEntity.getVersions().size());
+    ServiceComponentVersionEntity persistedVersion = serviceComponentDesiredStateEntity.getVersions().iterator().next();
+
+    assertEquals(RepositoryVersionState.CURRENT, persistedVersion.getState());
+  }
+
+  @Test
+  public void testVersionRemoval() throws Exception {
+    ServiceComponentDesiredStateDAO serviceComponentDesiredStateDAO = injector.getInstance(
+        ServiceComponentDesiredStateDAO.class);
+
+    String componentName = "NAMENODE";
+    ServiceComponent component = serviceComponentFactory.createNew(service, componentName);
+    service.addServiceComponent(component);
+    component.persist();
+
+    ServiceComponent sc = service.getServiceComponent(componentName);
+    Assert.assertNotNull(sc);
+
+    sc.setDesiredState(State.INSTALLED);
+    Assert.assertEquals(State.INSTALLED, sc.getDesiredState());
+
+    sc.setDesiredStackVersion(new StackId("HDP-2.2.0"));
+    StackId stackId = sc.getDesiredStackVersion();
+    Assert.assertEquals(new StackId("HDP", "2.2.0"), stackId);
+
+    Assert.assertEquals("HDP-2.2.0", sc.getDesiredStackVersion().getStackId());
+
+    ServiceComponentDesiredStateEntity serviceComponentDesiredStateEntity = serviceComponentDesiredStateDAO.findByName(
+        cluster.getClusterId(), serviceName, componentName);
+
+    Assert.assertNotNull(serviceComponentDesiredStateEntity);
+
+    RepositoryVersionEntity rve = new RepositoryVersionEntity(
+        serviceComponentDesiredStateEntity.getDesiredStack(), "HDP-2.2.0", "2.2.0.1-1111",
"[]");
+
+    RepositoryVersionDAO repositoryDAO = injector.getInstance(RepositoryVersionDAO.class);
+    repositoryDAO.create(rve);
+
+    ServiceComponentVersionEntity version = new ServiceComponentVersionEntity();
+    version.setState(RepositoryVersionState.CURRENT);
+    version.setRepositoryVersion(rve);
+    version.setUserName("user");
+    serviceComponentDesiredStateEntity.addVersion(version);
+
+    serviceComponentDesiredStateEntity = serviceComponentDesiredStateDAO.merge(
+        serviceComponentDesiredStateEntity);
+
+    serviceComponentDesiredStateEntity = serviceComponentDesiredStateDAO.findByName(
+        cluster.getClusterId(), serviceName, componentName);
+
+    assertEquals(1, serviceComponentDesiredStateEntity.getVersions().size());
+    ServiceComponentVersionEntity persistedVersion = serviceComponentDesiredStateEntity.getVersions().iterator().next();
+
+    assertEquals(RepositoryVersionState.CURRENT, persistedVersion.getState());
+
+    sc.delete();
+
+    serviceComponentDesiredStateEntity = serviceComponentDesiredStateDAO.findByName(
+        cluster.getClusterId(), serviceName, componentName);
+    Assert.assertNull(serviceComponentDesiredStateEntity);
+
+
+    // verify versions are gone, too
+    List<ServiceComponentVersionEntity> list = serviceComponentDesiredStateDAO.findVersions(cluster.getClusterId(),
serviceName, componentName);
+    assertEquals(0, list.size());
+  }
+
   /**
    * Creates an upgrade entity, asserting it was created correctly.
    *
@@ -574,4 +693,5 @@ public class ServiceComponentTest {
     assertEquals(1, upgrades.size());
     return upgradeEntity;
   }
+
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/b31c6c28/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java
b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java
index dcb1fdd..df3d79a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog300Test.java
@@ -17,13 +17,39 @@
  */
 package org.apache.ambari.server.upgrade;
 
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.capture;
 import static org.easymock.EasyMock.createMockBuilder;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.createStrictMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.newCapture;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
 
 import java.lang.reflect.Method;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
+import javax.persistence.EntityManager;
+
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.orm.DBAccessor;
+import org.apache.ambari.server.state.stack.OsFamily;
+import org.easymock.Capture;
+import org.junit.Assert;
 import org.junit.Test;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+import com.google.inject.Binder;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Module;
 
 public class UpgradeCatalog300Test {
 
@@ -47,8 +73,81 @@ public class UpgradeCatalog300Test {
     upgradeCatalog300.executeDMLUpdates();
 
     verify(upgradeCatalog300);
+  }
+
+  @Test
+  public void testExecuteDDLUpdates() throws Exception {
+
+    final EntityManager entityManager = createNiceMock(EntityManager.class);
+    final DBAccessor dbAccessor = createStrictMock(DBAccessor.class);
+    Configuration configuration = createNiceMock(Configuration.class);
+    Connection connection = createNiceMock(Connection.class);
+    Statement statement = createNiceMock(Statement.class);
+    ResultSet resultSet = createNiceMock(ResultSet.class);
+
+
+    // !!! setup capture for servicecomponent_version
+    Capture<List<DBAccessor.DBColumnInfo>> capturedComponentVersionColumns =
newCapture();
+
+    dbAccessor.createTable(eq(UpgradeCatalog300.COMPONENT_VERSION_TABLE), capture(capturedComponentVersionColumns),
+        eq((String[]) null));
+
+    dbAccessor.addPKConstraint(eq(UpgradeCatalog300.COMPONENT_VERSION_TABLE),
+        eq(UpgradeCatalog300.COMPONENT_VERSION_PK), eq("id"));
+    dbAccessor.addFKConstraint(eq(UpgradeCatalog300.COMPONENT_VERSION_TABLE),
+        eq(UpgradeCatalog300.COMPONENT_VERSION_FK_COMPONENT), eq("component_id"),
+        eq(UpgradeCatalog300.COMPONENT_TABLE), eq("id"), eq(false));
+    dbAccessor.addFKConstraint(eq(UpgradeCatalog300.COMPONENT_VERSION_TABLE),
+        eq(UpgradeCatalog300.COMPONENT_VERSION_FK_REPO_VERSION), eq("repo_version_id"),
+        eq("repo_version"), eq("id"), eq(false));
+
+
+    expect(dbAccessor.getConnection()).andReturn(connection);
+    expect(connection.createStatement()).andReturn(statement);
+    expect(statement.executeQuery(anyObject(String.class))).andReturn(resultSet);
+
+    replay(dbAccessor, configuration, connection, statement, resultSet);
+
+    Module module = new Module() {
+      @Override
+      public void configure(Binder binder) {
+        binder.bind(DBAccessor.class).toInstance(dbAccessor);
+        binder.bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
+        binder.bind(EntityManager.class).toInstance(entityManager);
+        binder.bind(PasswordEncoder.class).toInstance(createNiceMock(PasswordEncoder.class));
+      }
+    };
+
+    Injector injector = Guice.createInjector(module);
+    UpgradeCatalog300 upgradeCatalog300 = injector.getInstance(UpgradeCatalog300.class);
+    upgradeCatalog300.executeDDLUpdates();
+
+    verify(dbAccessor);
+
+    // !!! check the captured for servicecomponent_version
+    Map<String, DBAccessor.DBColumnInfo> expected = new HashMap<>();
+    expected.put("id", new DBAccessor.DBColumnInfo("id", Long.class, null, null, false));
+    expected.put("component_id", new DBAccessor.DBColumnInfo("component_id", Long.class,
null, null, false));
+    expected.put("repo_version_id", new DBAccessor.DBColumnInfo("repo_version_id", Long.class,
null, null, false));
+    expected.put("state", new DBAccessor.DBColumnInfo("state", String.class, 32, null, false));
+    expected.put("user_name", new DBAccessor.DBColumnInfo("user_name", String.class, 255,
null, false));
+
+    List<DBAccessor.DBColumnInfo> captured = capturedComponentVersionColumns.getValue();
+    Assert.assertEquals(5, captured.size());
+
+    for (DBAccessor.DBColumnInfo column : captured) {
+      DBAccessor.DBColumnInfo expectedColumn = expected.remove(column.getName());
 
+      Assert.assertNotNull(expectedColumn);
+      Assert.assertEquals(expectedColumn.getDefaultValue(), column.getDefaultValue());
+      Assert.assertEquals(expectedColumn.getName(), column.getName());
+      Assert.assertEquals(expectedColumn.getLength(), column.getLength());
+      Assert.assertEquals(expectedColumn.getType(), column.getType());
+      Assert.assertEquals(expectedColumn.getClass(), column.getClass());
+    }
 
+    // did we get them all?
+    Assert.assertEquals(0, expected.size());
   }
 
 }


Mime
View raw message