Plan and execute Guidewire InsuranceSuite version upgrades and migrations between self-managed and cloud environments.
typescript
// Breaking change analysis script
interface BreakingChange {
version: string;
category: 'API' | 'Gosu' | 'Database' | 'Configuration';
description: string;
impact: 'High' | 'Medium' | 'Low';
migration: string;
}
const breakingChanges: BreakingChange[] = [
{
version: '2024.03',
category: 'API',
description: 'Deprecated endpoints removed from Cloud API',
impact: 'High',
migration: 'Update to new endpoint paths - see migration guide'
},
{
version: '2024.03',
category: 'Gosu',
description: 'Query API syntax changes for complex joins',
impact: 'Medium',
migration: 'Update Query.make() calls with new join syntax'
},
{
version: '2024.01',
category: 'Database',
description: 'Column type changes for monetary amounts',
impact: 'High',
migration: 'Run provided migration script before upgrade'
}
];
function analyzeImpact(currentVersion: string, targetVersion: string): void {
const applicableChanges = breakingChanges.filter(change => {
return compareVersions(change.version, currentVersion) > 0 &&
compareVersions(change.version, targetVersion) <= 0;
});
console.log('=== Breaking Changes Analysis ===');
console.log(`From: ${currentVersion} To: ${targetVersion}`);
console.log(`Total breaking changes: ${applicableChanges.length}`);
const byCategory = applicableChanges.reduce((acc, change) => {
acc[change.category] = acc[change.category] || [];
acc[change.category].push(change);
return acc;
}, {} as Record<string, BreakingChange[]>);
Object.entries(byCategory).forEach(([category, changes]) => {
console.log(`\n${category}:`);
changes.forEach(change => {
console.log(` [${change.impact}] ${change.description}`);
console.log(` Migration: ${change.migration}`);
});
});
}
groovy
// build.gradle - Database upgrade tasks
tasks.register('backupDatabase') {
doLast {
exec {
commandLine 'pg_dump', '-h', dbHost, '-U', dbUser,
'-d', dbName, '-F', 'c',
'-f', "backup-${dbName}-${new Date().format('yyyyMMdd-HHmmss')}.dump"
}
}
}
tasks.register('upgradeDatabase') {
dependsOn 'backupDatabase'
doLast {
// Run Guidewire database upgrade
exec {
commandLine './gradlew', 'dbupgrade',
"-PdbHost=${dbHost}",
"-PdbName=${dbName}",
"-PdbUser=${dbUser}",
"-PdbPassword=${dbPassword}"
}
}
}
tasks.register('validateDatabaseUpgrade') {
dependsOn 'upgradeDatabase'
doLast {
// Verify schema version
def result = exec {
commandLine 'psql', '-h', dbHost, '-U', dbUser, '-d', dbName,
'-c', 'SELECT version FROM schema_version ORDER BY id DESC LIMIT 1'
standardOutput = new ByteArrayOutputStream()
}
println "Current schema version: ${result.standardOutput}"
}
}
gosu
// Automated code migration helpers
package gw.migration
uses gw.api.util.Logger
class CodeMigrationHelper {
private static final var LOG = Logger.forCategory("Migration")
// Replace deprecated API calls
static function migrateDeprecatedAPIs(code : String) : String {
var migrated = code
// Example: Migrate old Query syntax
migrated = migrated.replaceAll(
"Query\\.make\\(([^)]+)\\)\\.withEqual",
"Query.make($1).compare"
)
// Example: Migrate old date handling
migrated = migrated.replaceAll(
"new Date\\(\\)",
"Date.Today"
)
// Example: Migrate deprecated methods
migrated = migrated.replaceAll(
"\\.getBundle\\(\\)",
".Bundle"
)
return migrated
}
// Check for deprecated patterns
static function findDeprecatedPatterns(code : String) : List<String> {
var issues = new ArrayList<String>()
var patterns = {
"deprecated_query" -> "Query.make.*withEqual",
"old_date" -> "new java.util.Date\\(\\)",
"string_concat_in_query" -> "\"SELECT.*\\+.*\\+",
"deprecated_session" -> "SessionInfo.getCurrentSession"
}
patterns.eachKeyAndValue(\name, pattern -> {
if (code.matches(".*${pattern}.*")) {
issues.add("Found deprecated pattern: ${name}")
}
})
return issues
}
}
typescript
// API version migration
interface EndpointMigration {
oldPath: string;
newPath: string;
changes: string[];
}
const endpointMigrations: EndpointMigration[] = [
{
oldPath: '/account/v1/accounts/{id}/policies',
newPath: '/account/v1/accounts/{id}/active-policies',
changes: ['Path renamed', 'Only returns in-force policies']
},
{
oldPath: '/job/v1/submissions/{id}/quote',
newPath: '/job/v1/submissions/{id}/actions/quote',
changes: ['Moved to actions sub-resource']
}
];
function migrateApiCalls(code: string, fromVersion: string, toVersion: string): string {
let migratedCode = code;
endpointMigrations.forEach(migration => {
const oldPattern = new RegExp(
migration.oldPath.replace(/\{[^}]+\}/g, '[^/]+'),
'g'
);
if (oldPattern.test(migratedCode)) {
console.log(`Migrating: ${migration.oldPath} -> ${migration.newPath}`);
console.log(` Changes: ${migration.changes.join(', ')}`);
migratedCode = migratedCode.replace(
migration.oldPath,
migration.newPath
);
}
});
return migratedCode;
}
gosu
// Migration test suite
package gw.migration.test
uses gw.testharness.v3.PLTestCase
uses gw.testharness.v3.PLAssert
class MigrationTestSuite extends PLTestCase {
function testQueryAPICompatibility() {
// Test new Query API syntax works
var accounts = Query.make(Account)
.compare(Account#AccountStatus, Equals, AccountStatus.TC_ACTIVE)
.select()
.toList()
PLAssert.assertNotNull(accounts)
}
function testEntityExtensions() {
// Verify custom entity extensions still work
var policy = createTestPolicy()
policy.CustomField_Ext = "Test Value"
policy.Bundle.commit()
var loaded = Query.make(Policy)
.compare(Policy#ID, Equals, policy.ID)
.select()
.AtMostOneRow
PLAssert.assertEquals("Test Value", loaded.CustomField_Ext)
}
function testIntegrationEndpoints() {
// Verify integration endpoints respond correctly
var client = new ExternalServiceClient()
var response = client.healthCheck()
PLAssert.assertTrue(response.isHealthy())
}
function testDataMigration() {
// Verify migrated data integrity
var count = Query.make(Account).select().Count
PLAssert.assertTrue(count > 0, "Expected migrated accounts")
}
}
For CI/CD integration, see
.