Skip to content

Commit

Permalink
Merge pull request #583 from naphelps/issue-581
Browse files Browse the repository at this point in the history
Issue 581 and 582
  • Loading branch information
naphelps authored Apr 22, 2022
2 parents 145972c + 4d1cbe5 commit 854bb9c
Show file tree
Hide file tree
Showing 11 changed files with 176 additions and 119 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,10 @@ Now you can disable root by setting `api.root.enabled` to `false` in `/etc/horiz
- detect if a pattern is updated with service that has userInput w/o default values, and give warning
- Consider changing all creates to POST, and update (via put/patch) return codes to 200

## Changes in 2.101.0
- Issue 581: Array order for versions maintained in the Exchange's DB and returned correctly when retrieved using a GET.
- Issue 582: Nodes, Agbots, Users, and Admin can now read resource changes for AgentFileVersions.

## Changes in 2.100.0
- Issue 572: All request body values are optional except for `scheduledTime`.
- Updated internationalization.
Expand Down
2 changes: 1 addition & 1 deletion docs/openapi-3-developer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"name" : "Apache License Version 2.0",
"url" : "https://www.apache.org/licenses/LICENSE-2.0"
},
"version" : "2.100.0"
"version" : "2.101.0"
},
"externalDocs" : {
"description" : "Open-horizon ExchangeAPI",
Expand Down
2 changes: 1 addition & 1 deletion docs/openapi-3-user.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"name" : "Apache License Version 2.0",
"url" : "https://www.apache.org/licenses/LICENSE-2.0"
},
"version" : "2.100.0"
"version" : "2.101.0"
},
"externalDocs" : {
"description" : "Open-horizon ExchangeAPI",
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.100.0
2.101.0
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ trait AgentConfigurationManagementRoutes extends JacksonSupport with Authenticat
lastUpdated = timestamp,
operation = ResChangeOperation.MODIFIED.toString,
orgId = "IBM",
public = "false",
resource = ResChangeResource.ORG.toString)
public = "true",
resource = ResChangeResource.AGENTFILEVERSION.toString)
software <- AgentSoftwareVersionsTQ.delete
} yield (certificate, changed, configuration, resource, software)

Expand Down Expand Up @@ -150,10 +150,10 @@ trait AgentConfigurationManagementRoutes extends JacksonSupport with Authenticat
db.run({
val versions: DBIOAction[(Seq[String], Seq[Timestamp], Seq[String], Seq[String]), NoStream, Effect.Read] =
for {
certificate <- AgentCertificateVersionsTQ.getAgentCertificateVersions("IBM").sortBy(_.desc).result
certificate <- AgentCertificateVersionsTQ.sortBy(_.priority.asc.nullsLast).filter(_.organization === "IBM").map(_.certificateVersion).result
changed <- AgentVersionsChangedTQ.getChanged("IBM").sortBy(_.desc).result
configuration <- AgentConfigurationVersionsTQ.getAgentConfigurationVersions("IBM").sortBy(_.desc).result
software <- AgentSoftwareVersionsTQ.getAgentSoftwareVersions("IBM").sortBy(_.desc).result
configuration <- AgentConfigurationVersionsTQ.sortBy(_.priority.asc.nullsLast).filter(_.organization === "IBM").map(_.configurationVersion).result
software <- AgentSoftwareVersionsTQ.sortBy(_.priority.asc.nullsLast).filter(_.organization === "IBM").map(_.softwareVersion).result
} yield (certificate, changed, configuration, software)

versions.transactionally.asTry}).map({
Expand Down Expand Up @@ -220,31 +220,22 @@ trait AgentConfigurationManagementRoutes extends JacksonSupport with Authenticat
def putAgentConfigMgmt: Route = (path("orgs" / Segment / "AgentFileVersion") & put & entity(as[AgentVersionsRequest])) { (orgId, reqBody) =>
exchAuth(TOrg("IBM"), Access.WRITE_AGENT_CONFIG_MGMT) { _ =>
complete({
val a: Seq[String] = reqBody.agentCertVersions
val b: Seq[String] = reqBody.agentConfigVersions
val c: Seq[String] = reqBody.agentSoftwareVersions
orgId match {
case "IBM" =>
db.run(
(AgentCertificateVersionsTQ.delete) andThen (AgentConfigurationVersionsTQ.delete) andThen (AgentSoftwareVersionsTQ.delete)
andThen (
AgentCertificateVersionsTQ ++= a.map(v => {(v, orgId)}))
andThen (
AgentConfigurationVersionsTQ ++= b.map(v => {(v, orgId)}))
andThen (
AgentSoftwareVersionsTQ ++= c.map(v => {(orgId, v)}))
andThen (
AgentVersionsChangedTQ
.insertOrUpdate(ApiTime.nowUTCTimestamp, orgId))
andThen (
ResourceChange(category = ResChangeCategory.ORG,
changeId = 0L,
id = orgId,
operation = ResChangeOperation.MODIFIED,
orgId = orgId,
public = false,
resource = ResChangeResource.ORG)
.insert)
db.run((AgentCertificateVersionsTQ.delete) andThen
(AgentConfigurationVersionsTQ.delete) andThen
(AgentSoftwareVersionsTQ.delete) andThen
(AgentCertificateVersionsTQ ++= reqBody.agentCertVersions.zipWithIndex.map(certificates => {(certificates._1, orgId, Option(certificates._2.toLong))})) andThen
(AgentConfigurationVersionsTQ ++= reqBody.agentConfigVersions.zipWithIndex.map(configurations => {(configurations._1, orgId, Option(configurations._2.toLong))})) andThen
(AgentSoftwareVersionsTQ ++= reqBody.agentSoftwareVersions.zipWithIndex.map(software => {(orgId, software._1, Option(software._2.toLong))})) andThen
(AgentVersionsChangedTQ.insertOrUpdate((ApiTime.nowUTCTimestamp, orgId))) andThen
(ResourceChange(category = ResChangeCategory.ORG,
changeId = 0L,
id = orgId,
operation = ResChangeOperation.MODIFIED,
orgId = orgId,
public = true,
resource = ResChangeResource.AGENTFILEVERSION).insert)
.transactionally.asTry.map({
case Success(v) =>
logger.debug("PUT /orgs/" + orgId + "/AgentFileVersion result: " + v)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,41 +26,47 @@ final case class AgentVersionsResponse(agentCertVersions: Seq[String],
lastUpdated: String) extends AgentVersions


class AgentCertificateVersions(tag: Tag) extends Table[(String, String)](tag, "agent_version_certificate") {
class AgentCertificateVersions(tag: Tag) extends Table[(String, String, Option[Long])](tag, "agent_version_certificate") {
def certificateVersion = column[String]("version")
def organization = column[String]("organization", O.Default("IBM"))
def priority = column[Option[Long]]("priority")

def * = (certificateVersion, organization)
def * = (certificateVersion, organization, priority)
def pkAgentVerCert = primaryKey("pk_agent_version_certificate", (organization, certificateVersion))
def fkOrg = foreignKey("fk_organization", organization, OrgsTQ)(_.orgid, onUpdate=ForeignKeyAction.Cascade, onDelete=ForeignKeyAction.Cascade)
def idxPriority = index("idx_avcert_priority", (organization, priority), unique = true)
}

object AgentCertificateVersionsTQ extends TableQuery(new AgentCertificateVersions(_)) {
def getAgentCertificateVersions(organization: String): Query[Rep[String], String, Seq] = this.filter(_.organization === organization).map(_.certificateVersion)
}


class AgentConfigurationVersions(tag: Tag) extends Table[(String, String)](tag, "agent_version_configuration") {
class AgentConfigurationVersions(tag: Tag) extends Table[(String, String, Option[Long])](tag, "agent_version_configuration") {
def configurationVersion = column[String]("version")
def organization = column[String]("organization", O.Default("IBM"))
def priority = column[Option[Long]]("priority")

def * = (configurationVersion, organization)
def * = (configurationVersion, organization, priority)
def pkAgentVerConfig = primaryKey("pk_agent_version_configuration", (organization, configurationVersion))
def fkOrg = foreignKey("fk_organization", organization, OrgsTQ)(_.orgid, onUpdate=ForeignKeyAction.Cascade, onDelete=ForeignKeyAction.Cascade)
def idxPriority = index("idx_avconfig_priority", (organization, priority), unique = true)
}

object AgentConfigurationVersionsTQ extends TableQuery(new AgentConfigurationVersions(_)) {
def getAgentConfigurationVersions(organization: String): Query[Rep[String], String, Seq] = this.filter(_.organization === organization).map(_.configurationVersion)
}


class AgentSoftwareVersions(tag: Tag) extends Table[(String, String)](tag, "agent_version_software") {
class AgentSoftwareVersions(tag: Tag) extends Table[(String, String, Option[Long])](tag, "agent_version_software") {
def organization = column[String]("organization", O.Default("IBM"))
def softwareVersion = column[String]("version")
def priority = column[Option[Long]]("priority")

def * = (organization, softwareVersion)
def * = (organization, softwareVersion, priority)
def pkAgentVerSoft = primaryKey("pk_agent_version_software", (organization, softwareVersion))
def fkOrg = foreignKey("fk_organization", organization, OrgsTQ)(_.orgid, onUpdate=ForeignKeyAction.Cascade, onDelete=ForeignKeyAction.Cascade)
def idxPriority = index("idx_avsoft_priority", (organization, priority), unique = true)
}

object AgentSoftwareVersionsTQ extends TableQuery(new AgentSoftwareVersions(_)) {
Expand Down
12 changes: 6 additions & 6 deletions src/main/scala/com/horizon/exchangeapi/tables/Orgs.scala
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package com.horizon.exchangeapi.tables

import java.sql.Timestamp

import org.json4s._
import org.json4s.jackson.Serialization.read
import org.json4s.jackson.Serialization.write
import slick.dbio.Effect
import slick.sql.FixedSqlAction

import com.horizon.exchangeapi.{ApiUtils,ApiTime}
import com.horizon.exchangeapi.{ApiTime, ApiUtils}
import com.horizon.exchangeapi.tables.ExchangePostgresProfile.api._
import com.horizon.exchangeapi.tables.ResChangeCategory.Value


/** Contains the object representations of the DB tables related to orgs. */
Expand Down Expand Up @@ -102,12 +101,12 @@ final case class Org(orgType: String, label: String, description: String, lastUp
/** Contains the object representations of the DB tables related to resource changes. */
object ResChangeCategory extends Enumeration {
type ResChangeCategory = Value
val ORG: ResChangeCategory.Value = Value("org")
val AGBOT: ResChangeCategory.Value = Value("agbot")
val NODE: ResChangeCategory.Value = Value("node")
val POLICY: ResChangeCategory.Value = Value("policy")
val MGMTPOLICY: ResChangeCategory.Value = Value("mgmtpolicy")
val NODE: ResChangeCategory.Value = Value("node")
val ORG: ResChangeCategory.Value = Value("org")
val PATTERN: ResChangeCategory.Value = Value("pattern")
val POLICY: ResChangeCategory.Value = Value("policy")
val SERVICE: ResChangeCategory.Value = Value("service")
}
import com.horizon.exchangeapi.tables.ResChangeCategory._
Expand All @@ -119,6 +118,7 @@ object ResChangeResource extends Enumeration {
val AGBOTBUSINESSPOLS: ResChangeResource.Value = Value("agbotbusinesspols")
val AGBOTMSGS: ResChangeResource.Value = Value("agbotmsgs")
val AGBOTPATTERNS: ResChangeResource.Value = Value("agbotpatterns")
val AGENTFILEVERSION: ResChangeResource.Value = Value("agentfileversion")
val NODE: ResChangeResource.Value = Value("node")
val NODEAGREEMENTS: ResChangeResource.Value = Value("nodeagreements")
val NODEERRORS: ResChangeResource.Value = Value("nodeerrors")
Expand Down
14 changes: 11 additions & 3 deletions src/main/scala/com/horizon/exchangeapi/tables/Schema.scala
Original file line number Diff line number Diff line change
Expand Up @@ -204,21 +204,29 @@ object SchemaTQ extends TableQuery(new SchemaTable(_)){
AgentSoftwareVersionsTQ.schema.create,
AgentVersionsChangedTQ.schema.create
)
case 47 => DBIO.seq( // v2..0
case 47 => DBIO.seq( // v2.100.0
sqlu"ALTER TABLE management_policy_status_node ALTER COLUMN time_start_actual DROP NOT NULL",
sqlu"ALTER TABLE management_policy_status_node ALTER COLUMN version_certificate DROP NOT NULL",
sqlu"ALTER TABLE management_policy_status_node ALTER COLUMN version_configuration DROP NOT NULL",
sqlu"ALTER TABLE management_policy_status_node ALTER COLUMN time_end DROP NOT NULL",
sqlu"ALTER TABLE management_policy_status_node ALTER COLUMN error_message DROP NOT NULL",
sqlu"ALTER TABLE management_policy_status_node ALTER COLUMN version_software DROP NOT NULL",
sqlu"ALTER TABLE management_policy_status_node ALTER COLUMN status DROP NOT NULL"
)
case 48 => DBIO.seq( // v2.101.0
sqlu"ALTER TABLE agent_version_certificate ADD COLUMN IF NOT EXISTS priority bigint NULL;",
sqlu"ALTER TABLE agent_version_configuration ADD COLUMN IF NOT EXISTS priority bigint NULL;",
sqlu"ALTER TABLE agent_version_software ADD COLUMN IF NOT EXISTS priority bigint NULL;",
sqlu"CREATE UNIQUE INDEX IF NOT EXISTS idx_avcert_priority ON agent_version_certificate (organization, priority);",
sqlu"CREATE UNIQUE INDEX IF NOT EXISTS idx_avconfig_priority ON agent_version_configuration (organization, priority);",
sqlu"""CREATE UNIQUE INDEX IF NOT EXISTS idx_avsoft_priority ON agent_version_software ("version", priority);"""
)
case other => logger.error("getUpgradeSchemaStep was given invalid step "+other); DBIO.seq() // should never get here
}
}

val latestSchemaVersion = 47 // NOTE: THIS MUST BE CHANGED WHEN YOU ADD TO getUpgradeSchemaStep() above
val latestSchemaDescription = "adding deployment, management, nodepolicyversion columns to nodepolicies table"
val latestSchemaVersion: Int = 48 // NOTE: THIS MUST BE CHANGED WHEN YOU ADD TO getUpgradeSchemaStep() above
val latestSchemaDescription: String = "adding deployment, management, nodepolicyversion columns to nodepolicies table"
// Note: if you need to manually set the schema number in the db lower: update schema set schemaversion = 12 where id = 0;

def isLatestSchemaVersion(fromSchemaVersion: Int): Boolean = fromSchemaVersion >= latestSchemaVersion
Expand Down
Loading

0 comments on commit 854bb9c

Please sign in to comment.