private static void prepatePackageData(PackageVersion version, List<Instance> members) { LOG.info("Preparing Package Data file for package '" + version); String jarName = JarUtils.getPackagePath(version, false); // Prepare jar for this package version DataStore dataStore = InvocationContext.get().getDataStore(); try (GZIPOutputStream out = new GZIPOutputStream(new FileOutputStream(jarName))) { Kryo kryo = new Kryo(); Output output = new Output(out); // Write Package Members List<Instance> collect = members.stream().collect(Collectors.toList()); long id = version.getId(); SerializationUtil.writeInstances(kryo, output, collect); // Write QueryPlans List<ReplicationSQLQueryPlan> qPlans = dataStore.getAllQueryPlansByPackageVersion(id); output.writeInt(qPlans.size()); qPlans.forEach(m -> m.write(kryo, output)); // Write ModelHierarchyInfos List<ModelHierarchyInfo> mHierarchies = dataStore.getAllModelHierachyInfoByPackageVersion(id); output.writeInt(mHierarchies.size()); mHierarchies.forEach( m -> { output.writeInt(m.getParent()); output.writeInt(m.getSubModel()); }); // Write ClassHierarchy infos List<ClassHierarchyInfo> clsHierarchies = dataStore.getAllClassHierachyInfoByPackageVersion(id); output.writeInt(clsHierarchies.size()); clsHierarchies.forEach( m -> { output.writeString(m.getCls()); output.writeString(m.getSubClass()); }); output.close(); } catch (Exception e) { LOG.info("Package Data not prepared for " + jarName); throw new RuntimeException(e); } }
@Override public void commit() { if (isDisable) { return; } InvocationContext context = InvocationContext.get(); // Here we have to prepare Output data for this transaction. ChangesTracker tracker = context.getDbChanges(); // Save only ids for all added instances(including children to delete it // while reverting) List<Instance> added = tracker.getAdded(); // Get only changes for updated instances Set<Instance> updated = new HashSet<Instance>(); List<Instance> changes = tracker.getUpdated(); changes = filterChild(changes); changes.forEach( u -> updated.add( getChanges( u, i -> { Instance old = tracker.getOld(i.getId()); if (old != null) { return old; } return context.getDatabase().load(i.getId(), false); }, false))); // Save complete instances for all deleted instances Set<Instance> deleted = new HashSet<Instance>(); List<Instance> deletedObjs = filterChild(tracker.getDeleted()); deletedObjs.forEach(d -> deleted.add(tracker.getOld(d.getId()))); TxOutputDataFull full = new TxOutputDataFull(); full.setAdded(added); full.setUpdated(updated); full.setDeleted(deleted); full.setAddedModelHierachy(addedModelHierarchies); full.setRemovedModelHierachy(deletedModelHierarchies); full.setAddedClassHierachy(addedClassHierarchies); full.setRemovedClassHierachy(deletedClassHierarchies); full.setAddedQueryPlans(insertedQueryPlans); full.setUpdatedQueryPlans(updateQueryPlans); full.setDeletedQueryPlans(deletedQueryPlans); full.setCreatedShares( sharesCreated.stream().map(s -> s.getInstance()).collect(Collectors.toSet())); full.setDeletedShares(sharesDeleted); byte[] output = null; byte[] input = null; try { output = SerializationUtil.kryoSerialize(full); MutableLong initialId = new MutableLong(1L); inputs.forEach(i -> allocateDuplicateId(i, initialId)); input = SerializationUtil.kryoSerializeInstances(inputs); } catch (Exception e) { // TODO } // Preparing createdPrefixBitset BitSet created = new BitSet(); added.forEach(i -> created.set(i._type())); // Save it in database TxData data = new TxData(); data.setInputs(input); data.setAllocatedIds(allocatedIds); data.setOutput(output); data.setType(isDelete ? TxData.DELETE : TxData.UPSERT); data.setCreatedPrefixes(created); data.setFullOutput(full); data.setTxDone(new Timestamp(new Date().getTime())); data.setServerId(context.getServerId()); data.setTxDoneBy(context.getUserId()); this.txdata = data; }