| name | guidewire-migration-deep-dive |
| description | Deep dive into Guidewire migration strategies including self-managed to Cloud,
legacy system migrations, data migration, and integration cutover planning.
Trigger with phrases like "guidewire migration", "cloud migration",
"legacy migration", "data migration guidewire", "cutover planning".
|
| allowed-tools | Read, Write, Edit, Bash(curl:*), Bash(gradle:*), Grep |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
Guidewire Migration Deep Dive
Overview
Comprehensive guide for Guidewire migrations including self-managed to Cloud migrations, legacy system replacements, data migrations, and integration cutover strategies.
Prerequisites
- Understanding of current system architecture
- Access to source and target environments
- Stakeholder alignment on migration scope
- Detailed inventory of customizations
Migration Types
| Migration Type | Description | Complexity | Timeline |
|---|
| Version Upgrade | Same platform, new version | Low-Medium | 3-6 months |
| Cloud Migration | Self-managed to Guidewire Cloud | Medium-High | 6-12 months |
| Platform Replacement | Legacy to Guidewire | High | 12-24 months |
| Consolidation | Multiple systems to one | High | 12-18 months |
Migration Phases
┌─────────────────────────────────────────────────────────────────────────────────┐
│ Migration Lifecycle │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ Phase 1 Phase 2 Phase 3 Phase 4 Phase 5 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ ASSESS │──▶│ PLAN │──▶│ BUILD │──▶│ MIGRATE │──▶│OPTIMIZE │ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ 4-6 wks │ │ 4-8 wks │ │12-20 wks│ │ 4-8 wks │ │ 8-12 wks│ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
│ │ │ │ │ │ │
│ ▼ ▼ ▼ ▼ ▼ │
│ • Discovery • Roadmap • Config • Data • Performance │
│ • Inventory • Resources • Testing • Cutover • Tuning │
│ • Risk • Timeline • Integration • Validation • Documentation │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
Instructions
Step 1: Assessment and Discovery
interface AssessmentResult {
customizations: CustomizationInventory;
integrations: IntegrationInventory;
dataVolume: DataVolumeAnalysis;
risks: Risk[];
recommendations: Recommendation[];
}
interface CustomizationInventory {
gosuFiles: number;
pcfFiles: number;
entityExtensions: number;
plugins: number;
customRules: number;
estimatedEffort: string;
}
class MigrationAssessment {
async assess(sourceEnvironment: string): Promise<AssessmentResult> {
console.log('Starting migration assessment...');
const customizations = await this.inventoryCustomizations(sourceEnvironment);
const integrations = await this.inventoryIntegrations(sourceEnvironment);
const dataVolume = await this.(sourceEnvironment);
risks = .(customizations, integrations, dataVolume);
recommendations = .(risks);
{
customizations,
integrations,
dataVolume,
risks,
recommendations
};
}
(: ): <> {
gosuFiles = .(env, );
pcfFiles = .(env, );
entityExtensions = .(env, );
plugins = .(env);
customRules = .(env);
estimatedEffort = .(
gosuFiles, pcfFiles, entityExtensions, plugins, customRules
);
{
gosuFiles,
pcfFiles,
entityExtensions,
plugins,
customRules,
estimatedEffort
};
}
(: ): <> {
{
: .(env),
: .(env),
: .(env),
: .(env)
};
}
(
: ,
: ,
:
): [] {
: [] = [];
(customizations. > ) {
risks.({
: ,
: ,
: ,
:
});
}
(integrations. > ) {
risks.({
: ,
: ,
: ,
:
});
}
(dataVolume. > ) {
risks.({
: ,
: ,
: ,
:
});
}
risks;
}
}
Step 2: Data Migration Planning
interface DataMigrationPlan {
phases: MigrationPhase[];
totalRecords: number;
estimatedDuration: string;
rollbackStrategy: RollbackStrategy;
}
interface MigrationPhase {
name: string;
entities: EntityMigration[];
sequence: number;
dependencies: string[];
estimatedDuration: string;
}
interface EntityMigration {
sourceEntity: string;
targetEntity: string;
recordCount: number;
transformations: Transformation[];
validations: Validation[];
}
class DataMigrationPlanner {
createPlan(assessment: AssessmentResult): DataMigrationPlan {
const phases: MigrationPhase[] = [
{
name: 'Reference Data',
sequence: 1,
dependencies: [],
: ,
: [
{ : , : , : , : [], : [] },
{ : , : , : , : [], : [] },
{ : , : , : , : [], : [] }
]
},
{
: ,
: ,
: [],
: ,
: [
{ : , : , : , : [.()], : [.()] },
{ : , : , : , : [], : [] }
]
},
{
: ,
: ,
: [],
: ,
: [
{ : , : , : , : [.()], : [.()] },
{ : , : , : , : [], : [] }
]
},
{
: ,
: ,
: [],
: ,
: [
{ : , : , : , : [.()], : [.()] },
{ : , : , : , : [], : [] }
]
}
];
{
phases,
: .(phases),
: ,
: .(phases)
};
}
(): {
{
: ,
: [
{ : , : },
{ : , : },
{ : , : }
]
};
}
(): {
{
: ,
: [
{ : , : },
{ : , : },
{ : , : }
]
};
}
}
Step 3: Data Migration Execution
// Data migration executor
package gw.migration.data
uses gw.api.database.Query
uses gw.api.util.Logger
uses gw.transaction.Transaction
uses java.sql.Connection
uses java.sql.PreparedStatement
class DataMigrationExecutor {
private static final var LOG = Logger.forCategory("DataMigration")
private static final var BATCH_SIZE = 500
// Migrate accounts from legacy system
static function migrateAccounts(sourceConnection : Connection) : MigrationResult {
var result = new MigrationResult("accounts")
var selectStmt = sourceConnection.prepareStatement(
"SELECT * FROM legacy_accounts WHERE migration_status = 'pending' ORDER BY created_date"
)
var rs = selectStmt.executeQuery()
var batch = new ArrayList<LegacyAccount>()
while (rs.next()) {
batch.add(mapLegacyAccount(rs))
if (batch.size() >= BATCH_SIZE) {
processBatch(batch, result)
batch.clear()
}
}
// Process remaining
if (!batch.Empty) {
processBatch(batch, result)
}
rs.close()
selectStmt.close()
LOG.info("Account migration complete: ${result.Succeeded} succeeded, ${result.Failed} failed")
return result
}
private static function processBatch(batch : List<LegacyAccount>, result : MigrationResult) {
Transaction.runWithNewBundle(\bundle -> {
batch.each(\legacy -> {
try {
// Check if already migrated
var existing = Query.make(Account)
.compare(Account#LegacyID_Ext, Equals, legacy.LegacyId)
.select()
.AtMostOneRow
if (existing != null) {
LOG.debug("Account already migrated: ${legacy.LegacyId}")
result.incrementSkipped()
return
}
// Create new account
var account = createAccount(bundle, legacy)
// Validate
var validation = validateAccount(account)
if (validation.HasErrors) {
LOG.warn("Validation failed for ${legacy.LegacyId}: ${validation.Errors}")
result.addError(legacy.LegacyId, validation.toString())
result.incrementFailed()
return
}
result.incrementSucceeded()
} catch (e : Exception) {
LOG.error("Migration failed for ${legacy.LegacyId}", e)
result.addError(legacy.LegacyId, e.Message)
result.incrementFailed()
}
})
})
}
private static function createAccount(bundle : Bundle, legacy : LegacyAccount) : Account {
var account = new Account(bundle)
account.AccountNumber = generateAccountNumber(legacy)
account.LegacyID_Ext = legacy.LegacyId
// Create contact
var contact : Contact
if (legacy.IsCompany) {
var company = new Company(bundle)
company.Name = legacy.CompanyName
company.FEINOfficialID = legacy.FEIN
contact = company
} else {
var person = new Person(bundle)
person.FirstName = legacy.FirstName
person.LastName = legacy.LastName
person.DateOfBirth = legacy.DateOfBirth
contact = person
}
contact.EmailAddress1 = legacy.Email
contact.HomePhone = legacy.Phone
// Create address
var address = new Address(bundle)
address.AddressLine1 = legacy.Address1
address.AddressLine2 = legacy.Address2
address.City = legacy.City
address.State = mapState(legacy.State)
address.PostalCode = legacy.Zip
address.Country = Country.TC_US
contact.PrimaryAddress = address
account.AccountHolderContact = contact
return account
}
}
Step 4: Integration Cutover Planning
interface CutoverPlan {
phases: CutoverPhase[];
rollbackPoints: RollbackPoint[];
communicationPlan: CommunicationPlan;
goNoGoChecklist: ChecklistItem[];
}
interface CutoverPhase {
name: string;
startTime: Date;
duration: string;
tasks: CutoverTask[];
verificationSteps: VerificationStep[];
}
class CutoverPlanner {
createPlan(targetDate: Date): CutoverPlan {
const phases: CutoverPhase[] = [
{
name: 'Pre-Cutover (T-24 hours)',
startTime: new Date(targetDate.getTime() - 24 * 60 * 60 * 1000),
duration: '24 hours',
tasks: [
{ name: 'Final data sync', owner: 'Data Team', duration: '4 hours' },
{ : , : , : },
{ : , : , : },
{ : , : , : }
],
: [
{ : , : },
{ : , : }
]
},
{
: ,
: targetDate,
: ,
: [
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : }
],
: [
{ : , : },
{ : , : },
{ : , : }
]
},
{
: ,
: (targetDate.() + * * * ),
: ,
: [
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : }
],
: [
{ : , : },
{ : , : },
{ : , : }
]
}
];
{
phases,
: .(phases),
: .(),
: .()
};
}
(: []): [] {
[
{
: ,
: ,
: ,
:
},
{
: ,
: ,
: ,
:
},
{
: ,
: ,
: ,
:
}
];
}
(): [] {
[
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : }
];
}
}
Step 5: Validation Framework
// Post-migration validation
package gw.migration.validation
uses gw.api.database.Query
uses gw.api.util.Logger
class MigrationValidator {
private static final var LOG = Logger.forCategory("MigrationValidator")
static function validateMigration() : ValidationReport {
var report = new ValidationReport()
// Record count validation
report.addSection("Record Counts", validateRecordCounts())
// Data integrity validation
report.addSection("Data Integrity", validateDataIntegrity())
// Business rule validation
report.addSection("Business Rules", validateBusinessRules())
// Financial reconciliation
report.addSection("Financial Reconciliation", validateFinancials())
return report
}
private static function validateRecordCounts() : List<ValidationResult> {
var results = new ArrayList<ValidationResult>()
// Compare counts with source
var sourceCounts = getSourceCounts()
var targetCounts = getTargetCounts()
sourceCounts.eachKeyAndValue(\entity, sourceCount -> {
var targetCount = targetCounts.get(entity) ?: 0
var variance = Math.abs(sourceCount - targetCount)
var variancePercent = (variance * 100.0 / sourceCount)
var result = new ValidationResult()
result.Check = "Record count: ${entity}"
result.Expected = sourceCount.toString()
result.Actual = targetCount.toString()
result.Passed = variancePercent < 0.1 // Allow 0.1% variance
if (!result.Passed) {
result.Message = "Variance of ${variancePercent}% exceeds threshold"
}
results.add(result)
})
return results
}
private static function validateDataIntegrity() : List<ValidationResult> {
var results = new ArrayList<ValidationResult>()
// Check for orphan records
var orphanPolicies = Query.make(Policy)
.compare(Policy#Account, Equals, null)
.select()
.Count
results.add(new ValidationResult() {
:Check = "Orphan policies",
:Expected = "0",
:Actual = orphanPolicies.toString(),
:Passed = orphanPolicies == 0,
:Message = orphanPolicies > 0 ? "Found ${orphanPolicies} policies without accounts" : null
})
// Check for duplicate records
var duplicateAccounts = findDuplicateAccounts()
results.add(new ValidationResult() {
:Check = "Duplicate accounts",
:Expected = "0",
:Actual = duplicateAccounts.Count.toString(),
:Passed = duplicateAccounts.Empty,
:Message = !duplicateAccounts.Empty ? "Found ${duplicateAccounts.Count} duplicate accounts" : null
})
return results
}
private static function validateFinancials() : List<ValidationResult> {
var results = new ArrayList<ValidationResult>()
// Total written premium reconciliation
var sourcePremium = getSourceTotalPremium()
var targetPremium = Query.make(Policy)
.select()
.sum(\p -> p.TotalPremiumRPT.Amount)
var variance = Math.abs(sourcePremium - targetPremium)
var variancePercent = (variance * 100.0 / sourcePremium)
results.add(new ValidationResult() {
:Check = "Total written premium",
:Expected = sourcePremium.toString(),
:Actual = targetPremium.toString(),
:Passed = variancePercent < 0.01, // Allow 0.01% variance for rounding
:Message = variancePercent >= 0.01 ? "Variance of ${variancePercent}%" : null
})
return results
}
}
Migration Checklist
| Phase | Task | Owner | Status |
|---|
| Assessment | Complete inventory | PM | [ ] |
| Assessment | Risk analysis | Architect | [ ] |
| Planning | Data migration plan | Data Lead | [ ] |
| Planning | Integration cutover plan | Integration Lead | [ ] |
| Build | Configuration migration | Dev Team | [ ] |
| Build | Integration updates | Integration Team | [ ] |
| Test | UAT completion | QA Lead | [ ] |
| Test | Performance testing | Performance Team | [ ] |
| Migrate | Data migration execution | Data Team | [ ] |
| Migrate | Cutover execution | Ops Team | [ ] |
| Validate | Post-migration validation | QA Team | [ ] |
| Optimize | Performance tuning | Dev Team | [ ] |
Output
- Assessment and discovery framework
- Data migration plan and executor
- Integration cutover strategy
- Validation framework
- Migration checklist
Resources
Conclusion
This skill pack provides comprehensive guidance for Guidewire InsuranceSuite development and operations. For additional support, contact Guidewire Support or consult the Guidewire Community.