Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 581 and 582 #583

Merged
merged 3 commits into from
Apr 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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