Community
Participate
Working Groups
To create a JDBC connection profile instance using the Connectivity Profile Management API, a connection profile provider id is needed. Given a database vendor and version, the framework will need to navigate and find the best supporting connection profile provider id. A database vendor and version are defined in a driver template. A driver template may be associated with zero or more types of profile providers. However, such direct association is not explicitly defined in DTP. They are only loosely coupled through a driver category in the UI page implementation of a profile provider. Specifically, a profile provider specific UI page is associated with a driver category, which is then used to filter the list of supported driver templates and definitions. The proposal is to extract such association from the UI implementation to a new element in the connection profile extension point. That is, add a new element to define the "driverCategory" supported by a JDBC connection profile provider id. A JDBC profile provider is expected to support one-and-only-one driver category. And technically, multiple profile providers may support the same driver category. Related profile UI page implementation can gradually migrate and replace its hard-coded driverCategory with the attribute value specified in the extension element. New utiltiy API will be needed to support navigating from a driver template's category to 0..n profile providers. The generic JDBC profile provider will be applied if none is found. If more than one are found to be associated with a driver template's category, it will be up to a client to determine which connection profile provider to use.
I will start on this with a proposal of the related extension point schema definition.
I've been doing some thinking about this. Basically we're looking at a mapping between the driverCategory and a provider ID? And it would be a one to many relationship (if any exist), as a given connection profile type may support many different driver categories. And then we need a map to get from the driver template ID (up from there via the template category) to get back to the provider ID? Since this will be fairly experimental for Galileo, can we simply create a new extension point that does this binding from provider ID to template category and then roll it back into the connection profile extension if we need to in a future release?
(In reply to comment #2) From what I understand, the current relationships are: * 1 profile provider is expected to support one-and-only-one db driver category * 1 db driver template's category may be supported by 0..n profile providers Using a new extension point to specify such mapping should be fine. An utility API method would then use this to look up to the connection profile provider id(s) based on a specified driver template ID (via the template category). Wonder if there may be any issue with ensuring consistency with the mapping implemented in a profile provider specific UI page? Larry, comments?
Yes, I think if an extension point is simply added then it is possible that the UI page could specify one category and the extension point could specify another.
Ok I get it. Right now the category ID is specified in the constructor for the UI page (wizard page or property page). The only problem with that is that it's in the UI plug-ins, not the core plug-ins, for the enablement projects. So if we're doing this all API under the covers, there's a chance it won't jive. So what happens if we provide this new extension point with a utility class that we can turn around and use to provide that category ID in the constructor from the new extension point? If there's no extension point defined, we can pass in a default. This should make it a fairly simple search/replace through the enablement projects for the property pages and wizard pages to adjust the constructor. The new extension point would map the provider ID to a category ID. The utility class could then process the driver template registry to find a suitable category for a vendor/version (by surfing for entries that support the vendor/version and back-tracing to the category). Am I oversimplifying this?
Larry, could really use your input on this so we might add it as an "experimental" item for Galileo.
So after discussing this with Larry & Linda at the Connectivity Team Meeting, we're going to do this... 1) Create an extension point that allows mapping of Connection Profile provider ID to Driver category ID as well as from Vendor and Version to Driver category ID. Ideally this should be done in the non-ui plug-in's plugin.xml so it's available for API use and UI use. 2) Create a utility class that provides a number of methods for retrieving the category ID from the provider ID and also from vendor and version. 3) Update the ExtensibleProfileDetailsPropertyPage and ExtensibleProfileDetailsWizardPage to use the utility class from #2 to map from the connection profile provider ID instead of hard-coding a category ID. If no mapping can be found via the utility class, default to the category ID specified if it is available. 4) Implement the extension point from #1 in all of the available enablement projects.
So to clarify just a bit so I don't forget... the ultimate goal is to go from the vendor/version to the provider ID by way of the intermediary category ID. I think the proposed API and extension points will handle this case.
Created attachment 133671 [details] First Cut at Patch Hey guys... This patch provides three things: 1) The extension points and a registry class to get the info out that you want 2) Updated extensibility wizard and property pages that grab the info from the registry if it's there 3) An updated plugin.xml that registers the correct bits for Derby Let me know what you think. It's not well documented yet, but it's pretty easy to use. --Fitz
Bumping this to RC1 so we have some time to review/change it if need be.
Looks good. Just as we discussed.
Linda, any thoughts?
The part of extension point that maps between the driverCategoryId and providerId looks fine to me. For the direct mapping of vendor+version to a driverCategory, I was walking thru the existing extension points, and notice that such mapping seem to already exist indirectly in the driverExtension extension point. The driverTemplate element in driverExtension specifies the vendor and version properties, and its associated parentCategory. Is it feasible to get the mapping from vendor+version to driverCategory thru the driverExtension's driverTemplate element? If so, it would avoid inconsistent definition across different extension points. The same vendor+version may be supported by multiple driverTemplates (defined in a driverExtension), which each can specify a different parentCategory. So technically, the registry method #getCategoryIdForVendorVersion could end up finding multiple categories that match the specified vendor+version. So the method should perhaps return a collection of driver category ids? The caller can then pick the appropriate driver category id that it wants, and call the mapping registry to get the corresponding providerId. The driverCategory could be a hierarchy. And it could be the parent category of a specified category id that has a mapping to a provider id. Perhaps the registry method #getProviderIDforDriverCategoryID can traverse up the driverCategory hierarchy, to find its first corresponding profileProviderId (defined in the new extension point)?
Very interesting observation. I'll have to look at it today and get back to you. Right now without surfing through all the available driver template extensions there's no index that would make this easy. But it would make sense to reuse what's already there in the driver extension. We're pushing this really close to the edge of RC1 though...
Created attachment 135230 [details] Add this to the first cut patch Hey guys... Ok, so I went back and revamped the ProviderIDMappingRegistry to use the driver template instead of the vendor/version to category ID extension point I created before. The upshot is that I default to the parent category of the parent category of the driver template wherever possible. The reasoning behind this is typically you have a version-specific category (you have the org.eclipse.datatools.connectivity.db.derby.10_2.driverCategory for derby, but we're not interested in that category, we're more interested in the org.eclipse.datatools.connectivity.db.derby.driverCategory category, which is the child of the main Database category). The only place where this appears to be a problem is for the generic JDBC driver template, which is a direct child beneath the Database category. Anyway... Long story short, I think this works. I haven't removed the extra extension point yet, but wanted someone to take a look at this to see what they think. Linda? Larry? Thanks in advance. --Fitz
Brian, The method that returns a providerId for vendor+version does work fine when a category has up to one level of db-specific parent. Thanks! BTW, the method name #getCategoryIDforVendorVersion can use a rename, since it now returns a "providerId". In case there are third-party driver categories that have more than 1 level of parent category before it reaches the DATABASE_CATEGORY_ID, it would be nice if the implementation can keep iterate up the parent category hierarchy till it gets to the DATABASE_CATEGORY_ID, and include each of the intermediate parent category ids in the sVendorVersionToCategoryIDMap. Somewhat separately, will the public method #getProviderIDforDriverCategoryID implementation be updated as well to handle mapping of a category hierarchy? For example, a mapping extension may specify the provider id for the top-level db-specific category only. The #getProviderIDforDriverCategoryID method argument may be its child category id, which ideally should return the providerId inherited from its parent category's mapping. Otherwise, one would have to create separate mapping extensions for each of the child category ids. Another separate minor thing, we currently have sqm.core.SQMServices as the main entry point to get various registry services. Should it be consistent and provide a new getter method in SQMServices to get the ProviderIDMappingRegistry singleton instance? E.g. public static ProviderIDMappingRegistry getProviderIDMappingRegistry()
1) Well... in the case of multiple nested categories, sometimes you don't want the top one. Sometimes you want one beneath that. Take for example Sybase driver templates... Databases Sybase ASA 9.x 10.x ASE 15.x If we climb all the way up to the one below the Databases node, you end up with Sybase, which isn't really what you want. So I'm not sure about that. Yes, this is because we used a slightly different hierarchy for our driver template categories for the Sybase plug-ins, but we shouldn't force changes unless they're really needed. 2) Are you asking to change getProviderIDforDriverCategoryID to be aware of child category IDs? 3) That's fine. I can add a reference from SQMServices.
1) If I understand the implementation correctly, the sVendorVersionToCategoryIDMap is mainly used as an interim collection to figure out sVendorVersionToProviderIDMap? For the Sybase case, including vendor+version -> "Sybase" category id in sVendorVersionToCategoryIDMap would not affect the sVendorVersionToProviderIDMap, since the "Sybase" category will not find a corresponding providerId in a Mapping extension. But for other cases where the top-level and/or intermediate category does have a mapped providerId in a Mapping extension, its vendor+version mapping to the providerId will then get correctly included in the providerId map. 2) >> Are you asking to change getProviderIDforDriverCategoryID to be aware of child category IDs? Yes in the public method, which would be separate from the private access to the Mapping extension entries. This would be more friendly and not require a providerId Mapping extension for each level of nested categories.
For 1) - ASA and ASE have different provider IDs. That's what I'm trying to say. So if we go this route and we try to bind the high-level category (the Sybase category, not Sybase ASA) to a provider ID, you end up binding to the wrong thing and will end up broken. For 2) - Cool, I'm working on it
Created attachment 135469 [details] Updated patch (complete) This updated patch cleans up the unnecessary extension point now and does pretty much everything I think what you've asked except for processing up to the Database category for the reasons I've explained in an earlier comment.
>> For 1) - ASA and ASE have different provider IDs That's what I thought too. So for the Sybase nested categories, it will only have the following Mapping extensions: A) ASA category <-> ASA provider id B) ASE category <-> ASE provider id When it walks up to the top level, and add each nested category to sVendorVersionToCategoryIDMap, it will have the following entries: 1) ASA+9.x -> ASA category 2) ASA+9.x -> Sybase category 3) ASA+10.x -> ASA category 4) ASA+10.x -> Sybase category 5) ASE_15.x -> ASE category 6) ASE_15.x -> Sybase category Then when it iterates thru each categoryId key in sVendorVersionToCategoryIDMap, to find corresponding mapped providerId, the Sybase category will not find a mapping providerId: 1) ASA+9.x -> ASA category -> ASA provider id 2) ASA+9.x -> Sybase category -> null 3) ASA+10.x -> ASA category -> ASA provider id 4) ASA+10.x -> Sybase category -> null 5) ASE_15.x -> ASE category-> ASE provider id 6) ASE_15.x -> Sybase category -> null So isn't it that only those category ids with mapping providerId will get added to sVendorVersionToProviderIDMap: 1) ASA+9.x -> ASA provider id 3) ASA+10.x -> ASA provider id 5) ASE_15.x -> ASE provider id
My last comment was based on the previous implementation in #loadMaps, in which it looks up the sCategoryIDtoProviderIDMap only when it iterates thru each categoryId in sVendorVersionToCategoryIDMap to populate sVendorVersionToProviderIDMap. Now that patch 135469 has #loadMaps using the reworked #getProviderIDforDriverCategoryID, this actually would take care of the multiple nested category issue #1 as well, if #loadMaps simply uses the driverTemplate's categoryId to put in sVendorVersionToCategoryIDMap (i.e. no need to even use its immediate parent categoryId). E.g. if (vendor != null && vendor.trim().length() > 0 && version != null && version.trim().length() > 0) { String encoded = encodeVendorVersion(vendor, version); String categoryID = templates[i].getParentCategory(); if (categoryID != null) { sVendorVersionToCategoryIDMap.put( encoded, categoryID); } } Then when #loadMaps later calls #getProviderIDforDriverCategoryID to populate sVendorVersionToProviderIDMap, it takes care of walking up the category hierarchy (including multiple-level cases) and would correctly applies the first mapping providerId for the vendor+version. -------- Separately, to ensure thread-safe usage, how about add synchronized to #getInstance, e.g. public static ProviderIDMappingRegistry getInstance() { if (sRegistry == null) { synchronized( ProviderIDMappingRegistry.class ) { if (sRegistry == null) sRegistry = new ProviderIDMappingRegistry(); } } return sRegistry; }
Good points on both items. I'll see about updating the patch this morning.
Created attachment 135694 [details] Updated patch (with Linda's last round of comments) Here's the updated patch with Linda's latest round of suggestions. Once this is in we can update each enablement plug-in to provide the provider ID to category ID mapping and we should be good to go. That's a minor tweak.
The latest patch 135694 looks good. Thanks! I can help add the mapping extensions for some of the db-specific components. Should the extension be in the *.dbdefinition plugin, or the runtime plugin? Attached are the ones for the generic JDBC and Apache ones in their dbdefinition plugin.
Created attachment 135711 [details] Mapping extensions for Generic JDBC and Apache Derby
That would be great if you can help out. I'd put them in the runtime plug-ins along with the driver definitions, since they kind of go together. And I'll go ahead and label these more explicitly as experimental. In the exsd documentation description and in the related public API Javadoc comments: * <p> * <strong>EXPERIMENTAL</strong>. This class or interface has been added as * part of a work in progress. There is no guarantee that this API will * work or that it will remain the same. Please do not use this API without * consulting with the DTP Connectivity team. * </p>
Created attachment 135728 [details] Mapping extensions batch 1 Mapping extensions for * Generic JDBC * Apache Derby * DB2 LUW * Informix * SQL Server * Oracle
Delivered framework changes to o.e.d.connectivity.sqm.core and o.e.d.connectivity.ui as tag v200905150650
Created attachment 135885 [details] Patch for all enablement projects This patch hits 'em all. I'll deliver now...
I'm guessing these tweaks won't make it into today's build, but may make it into the first RC2 build? Linda, can you verify as many of these as you want (you've already obviously done a few) when we get a build? Updated the following with tag v200905150820 o.e.d.c.apache.derby o.e.d.c.db.generic o.e.d.e.hsqldb o.e.d.e.ibm.db2.iseries o.e.d.e.ibm.db2.luw o.e.d.e.ibm.db2.zseries o.e.d.e.ibm.informix o.e.d.e.ingres o.e.d.e.msft.sqlserver o.e.d.e.mysql o.e.d.e.oracle o.e.d.e.postgresql o.e.d.e.sap.maxdb o.e.d.e.sqlite o.e.d.e.sybase.asa.ui (should really be in o.e.d.e.sybase.asa, but it's arranged differently for some reason) o.e.d.e.sybase.ase.ui (same as asa)
Marking as fixed.