The BugCentral Project

By: John Kaster

Abstract: This project is the community "bug-tracking" system that will be coming soon to a web site near you. John K has put up a description of it to solicit feedback from the community before the public beta starts.

The Community Application Factory

One of my roles in Borland Developer Relations is Architect of the community web site. Basically, that means that I digest input from a variety of people both inside and outside Borland, and define features, functionality, and how the pieces of the community web site infrastructure fit together.

Frequently, suggestions come from inside the company because of things we see when communicating with our customers, or from Borland's own needs. Our newsgroups are also a great source for things our customers would like to see. We always get suggestions from customers at trade shows, conferences, or seminars.

As you can imagine, we get a fair number of suggestions; far too many for one person to implement with any kind of timeliness. We also need to add functionality carefully, to make sure the community site stays as clean and simple to use as possible as we add more features to it.

We weigh our to-do list on factors such as:

  • The usefulness of the application
  • How much work it will be (at least, I do!)
  • The number of people who will benefit
  • The number of people who have requested it
  • The amount of time and effort it will theoretically save everyone in the long run
  • (Back in the early 1980's, I first made the joke "I'm so busy programming my computer to let me be lazy, I never get any rest!")

    This article is the beginning of what I'm sure will be a long discussion on the Borland Community newsgroup regarding a Borland community customer feedback service (for lack of a better term). It has been discussed previously as a bug tracking system, but that's not really the appropriate term for it since it's more than just that. However, before we jump into that description, I'd like to provide some background on what's happened over the last few years on the community site. I'm posting this article on the community site so people can see what we have in mind for this application and hopefully answer a lot of questions in advance.

    A quick look back

    When we began work on the community web site, we decided to use Borland technology whenever practical. Most of the applications currently running on the community site use Borland technology already.

    Content publishing

    I figured I'd get the one piece out of the way that's not written with Borland technology. The original timeframe for the launch of the community site was extremely aggressive, so we used an existing content publishing system rather than attempting to write one. Eventually, it will be replaced, but "if it ain't broke, don't fix it."

    CodeCentral

    One piece that actually predates the community site is CodeCentral, which I wrote back when I was a Product Manager for the technology we now call DataSnap. The browser interface for CodeCentral was designed to look like a part of the same community content system, and has been live for a few years. Along the way, I received some strategic assistance from Dan Miser, Jeff Overcash, and Chad Hower when building the various pieces of CodeCentral.

    CodeCentral uses Delphi, NetCLX, DataSnap, and InterBase. It's due for an update to our latest technology, but that will have to wait until other applications have been implemented so I can get back to it. Remember the cliche, "if it ain't broke, don't fix it."

    Threads

    The threaded conversation server (see the bottom of this article for a link to it) was written so community members could provide feedback for any content on the web site. All applications for the community web site support user comments. These comments never expire, and you can see them and search them at any time, including seeing all the comments you've ever made.

    The threads server uses Delphi, NetCLX, and InterBase. It will also receive a second round of intellectual funding in the future.

    Ad Banners

    The Advertising server uses Delphi, NetCLX, and InterBase. Both the threaded conversation server and CodeCentral have rotating ad banners, that actually have a pretty high click-through rate. We currently provide advertising for free for vendors who are a part of our community and are offering services or products to the development community. This "application" is really just a specialized WebModule for serving up rotating ads that's called directly by the threads server and CodeCentral. There's not much to work on for this application in a "round 2."

    These are the applications using Borland technology that are currently available on the community site. The remainder of this article discusses future implementations, and this is where I'd like your feedback.

    Community Application Common Features

    Before we get into the specifications of the new application I want to discuss with you, let's talk about features that will be common to all future applications hosted on the Borland community web site.

    • a publicly available server hosted and maintained by Borland.
    • either Interbase or JDataStore for the database, with a replicated database to a back-up machine to drastically reduce down time and data loss risks
    • a WebServices (SOAP/WSDL) interface that exchanges information with the server via XML, including the data packets and all requests for the server
    • if the server piece is written in Delphi, Kylix, or C++ Builder, there will also be a binary DataSnapTM interface available for the server
    • Clients
      • a browser-based interface
      • a native GUI (Kylix/Delphi/C++ Builder based) client invokable directly from the IDE or as a stand-alone application
      • a Java client invokable directly from the IDE or as a stand-alone application
      • additional clients that make sense in specific cases, like Palm or mobile clients for an event calendar

    This list may appear ambitious, but most of it will be leveraging existing Borland technology, or building on multi-tier application logic so all clients can be rapidly updated and conform to the same requirements without having to worry too much about breaking the functionality of one specific client. Since only one or two developers will typically be working on these projects (if we're lucky, we'll have one full time!) not all clients will come out at the same time.

    Now that I have the overview/introductory stuff out of the way, we can talk about the project code named "BugCentral". This won't be the final name, since it's for more than just bug reporting.

    "BugCentral" Project

    The "BugCentral" project started as a community-based bug tracking system. It has evolved into a feedback application that has its own unique twist -- it allows the entire Borland community to participate in a discussion with measurable value. There's not really a simple way to describe everything it does, but perhaps it can be summed up as a "request" box for Borland customers. When someone posts a "request," other community members can agree, disagree, rate, vote, or comment on that topic. These requests will be bug reports, feature suggestions, ideas for community articles, requests for content on the Borland web site, and so on.

    The appeal of these ideas to the community will be quantifiable; the number of people who respond, comment, rate, and vote on the topics submitted will be measurable, and each vote or rating will be tracked to a specific community member's ID. This will help provide indicators to Borland as to what our community considers important, and is slightly more accurate (dare we say scientific) than long threads on our newsgroup server. This does not mean that the most popular suggestion is guaranteed to be implemented by Borland, but it does mean that it's an indicator of customer interest, which will carry some weight in helping Borland determine which customer requests to implement.

    John Hawklyn, from our developer support department, several other people from Borland Developer Support, and the Developer Relations staff all produced the specification for this project, based on our own needs and desires, and input from the newsgroups, customer emails, and the strongly voiced opinions (as always) of TeamB. By getting input from a wide variety of sources, hopefully we will address the needs of the majority of users, who are both Borland customers and Borland employees.

    But what about bug reports?

    Of course, this project began as a community bug-tracking system, so let's talk about what will happen with bug reports and feature requests.

    1. Any community member will be able to submit a bug report for any product Borland is actively supporting. (For example, you won't be able to report Turbo Pascal bugs, but you will be able to report Delphi bugs.)
    2. When the "bug" is reported, it immediately becomes visible, and other commmunity members can provide feedback on it. With their feedback, they can comment on the bug, rate the bug (in terms of severity and usefulness), provide work-around suggestions, or vote on the bug as one of their three votes for bugs.
    3. A second-tier group of people selected by Borland (probably starting with TeamB members who are interested) will be able to verify the reported bugs. This will be done on a volunteer basis.
    4. When the bug has been verified, this group can then migrate the bug report to the "official" bug database where the bug will be assigned an official bug tracking number.
    5. Communication among the reporter of the bug, Borland Developer Support, QA, and R&D can then be brokered by the application, so all people interested in the bug can track its progress.

    This community-based rating system will help much more in the realm of bug reports being reviewed by multiple community members. The Borland community site will also identify top bug reporters, most "popular" (or perhaps "notorious" would be a better word) bugs for each "product", top reviewers, and so on. We'll also give out prizes for people finding severe bugs in the products, or making the best product suggestions.

    Bug-tracking features

    There will be a variety of ways for you to use this system, in addition to looking at product-specific areas for bug reports.

    You can:

    • retrieve all items you've posted
    • create a "watch" entry for any item, so you'll be notified of updates to it. This way, if you care about a bug, you can keep up to date with information about it automatically.
    • do searches for bugs on a variety of factors, including keyword searches.
    • keep your own copy of items with the native GUI and Java clients
    • do any offline processing you might want to do to minimize your on-line time with the GUI and Java clients
    • submit work-arounds and bug reports directly from the active project in the IDE when the IDE hooks are completed, automatically attaching the current project as the bug report, or attaching other files needed to demonstrate the bug.
    • download and open attachments as projects directly in the IDE for Delphi, Kylix, C++ Builder, or JBuilder.
    • view bug reports by:
      • defect number
      • status (open/closed)
      • classification (prevalence of bug)
      • type (crash, data loss, etc.)
      • bugs by category (i.e., product/area)
      • product version
      • user submitted
      • rating
      • date reported
      • bugs with workarounds
      • most voted by product
      • most rated by product
      • newest by product
      • bugs you've submitted

    Most importantly (for me!), you'll be able to build your own clients for it if you don't like the ones we produce.

    Because Jeff Overcash has been so helpful with the community projects in the past, I've contracted him to produce the server and native-code GUI client for this project.

    Current status

    This is what's currently completed. Coming soon to a web site near you for testing:

  • database design
  • WebService (WSDL) interface for ClientDataSet XML packets
  • Native-Code (RAD group) GUI interface, not yet invokable from the IDE
  • What's coming

    To do (mostly by me, probably):

  • The browser client. There will probably be multiple clients for this, since that's one of the main ideas for the second generation of community site applications
  • The Java-based client. I imagine there might be multiple ones of these as well. This may require the XML-DOM version of the data packets, but it really shouldn't.
  • One thing I'd hope to have functional for both IDE clients is the ability to package up the current project in the IDE and submit it as part of the submission for people making product-specific suggestions, requests, or bug reports.

    Components that still need to be written:

  • The Delphi/Kylix/BCB connection pooling components. I am still working on the specification for this piece, with some help from Danny Thorpe, Jeff Overcash, Deepak Shenoy, and Dan Miser. It will be generic, descending from a native Delphi resource dispenser architecture.
  • An archiving component callable from Delphi that understands jars, gzips, and zips. I only have zip support right now, which may or may not work for all jars and gzips. I have run into problems with some gzips before. The source code to this will need to be publishable, so commercial components can't be used.
  • Web Service Interface Definition

    The server piece of this application is being developed with Delphi 6 Enterprise. Here's the current WSDL for this WebService, as produced by the TWSDLHTMLPublish component:

    ICDSBugPublicInterface.xml

    Here is the Delphi equivalent of that WSDL, generated by the web services importer. Descriptions of these methods and their purpose will be provided in a future article, as this interface is still currently subject to change as we start testing the application. However, the method names and arguments should be pretty easy to understand as is.

    
    ICDSBugPublicInterface = interface(IInvokable)
      ['{88917E2E-5E46-4625-B246-746A9855F745}']
      function AddUser(const EMail: WideString; const Passcode: WideString;
        const First_Name: WideString; const Last_Name: WideString;
        const Organization: WideString; const Title: WideString;
        const Phone: WideString; const Ext: WideString; const Fax: WideString;
        const URL: WideString; const Address: WideString; const City: WideString;
        const State: WideString; const Zip: WideString; const Country: WideString;
        const Auto_Notify: Boolean; const Cookie: WideString;
        const Threadview: Integer; const Digest_Mail: Boolean): Integer;  stdcall;
      function ModifyUser(const Sessionid: WideString; const EMail: WideString;
        const New_Passcode: WideString; const First_Name: WideString;
        const Last_Name: WideString; const Organization: WideString;
        const Title: WideString; const Phone: WideString; const Ext: WideString;
        const Fax: WideString; const URL: WideString; const Address: WideString;
        const City: WideString; const State: WideString; const Zip: WideString;
        const Country: WideString; const Auto_Notify: Boolean;
        const Cookie: WideString; const Threadview: Integer;
        const Digest_Mail: Boolean): Boolean;  stdcall;
      function Login(const EMail: WideString;
        const Passcode: WideString): WideString;  stdcall;
      function AddBug(const Sessionid: WideString; const Status: Integer;
        const Data_type: WideString; const Severity: Integer;
        const Project: Integer; const Version: WideString;
        const Area: Integer; const Date_Reported: WideString;
        const Description: WideString; const Build: WideString;
        const Steps: WideString; const Platform: Integer): Integer;  stdcall;
      function ModifyBug(const Sessionid: WideString; const Defect_No: Integer;
        const Status: Integer; const Data_type: WideString; const Severity: Integer;
        const Project: Integer; const Version: WideString; const Area: Integer;
        const Date_Reported: WideString; const Description: WideString;
        const Build: WideString; const Steps: WideString;
        const Platform: Integer): Boolean;  stdcall;
      function DeleteBug(const Sessionid: WideString;
        const Defect_No: Integer): Boolean;  stdcall;
      function SumbitAWorkaround(const Sessionid: WideString;
        const Defect_no: Integer; const Workaround: WideString): Boolean;  stdcall;
      procedure AddAttachment(const Sessionid: WideString; const defectid: Integer;
        const Attachment: WideString);  stdcall;
      function CommentOnBug(const Sessionid: WideString; const Defect_No: Integer;
        const ParentID: Integer; const Comment: WideString): Integer;  stdcall;
      function RateABug(const Sessionid: WideString; const Defect_No: Integer;
        const Rate: Integer): Double;  stdcall;
      function VoteOnBug(const Sessionid: WideString; const Defect_No: Integer;
        const Vote: Boolean): Integer;  stdcall;
      function TrackABug(const Sessionid: WideString; const Defect_No: Integer;
        const Tracking_Option: Integer): Boolean;  stdcall;
      function GetTrackedBugs(const Sessionid: WideString): WideString;  stdcall;
      function GetUserBugs(const Sessionid: WideString): WideString;  stdcall;
      function GetUserVotes(const Sessionid: WideString): WideString;  stdcall;
      function GetUserRatings(const Sessionid: WideString): WideString;  stdcall;
      function GetTrackingList(const Sessionid: WideString): WideString;  stdcall;
      function GetMailings(const Sessionid: WideString): WideString;  stdcall;
      function GetLookup(const lookup_name: WideString): WideString;  stdcall;
      function GetOutLine: WideString;  stdcall;
      function GetProjects: WideString;  stdcall;
      function SaveQuery(const Sessionid: WideString; const Name_: WideString;
        const Query: WideString; const Default_: Boolean): Boolean;  stdcall;
      function RetrieveQuery(const Sessionid: WideString): WideString;  stdcall;
      function Search(const Sessionid: WideString; const First_Name: WideString;
        const Last_Name: WideString; const Defect_No: Integer;
        const RAID_No: Integer; const Status: Integer; const Data_Type: WideString;
        const Severity: WideString; const Resolution: Integer;
        const Project: Integer; const Area: Integer; const Version: WideString;
        const Date_Reported: WideString;
        const workarounds: Boolean): WideString;  stdcall;
      function SearchCount(const Sessionid: WideString;
        const First_Name: WideString; const Last_Name: WideString;
        const Defect_No: Integer; const RAID_No: Integer; const Status: Integer;
        const Data_Type: WideString; const Severity: WideString;
        const Resolution: Integer; const Project: Integer; const Area: Integer;
        const Version: WideString; const Date_Reported: WideString;
        const workarounds: Boolean): Integer;  stdcall;
      function GetDefect(const Sessionid: WideString;
        const defectid: Integer): WideString;  stdcall;
      function GetAttachmentList(const Sessionid: WideString;
        const defectid: Integer): WideString;  stdcall;
      function GetAttachment(const Sessionid: WideString;
        const defectid: Integer): WideString;  stdcall;
      function TopVoted(const project: Integer;
        const max: Integer): WideString;  stdcall;
      function TopRated(const project: Integer;
        const max: Integer): WideString;  stdcall;
      function NewestBugs(const project: Integer;
        const max: Integer): WideString;  stdcall;
    end;
    

    The XML datapackets will be compressed in a zip-compatible format before being base-64 encoded. We are using zip format because it is a standard format supported on every major platform, so someone wishing to create a custom client for this application can do so.

    Please let me know what you think of the plans so far, either by commenting on this article or participating in the Borland Community newsgroup.



    Server Response from: ETNASC01