Community
Participate
Working Groups
When importing an exported repository, I would like to apply new namespace URIs and their corresponding package units (meta models). This will allow us to migrate models whose meta models are changed in a binary compatible way.
First run: I am getting this exception: java.lang.IllegalStateException: Unresolvable proxy: http://example.com/users-v1.0.ecore#//User at org.eclipse.emf.cdo.common.model.EMFUtil.safeResolve(EMFUtil.java:414) at org.eclipse.emf.cdo.common.model.EMFUtil.safeResolveAll(EMFUtil.java:435) at org.eclipse.emf.cdo.server.CDOServerImporter$FlushHandler.handleModels(CDOServerImporter.java:268) This is the step when the new ecore file is loaded instead of the old one. In the new ecore file (just copied from my workspace into another temprorary folder), I can see things like this: <eStructuralFeatures xsi:type="ecore:EReference" name="creator" lowerBound="1" eType="ecore:EClass users-v1.0.ecore#//User"/> The old package unit contains this: <eStructuralFeatures xsi:type="ecore:EReference" name="creator" lowerBound="1" eType="ecore:EClass praesto-users-v1.0#//User"/> So, when it is about to resolve the type, it cannot be found as the namespace is not correctly built. Do you have any hints where to look for or what to do next? I will attach the current patch/diff...
Created attachment 205392 [details] preliminary nsURI/package unit rewrite support
Note to comment #1: It should read (not anonymized completely): """ The old package unit contains this: <eStructuralFeatures xsi:type="ecore:EReference" name="creator" lowerBound="1" eType="ecore:EClass users-v1.0#//User"/> """
I just opened the new package unit (modified ecore file) in a text editor and removed all ".ecore" occurences. Then, I am
Then, I am able to go one step further...
The next question is: How to resolve proxies that are still referencing old types, i.e. types whose package URI has changed? When loading the package unit that do not have changed, we must be able to dispatch proxy URIs. Is that possible?
What do you mean by proxy? That term does not exist in CDO.
Example: Package A contains a Class C1 that has a reference to Class C2 in package B. Now, I decide to change package B's URI. When loading package unit A, it will fail since C1 is referencing C2 which now has a new URI. I just saw that the exception is caused due to org.eclipse.emf.ecore.util.EcoreUtil.resolve(EObject, ResourceSet) being called. Inside this method: URI proxyURI = ((InternalEObject)proxy).eProxyURI(); proxyURI contains the old URI... Is that understandable?
Ah, you're referring to EReferences between EModelElements. You're right, EModelElements are EObjects, too. I thought you were referring to references between "normal" EObjects, which are really CDORevisions and have no proxy URIs ;-) Next question: You say "When loading the package unit that do not have changed, we must be able to dispatch proxy URIs." What means "dispatch"? "Map to new URIs"? Perhaps it's easier to understand if you first specify exactly *what* you're trying to achieve and then find out *how* to do that. What are the model changes you're planning to support and what will not be covered?
As said in the forum post, this solution is only meant to be usable for simple meta model changes (binary compatibility). This is to be achieved by "enhancing" the import functionality of cdo, i.e. when importing an exported repository: - "dispatch", i.e. map old URIs to new URIs - load new package units by specifying a new ecore file path Note: This could all be done at xml file level, e.g. via xslt. But that would be specific to the xml export. This solution will work for any import types. The patch attached does already do this. You can run the "enhanced import" this way: cdo import repo1 path/to/file.xml http://myOldURI=http://myNewURI=mynewuri.ecore
I see. Regarding your previous question: If you evolve one EPackage I'd expect all depending EPackages to evolve at the same pace. Changing something in an EPackage X must be followed by changing the nsURI to X'. If an EPackage Y depended on X and you're not going to drop it entirely you must also migrate Y to Y', even if it's only for the sake of the new references to X' (your "proxies", I guess). Does that make sense?
Yes, that makes sense! When changing X to X': Shouldn't Y automatically be changed to Y' by the emf tooling? If yes, I do not see any changes made to Y.ecore in my workspace... Then, I would have to replace all package units when importing: cdo import repo1 path/to/file.xml http://X=http://X'=X'.ecore http://Y=http://Y'=Y'.ecore
> When changing X to X': Shouldn't Y automatically be changed to Y' by the emf > tooling? If yes, I do not see any changes made to Y.ecore in my workspace... I doubt it. In the best case (well, in fact it's the worst case, IMHO) Y would be serialized with the new references to X' but keep its old nsURI Y. I do not recall a magic in EMF that chooses a new nsURI for changed packages. > Then, I would have to replace all package units when importing: > > cdo import repo1 path/to/file.xml http://X=http://X'=X'.ecore > http://Y=http://Y'=Y'.ecore Yeah ;-)
> cdo import repo1 path/to/file.xml http://X=http://X'=X'.ecore > http://Y=http://Y'=Y'.ecore Keep in mind (IIRC) the equal sign "=" is allowed in normal nsURIs! Personally I would prefer a separate migration mappings file and a command line option like: -migrate "/path/to/mappings"
What structure should the migration script have? Simple properties file? Maybe: X=X' Y=Y' X'=X'.ecore Y'=Y'.ecore Afaik, you can escape specific chars in a properties file and use: http\://example.com/model/version\=1.0=http://example.com/model/version\=2.0 What do you think about comment #1? Do you have a solution? How did you manage to put the ecore files as package units into the repository?
(In reply to comment #15) > What do you think about comment #1? Do you have a solution? How did you manage > to put the ecore files as package units into the repository? With this code: PackageLoader loader = new PackageLoader() { public EPackage[] loadPackages(CDOPackageUnit packageUnit) { String id = packageUnit.getID(); String data = models.get(id); EPackage ePackage = EMFUtil.createEPackage(id, data.getBytes(), false, resourceSet, true); return EMFUtil.getAllPackages(ePackage); } }; packageRegistry.putPackageUnits(array, CDOPackageUnit.State.PROXY); for (InternalCDOPackageUnit packageUnit : array) { packageUnit.load(loader, false); }
(In reply to comment #15) > What structure should the migration script have? > Simple properties file? I clarified that nsURIs may contain "=" characters, but spaces wouldn't work very well (although they're not explicitely excluded by the spec, according to Ed). What about an own format like: X -> X' Y -> Y'
(In reply to comment #17) > (In reply to comment #15) > > What structure should the migration script have? > > Simple properties file? > > I clarified that nsURIs may contain "=" characters, but spaces wouldn't work > very well (although they're not explicitely excluded by the spec, according to > Ed). > > What about an own format like: > > X -> X' > Y -> Y' Actually, that would be the start of a domain specific language (DSL) that we would have to maintain/extend by time... I tried with the plain old properties format and it works very well as long as we have such simple requirements. Or do we really want a specific 'migration file format'?
(In reply to comment #16) > (In reply to comment #15) > > What do you think about comment #1? Do you have a solution? How did you manage > > to put the ecore files as package units into the repository? > > With this code: > > PackageLoader loader = new PackageLoader() > { > public EPackage[] loadPackages(CDOPackageUnit packageUnit) > { > String id = packageUnit.getID(); > String data = models.get(id); > > EPackage ePackage = EMFUtil.createEPackage(id, data.getBytes(), > false, resourceSet, true); > return EMFUtil.getAllPackages(ePackage); > } > }; > > packageRegistry.putPackageUnits(array, CDOPackageUnit.State.PROXY); > for (InternalCDOPackageUnit packageUnit : array) > { > packageUnit.load(loader, false); > } E.g. my ecore files in the workspaces have embedded ecore file names when cross references are involved. In the datastore, those file references are not present... Does that have to do with URI conversion? I will try the code once I am back at my development machine...
(In reply to comment #18) > Or do we really want a specific 'migration file format'? Not necessarily now ;-) The format aspect is probably less costly than the execution semantics implied by a full-fledged model migration DSL.
(In reply to comment #19) > E.g. my ecore files in the workspaces have embedded ecore file names when cross > references are involved. > In the datastore, those file references are not present... Because obviously they would make sense in a non-local environment. > Does that have to do with URI conversion? I will try the code once I am back at > my development machine... I must admit that I've never fully understood the subtleness of references to unregistered packages. For a distributed system we definitely need keys that make sense everywhere.
Erdal, did you finally reach your goal (migrating a CDO-hosted model to a newer version of the metamodel)?
(In reply to comment #22) > Erdal, did you finally reach your goal (migrating a CDO-hosted model to a newer > version of the metamodel)? Unfortunately, not fully, as I am stuck with those embedded ecore meta model file names used when cross references occur... One workaround would be to remove the package units from the xml repository export and load it "manually" into the repository by registering your new meta models with the package registry (once you create your session). Then, import the (modified) repository file again. One other thing I still have to try out is: load the xml file into an xml database (e.g. basex), then use xquery to manipulate or "migrate" the "model" and export it again.
Moving all open issues to 4.2. Open bugs can be ported to 4.1 maintenance after they've been fixed in master.
Moving all outstanding enhancements to 4.3
Moving all open enhancement requests to 4.4
Moving all open bugzillas to 4.5.
Moving all unaddressed bugzillas to 4.6.
Moving all open bugs to 4.7
Moving all unresolved issues to version 4.8-
Moving all unresolved issues to version 4.9
Moving to 4.13.