<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.2.xsd"
                   logicalFilePath="upgrade_8.3.00.xml">
    <changeSet author="gateway" id="update_ssg_version">
        <update tableName="ssg_version">
            <column name="current_version" value="8.3.00"/>
        </update>
        <rollback>
            <update tableName="ssg_version">
                <column name="current_version" value="8.3.pre"/>
            </update>
        </rollback>
    </changeSet>
    <changeSet id="remove_next_hi_function" author="gateway">
        <sql dbms="mysql">DROP FUNCTION next_hi</sql>
        <rollback>
            <createProcedure dbms="mysql"
                             procedureName="next_hi">
                CREATE FUNCTION next_hi() RETURNS bigint NOT DETERMINISTIC MODIFIES SQL DATA SQL SECURITY INVOKER
                BEGIN
                UPDATE hibernate_unique_key SET next_hi=last_insert_id(next_hi)+IF(@@global.server_id=0,1,2);
                RETURN IF((last_insert_id()%2=0 and @@global.server_id=1) or (last_insert_id()%2=1 and @@global.server_id=2),last_insert_id()+1,last_insert_id());
                END
            </createProcedure>
        </rollback>
    </changeSet>
    <changeSet id="remove_hibernate_unique_key_table" author="gateway" dbms="mysql">
        <dropTable tableName="hibernate_unique_key"/>
        <rollback>
            <createTable tableName="hibernate_unique_key">
                <column name="next_hi" type="INT(11)">
                    <constraints nullable="true"/>
                </column>
            </createTable>
            <insert tableName="hibernate_unique_key">
                <column name="next_hi" valueNumeric="1"/>
            </insert>
        </rollback>
    </changeSet>
    <changeSet id="update_manage_siteminder_configuration_role" author="gateway">
        <comment>Update SiteMinder Configuration</comment>
        <update tableName="rbac_role">
            <column name="name" value="Manage CA Single Sign-On Configuration"/>
            <column name="description" value="Users assigned to the {0} role have the ability to read, create, update and delete CA Single Sign-On configuration."/>
            <where>entity_type = 'SITEMINDER_CONFIGURATION'</where>
        </update>
        <rollback>
            <update tableName="rbac_role">
                <column name="name" value="Manage SiteMinder Configuration"/>
                <column name="description" value="Users assigned to the {0} role have the ability to read, create, update and delete SiteMinder configuration."/>
                <where>entity_type = 'SITEMINDER_CONFIGURATION'</where>
            </update>
        </rollback>
    </changeSet>
    <changeSet id="introduce_policy_backed_services" author="gateway" failOnError="false">
        <validCheckSum>8:1e71ffad4fd1a38817b3cad66e181d92</validCheckSum>
        <preConditions onFail="MARK_RAN" onSqlOutput="TEST">
            <not>
                <columnExists tableName="policy" columnName="internal_sub_tag"/>
            </not>
        </preConditions>
        <comment>Adds subtags to the policy table, and introduces the policy_backed_service and policy_backed_service_operation tables</comment>
        <addColumn tableName="policy">
            <column name="internal_sub_tag" type="VARCHAR(255)"/>
        </addColumn>
        <modifyDataType tableName="policy" columnName="internal_tag" newDataType="VARCHAR(255)"/>
        <rollback>
            <modifyDataType tableName="policy" columnName="internal_tag" newDataType="VARCHAR(64)"/>
        </rollback>
    </changeSet>
    <changeSet id="add_policy_backed_service_table" author="gateway" failOnError="false">
        <preConditions onFail="MARK_RAN" onSqlOutput="TEST">
            <not>
                <tableExists tableName="policy_backed_service"/>
            </not>
        </preConditions>
        <createTable tableName="policy_backed_service">
            <column name="goid" type="${goid.type}">
                <constraints nullable="false" primaryKey="true"/>
            </column>
            <column name="version" type="INT(10)">
                <constraints nullable="false"/>
            </column>
            <column name="name" type="VARCHAR(255)">
                <constraints nullable="false" unique="true"/>
            </column>
            <column name="interface_name" type="VARCHAR(255)">
                <constraints nullable="false"/>
            </column>
            <column name="security_zone_goid" type="${goid.type}"/>
        </createTable>
        <rollback>
            <dropTable tableName="policy_backed_service"/>
        </rollback>
        <modifySql dbms="mysql">
            <append value="ENGINE=INNODB CHARSET=utf8mb3 COLLATE utf8mb3_general_ci"/>
        </modifySql>
    </changeSet>
    <changeSet id="policy_backed_service_fk" author="gateway" failOnError="false">
        <preConditions onFail="MARK_RAN" onSqlOutput="TEST">
            <not>
                <foreignKeyConstraintExists foreignKeyTableName="policy_backed_service" foreignKeyName="policy_backed_service_security_zone" />
            </not>
        </preConditions>
        <addForeignKeyConstraint baseTableName="policy_backed_service" baseColumnNames="security_zone_goid" constraintName="policy_backed_service_security_zone" deferrable="false" initiallyDeferred="false" onDelete="SET NULL" onUpdate="NO ACTION" referencedColumnNames="goid" referencedTableName="security_zone"/>
        <rollback>
            <dropForeignKeyConstraint baseTableName="policy_backed_service" constraintName="policy_backed_service_security_zone"/>
        </rollback>
    </changeSet>
    <changeSet id="add_policy_backed_service_operation" author="gateway" failOnError="false">
        <preConditions onFail="MARK_RAN" onSqlOutput="TEST">
            <not>
                <tableExists tableName="policy_backed_service_operation" />
            </not>
        </preConditions>
        <createTable tableName="policy_backed_service_operation">
            <column name="goid" type="${goid.type}">
                <constraints nullable="false" primaryKey="true"/>
            </column>
            <column name="version" type="INT(10)">
                <constraints nullable="false"/>
            </column>
            <column name="name" type="VARCHAR(255)">
            </column>
            <column name="policy_backed_service_goid" type="${goid.type}">
                <constraints nullable="false" references="policy_backed_service(goid)" foreignKeyName="fk_pbs_operation_pbs_service"/>
            </column>
            <column name="policy_goid" type="${goid.type}">
                <constraints references="policy(goid)" foreignKeyName="fk_pbs_operation_policy" deleteCascade="true"/>
            </column>
        </createTable>
        <rollback>
            <dropTable tableName="policy_backed_service_operation"/>
        </rollback>
        <modifySql dbms="mysql">
            <append value="ENGINE=INNODB CHARSET=utf8mb3 COLLATE utf8mb3_general_ci"/>
        </modifySql>
    </changeSet>
    <changeSet id="add_policy_backed_service_operation_fk" author="gateway" failOnError="false">
        <preConditions onFail="MARK_RAN" onSqlOutput="TEST">
            <not>
                <indexExists tableName="policy_backed_service_operation" indexName="i_pbs_operation_goid_name" />
            </not>
        </preConditions>
        <addUniqueConstraint tableName="policy_backed_service_operation" columnNames="policy_backed_service_goid, name" constraintName="i_pbs_operation_goid_name"/>
        <rollback>
            <dropUniqueConstraint tableName="policy_backed_service_operation" constraintName="i_pbs_operation_goid_name" />
        </rollback>
    </changeSet>
    <changeSet id="add_cassandra_connection_table" author="gateway">
        <validCheckSum>8:64c2f36b452ec5dd937784c4982f9873</validCheckSum>
        <createTable tableName="cassandra_connection">
            <column name="goid" type="${goid.type}">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="version" type="INT(10)">
                <constraints nullable="false"/>
            </column>
            <column name="name" type="VARCHAR(128)">
                <constraints nullable="false"/>
            </column>
            <column name="keyspace_name" type="VARCHAR(255)">
                <constraints nullable="false"/>
            </column>
            <column name="contact_points" type="VARCHAR(4096)">
                <constraints nullable="false"/>
            </column>
            <column name="port" type="VARCHAR(255)">
                <constraints nullable="false"/>
            </column>
            <column name="username" type="VARCHAR(255)">
                <constraints nullable="false"/>
            </column>
            <column name="password_goid" type="${goid.type}"/>
            <column name="compression" type="VARCHAR(255)">
                <constraints nullable="false"/>
            </column>
            <column name="use_ssl" type="${tinyint.type}" defaultValueNumeric="0">
                <constraints nullable="false"/>
            </column>
			<column name="enabled" type="${tinyint.type}" defaultValueNumeric="1">
                <constraints nullable="false"/>
            </column>
            <column name="${properties.column.name}" type="${mediumtext.type}"/>
            <column name="security_zone_goid" type="${goid.type}"/>
        </createTable>
        <modifySql dbms="mysql">
            <append value="ENGINE=INNODB CHARSET=utf8mb3 COLLATE utf8mb3_general_ci"/>
        </modifySql>
    </changeSet>
	<changeSet id="create-index-cassandra-connection-name" author="gateway">
        <createIndex indexName="index_cassandra_connection_name" tableName="cassandra_connection" unique="true">
            <column name="name"/>
        </createIndex>
    </changeSet>
    <changeSet id="add-fk-cassandra-connection-security-zone" author="gateway">
        <addForeignKeyConstraint baseTableName="cassandra_connection" baseColumnNames="security_zone_goid"
                                 constraintName="cassandra_connection_security_zone" referencedTableName="security_zone"
                                 referencedColumnNames="goid" onDelete="SET NULL" onUpdate="NO ACTION"/>
    </changeSet>
	<changeSet id="create-manage-cassandra-connection-role" author="gateway">
        <comment>Manage Cassandra Configuration</comment>
        <insert tableName="rbac_role">
            <column name="goid" valueComputed="toGoid(0, -1600)"/>
            <column name="version" valueNumeric="0"/>
            <column name="name" value="Manage Cassandra Connection"/>
            <column name="tag"/>
            <column name="entity_type" value="CASSANDRA_CONFIGURATION"/>
            <column name="entity_goid"/>
            <column name="description" value="Users assigned to the {0} role have the ability to read, create, update and delete Cassandra connection."/>
            <column name="user_created" valueComputed="${false}"/>
        </insert>
        <insert tableName="rbac_permission">
            <column name="goid" valueComputed="toGoid(0, -1601)"/>
            <column name="version" valueNumeric="0"/>
            <column name="role_goid" valueComputed="toGoid(0, -1600)"/>
            <column name="operation_type" value="READ"/>
            <column name="other_operation"/>
            <column name="entity_type" value="CASSANDRA_CONFIGURATION"/>
        </insert>
        <insert tableName="rbac_permission">
            <column name="goid" valueComputed="toGoid(0, -1602)"/>
            <column name="version" valueNumeric="0"/>
            <column name="role_goid" valueComputed="toGoid(0, -1600)"/>
            <column name="operation_type" value="CREATE"/>
            <column name="other_operation"/>
            <column name="entity_type" value="CASSANDRA_CONFIGURATION"/>
        </insert>
        <insert tableName="rbac_permission">
            <column name="goid" valueComputed="toGoid(0, -1603)"/>
            <column name="version" valueNumeric="0"/>
            <column name="role_goid" valueComputed="toGoid(0, -1600)"/>
            <column name="operation_type" value="UPDATE"/>
            <column name="other_operation"/>
            <column name="entity_type" value="CASSANDRA_CONFIGURATION"/>
        </insert>
        <insert tableName="rbac_permission">
            <column name="goid" valueComputed="toGoid(0, -1604)"/>
            <column name="version" valueNumeric="0"/>
            <column name="role_goid" valueComputed="toGoid(0, -1600)"/>
            <column name="operation_type" value="DELETE"/>
            <column name="other_operation"/>
            <column name="entity_type" value="CASSANDRA_CONFIGURATION"/>
        </insert>
        <insert tableName="rbac_permission">
            <column name="goid" valueComputed="toGoid(0, -1605)"/>
            <column name="version" valueNumeric="0"/>
            <column name="role_goid" valueComputed="toGoid(0, -1600)"/>
            <column name="operation_type" value="READ"/>
            <column name="other_operation"/>
            <column name="entity_type" value="SECURE_PASSWORD"/>
        </insert>
    </changeSet>
    <changeSet id="create-ssl-columns" author="gateway">
        <addColumn tableName="cassandra_connection">
            <column name="tls_protocol" type="VARCHAR(128)" defaultValue="TLSv1"/>
            <column name="tls_ciphers" type="${mediumtext.type}"/>
        </addColumn>
    </changeSet>
    <changeSet id="create_server_module_file_tables" author="gateway">
        <validCheckSum>8:0e58df9b98100876fb268bbadbb0fe92</validCheckSum>
        <comment>Introduces Server Module File tables (server_module_file, server_module_file_data and server_module_file_state)</comment>
        <createTable tableName="server_module_file_data">
            <column name="goid" type="${goid.type}">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="version" type="INT(10)">
                <constraints nullable="false"/>
            </column>
            <column name="data_bytes" type="${longblob.type}">
                <constraints nullable="false"/>
            </column>
        </createTable>
        <createTable tableName="server_module_file">
            <column name="goid" type="${goid.type}">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="version" type="INT(10)">
                <constraints nullable="false"/>
            </column>
            <column name="name" type="VARCHAR(128)">
                <constraints nullable="false"/>
            </column>
            <column name="module_type" type="VARCHAR(64)">
                <constraints nullable="false"/>
            </column>
            <column name="module_sha256" type="VARCHAR(255)">
                <constraints nullable="false" unique="true"/>
            </column>
            <column name="${properties.column.name}" type="${mediumtext.type}"/>
            <column name="data_goid" type="${goid.type}">
                <constraints nullable="false" references="server_module_file_data(goid)" foreignKeyName="fk_server_module_file_data" deleteCascade="true"/>
            </column>
        </createTable>
        <createTable tableName="server_module_file_state">
            <column name="goid" type="${goid.type}">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="version" type="INT(10)">
                <constraints nullable="false"/>
            </column>
            <column name="node_id" type="VARCHAR(36)">
                <constraints nullable="false"/>
            </column>
            <column name="${state.column.name}" type="VARCHAR(64)">
                <constraints nullable="false"/>
            </column>
            <column name="error_message" type="${mediumtext.type}"/>
            <column name="module_goid" type="${goid.type}">
                <constraints nullable="false" references="server_module_file(goid)" foreignKeyName="fk_server_module_file_state" deleteCascade="true"/>
            </column>
        </createTable>
        <rollback>
            <delete tableName="server_module_file_data"/>
            <delete tableName="server_module_file"/>
            <dropTable tableName="server_module_file_state"/>
            <dropTable tableName="server_module_file"/>
            <dropTable tableName="server_module_file_data"/>
        </rollback>
        <modifySql dbms="mysql">
            <append value="ENGINE=INNODB CHARSET=utf8mb3 COLLATE utf8mb3_general_ci"/>
        </modifySql>
    </changeSet>
    <changeSet id="create_server_module_file_role" author="gateway">
        <comment>Manage Server Module File Roles</comment>
        <insert tableName="rbac_role">
            <column name="goid" valueComputed="toGoid(0, -1650)"/>
            <column name="version" valueNumeric="0"/>
            <column name="name" value="Manage Modules Installable via Policy Manager"/>
            <column name="tag"/>
            <column name="entity_type" value="SERVER_MODULE_FILE"/>
            <column name="entity_goid"/>
            <column name="description" value="Users assigned to the {0} role have the ability to read, create, update and delete Modules Installable via Policy Manager."/>
            <column name="user_created" valueComputed="${false}"/>
        </insert>
        <insert tableName="rbac_permission">
            <column name="goid" valueComputed="toGoid(0, -1651)"/>
            <column name="version" valueNumeric="0"/>
            <column name="role_goid" valueComputed="toGoid(0, -1650)"/>
            <column name="operation_type" value="READ"/>
            <column name="other_operation"/>
            <column name="entity_type" value="SERVER_MODULE_FILE"/>
        </insert>
        <insert tableName="rbac_permission">
            <column name="goid" valueComputed="toGoid(0, -1652)"/>
            <column name="version" valueNumeric="0"/>
            <column name="role_goid" valueComputed="toGoid(0, -1650)"/>
            <column name="operation_type" value="CREATE"/>
            <column name="other_operation"/>
            <column name="entity_type" value="SERVER_MODULE_FILE"/>
        </insert>
        <insert tableName="rbac_permission">
            <column name="goid" valueComputed="toGoid(0, -1653)"/>
            <column name="version" valueNumeric="0"/>
            <column name="role_goid" valueComputed="toGoid(0, -1650)"/>
            <column name="operation_type" value="UPDATE"/>
            <column name="other_operation"/>
            <column name="entity_type" value="SERVER_MODULE_FILE"/>
        </insert>
        <insert tableName="rbac_permission">
            <column name="goid" valueComputed="toGoid(0, -1654)"/>
            <column name="version" valueNumeric="0"/>
            <column name="role_goid" valueComputed="toGoid(0, -1650)"/>
            <column name="operation_type" value="DELETE"/>
            <column name="other_operation"/>
            <column name="entity_type" value="SERVER_MODULE_FILE"/>
        </insert>
        <insert tableName="rbac_permission">
            <column name="goid" valueComputed="toGoid(0, -1655)"/>
            <column name="version" valueNumeric="0"/>
            <column name="role_goid" valueComputed="toGoid(0, -1650)"/>
            <column name="operation_type" value="READ"/>
            <column name="other_operation"/>
            <column name="entity_type" value="CLUSTER_PROPERTY"/>
        </insert>
        <insert tableName="rbac_permission">
            <column name="goid" valueComputed="toGoid(0, -1656)"/>
            <column name="version" valueNumeric="0"/>
            <column name="role_goid" valueComputed="toGoid(0, -1650)"/>
            <column name="operation_type" value="READ"/>
            <column name="other_operation"/>
            <column name="entity_type" value="CLUSTER_PROPERTY"/>
        </insert>
        <insert tableName="rbac_predicate">
            <column name="goid" valueComputed="toGoid(0, -1655)"/>
            <column name="version" valueNumeric="0"/>
            <column name="permission_goid" valueComputed="toGoid(0, -1655)"/>
        </insert>
        <insert tableName="rbac_predicate_attribute">
            <column name="goid" valueComputed="toGoid(0, -1655)"/>
            <column name="attribute" value="name"/>
            <column name="${value.column.name}" value="serverModuleFile.upload.enable"/>
            <column name="mode" value="eq"/>
        </insert>
        <insert tableName="rbac_predicate">
            <column name="goid" valueComputed="toGoid(0, -1656)"/>
            <column name="version" valueNumeric="0"/>
            <column name="permission_goid" valueComputed="toGoid(0, -1656)"/>
        </insert>
        <insert tableName="rbac_predicate_attribute">
            <column name="goid" valueComputed="toGoid(0, -1656)"/>
            <column name="attribute" value="name"/>
            <column name="${value.column.name}" value="serverModuleFile.upload.maxSize"/>
            <column name="mode" value="eq"/>
        </insert>
        <insert tableName="rbac_permission">
            <column name="goid" valueComputed="toGoid(0, -1657)"/>
            <column name="version" valueNumeric="0"/>
            <column name="role_goid" valueComputed="toGoid(0, -1650)"/>
            <column name="operation_type" value="READ"/>
            <column name="other_operation"/>
            <column name="entity_type" value="CLUSTER_INFO"/>
        </insert>
        <rollback>
            <delete tableName="rbac_role">
                <where>goid = toGoid(0, -1650)</where>
            </delete>
        </rollback>
    </changeSet>
    <changeSet id="delete-ssl-protocol-column" author="gateway">
        <dropColumn tableName="cassandra_connection" columnName="tls_protocol"/>
    </changeSet>
</databaseChangeLog>
