Hit the ground running with AIDE, Part 5: Build an autonomic computing system

Database engine management with autonomic touchpoints

This tutorial -- the fifth in the series -- illustrates the management of Apache Derby databases using touchpoint technology. Learn how to use a touchpoint that contains a working instance of Derby, and work through a management interface to a Derby database instance as a Web service-based managed object. You interact with this touchpoint using the IBM® Autonomic Integrated Development Environment (AIDE) resource browser and a Derby Java™ client program.

Stephen B. Morris, CTO, Omey Communications

Stephen is the CTO of Omey Communications in Ireland. For the past 20 years, Stephen has worked for some of the world's largest networking companies on a wide range of software projects, including J2EE/J2SE-based network management systems, billing applications, porting and developing SNMP entities, network device technologies, and GSM mobile networking applications. He is the author of Network Management, MIBs and MPLS: Principles, Design and Implementation (Prentice Hall PTR, 2003) as well as several articles on network management and other topics for InformIT and OnJava.com. You can reach Stephen at stephenbjm@yahoo.com.

05 September 2006

Also available in Chinese

Before you start

Learn what to expect from this tutorial series and how to get the most out of it.

About this series

This tutorial is the fifth in a series that describes the IBM AIDE toolkit and key elements of IT management, from the managed elements all the way up to and including the autonomic management application, with all the elements shown in Figure 1. Derby is an example of a managed element, and this series examines it closely.

Previously, this series covered code-level descriptions for incorporating the Java Management Extensions (JMX) application programming interface (API). This API provides a convenient mechanism for extracting data from JMX-instrumented entities and presenting it as part of an autonomic touchpoint. JMX is an important technology because it facilitates management of any Java entity, from Java 2 Platform, Micro Edition (J2ME) and Java 2 Platform, Standard Edition (J2SE) all the way up to Java 2 Platform, Enterprise Edition (J2EE).

The main emphasis in this tutorial is on the use and management of Derby instances. You might ask, "What makes Derby so interesting?" Well, it's a completely Java-based, Structured Query Language (SQL)-based, lightweight database engine. If required, Derby can run in embedded mode (everything inside one Java Virtual Machine, or JVM) or network mode (clients and engine in separate JVMs). In other words, it's a flexible tool that can provide advanced database services on a single machine or across a network. Because of this, Derby (like any other similar product) can consume a lot of resources.

As with the earlier tutorials in this series (see Resources), this tutorial uses and builds upon the examples bundled with the AIDE toolkit. In this tutorial, you learn how to use AIDE to interact with an instance of Derby. So, you should learn a little about Derby. The major takeaway is an end-to-end understanding of management of an important application class.

This series is for anyone who knows some Java programming and wants to be able to use AIDE technology to create key components (instrumented entities, touchpoints, and managers) of IT management systems.

About this tutorial

This tutorial describes how to use and manage Derby in conjunction with the AIDE toolkit. This tutorial takes you beyond the basics you learned in Part 1, Part 2, Part 3, and Part 4 and introduces a concrete managed application. The ongoing aim of this tutorial series is to provide you with a solid foundation on issues relating to manager applications, touchpoints, and managed entities.

For this fifth tutorial, the platform is still quite generic: Any platform that supports Eclipse, the AIDE toolkit, and J2SE V5.0. For example, Microsoft® Windows® XP is more than adequate. All the example code was written and tested on a computer running Windows XP Professional with Service Pack 2 (SP2).

For this tutorial, you'll be running Derby in network mode. This doesn't actually require you to have access to a network. I tested all the code on a single computer running Windows XP Professional SP2. For the more adventurous reader, you can run the various elements on separate computers, and the results should be the same as described in this tutorial.


This tutorial is written for programmers who have a reasonable knowledge of Java programming, Eclipse, and IT systems management. The ability to use an integrated development environment (IDE) such as Eclipse and the various tools and plug-ins that go with it is helpful but not necessary. Detailed directions are provided throughout the tutorial. Likewise, a basic understanding of the following components and technology is useful:

  • JMX
  • Managed entity instrumentation
  • Web service orchestration
  • Monitoring and management

All concepts are described and illustrated with working code examples. If you've been following the series, you should have a fairly solid knowledge of these issues. Nearly all the example touchpoints and Java classes mentioned in this tutorial are part of the AIDE distribution. I also provide an example Java client program for accessing Derby. The unmodified version of this program is part of the Derby distribution and is available for download from the indicated location.

System requirements

To run the examples in this tutorial, the minimum platform requirements are a computer running Windows XP on which you've installed the AIDE software and Apache Tomcat V5.

Note: You can use Apache Tomcat V4, but you must use the compatibility package as well.

Apache Derby: A database engine for all seasons

Before looking at the details of Derby, let's see where it might feature in the autonomic computing landscape.

Derby in the computing landscape

Manageability and the IT industry

IT industry vendors are falling over each other to provide manageable products. This scramble reflects the trend for reduced IT staffing and increasingly complex IT requirements. The one drawback that most vendor-specific solutions have is their proprietary nature. In general, manageability should not allow a new kind of vendor lock-in; rather, it should represent a value-added element. IBM's use of Web Services Distributed Management (WSDM) is a strong step in the direction of interoperable, value-added manageability.

Derby would generally sit at the bottom left corner of our old friend Figure 1 -- that is, in the applications area. In a way, Derby straddles the applications and server areas, because Derby is a database engine and, typically, is in the server side of the house. The fact that Derby can be embedded in a client makes me say that it's an application, but the important point is that this is not a hard and fast rule.

This blurry distinction illustrates the important point that IT management forces you to look at managed elements in ways that are different from using them for application support. Perhaps surprisingly, the best application software in the world can have poor manageability. In other words, the requirements for manageability are separate and distinct from the application service requirements.

Figure 1. The autonomic computing management value chain
The autonomic computing management value chain

In this tutorial, you see a complete application (Derby) included as part of an autonomic computing touchpoint. This method is an important and interesting one for packaging software. Placing the application in a touchpoint is a technique for instrumenting that application.

Now, let's create the Derby touchpoint.

Create the Derby touchpoint

End-to-end service providers

A requirement is emerging for a new breed of service providers -- what I call end-to-end service providers, or providers who supply both bandwidth and managed IT services. Traditionally, telecom providers have supplied telecom services and bandwidth, leaving client organizations or specialist providers to supply IT services. This need reflects the global trend for consolidating suppliers and reducing costs. (For more on this interesting topic, see the McKinsey article, "A rising demand for integrated IT and telecom services" [see Resources])

One way to implement such an end-to-end service provision model is through autonomic computing. Ultimately, this means a close relationship between IT services (such as database engines) and bandwidth.

If you've been following this series, this section should hold no big surprises. The directions in the AIDE toolkit Help provide all the required steps. Follow them (as described below) after opening the Help under Autonomic Integrated Development Environment User Guide > Examples > Apache Derby Example.

Also, make sure to execute the steps appropriate to your platform. The steps described in the Help are clear enough, but be careful not to mix your platforms (for example, don't follow a step for IBM WebSphere® if you want to create an Eclipse touchpoint).

If Eclipse is your required platform, complete the following steps:

  1. Use the second half of Step 1 under the heading, "To work with the DerbyTouchpoint example on Eclipse, use these steps."
  2. Follow Step 2 to generate the manageability endpoint.
  3. Follow Step 3 to update the implementation class.
  4. Follow the second half of Step 4, which concerns the deployment of the manageability endpoint on a computer running IBM WebSphere Application Server. (If you're using Eclipse, Tomcat is your application server.)
  5. Follow Step 5 to run the manageability endpoint.

If your touchpoint construction story is to have a happy ending, you should now see a working touchpoint, as shown (in excerpt form) in Figure 2.

Figure 2. The Derby touchpoint
The Derby touchpoint

If you haven't managed to get the touchpoint working, go back over the steps to make sure you've followed them to the letter.

Using the Derby touchpoint

Now, let's begin using the Derby touchpoint.

Use the touchpoint

From Figure 2, click Create & browse. As you can see from the console window, quite a lot happens at this point, including:

  • The Derby instance is created.
  • The Derby instance starts.
  • An instance of NetworkServerControl is created.

You should see the contents of Listing 1 in the console.

Listing 1. Derby is up and running
Attempting to ping Derby server to see if it has started.
Started Derby server
Ping succeeded; Derby properly started
Connection URI = jdbc:derby://

The last line in Listing 1 indicates that the Derby instance resides on the local machine. This is indicated by the use of the local IP loopback address, The port number for the Derby instance is the default, 1527.

The IP loopback address

Just in case you're interested in IP, you can actually ping your own loopback address. Doing so sends an IP packet through your local IP stack, and then receives the same packet as input.

This trick provides a convenient way for software vendors to host network software on a single computer. This machine can then act as a server for itself. One important example of this technique is with application server software (such as Tomcat, WebSphere, and the reference application server that comes bundled with J2EE). The loopback address allows for programs on the same computer to access the application server as if both entities resided on different computers.

Use a remote test Java program

As you saw with the touchpoint you used in Part 4, it's possible to interact with the Derby touchpoint by using one of the pre-configured remote test programs. To do so, complete these steps:

  1. Expand DerbyTouchpoint > JavaSource > tests.
  2. Right-click DerbyTouchpoint_testRemote.java, and then select Run As > Java Application.

Listing 2 illustrates the key code executed in this test program.

Listing 2. A remote Java test program
EndpointReference eprMgrRes =
proxy.DerbyTouchpoint mgrTouchpoint =
  />new proxy.DerbyTouchpointProxy(eprMgrRes);

Recall that Part 4 discussed the use of endpoint references at some length. The same considerations apply in this case. Part 4 discussed this topic in the context of Web service orchestration and management application structure. So, I won't comment further except to say that the Java program in Listing 2 essentially mimics what you can see with the Derby touchpoint resource viewer. Sometimes, it's useful to see the same concepts illustrated in different ways.

I recommend that you take a close look at the touchpoint implementation file DerbyTouchpointImpl.java. This class communicates with Derby through a method called getDatabasePropertySQL(), which is passed a string as a parameter, as shown in Listing 3. The code in Listing 3 is delimited by a Java try-catch exception block. (The latter is not shown in Listing 3).

Listing 3. The getDatabasePropertySQL() method from the DerbyTouchpointImpl class
String uri = getDatabaseURI().toString() + "/TestDB;create=true";
conn = DriverManager.getConnection(uri);
PreparedStatement stmt = conn.prepareStatement(GET_PROPERTY_SQL);
stmt.setString(1, propertyName);
ResultSet rs = stmt.executeQuery();
result = rs.getString(1);
System.out.println("For propertyName = [" + propertyName + "],
  SQL result=[" + result + "]");

Next in getDatabasePropertySQL(), the database of interest is calculated. A Derby driver instance is then loaded to access this database using a connection. When a connection is established, an SQL statement is prepared for dispatch to the database through the executeQuery() method. When the result set is returned from the query, the required data is extracted. At this point, the work required of the getDatabasePropertySQL() method is done, so the connection is closed and the result is returned to the caller (that is, the touchpoint).

This method illustrates much of what the previous tutorials covered -- namely, interacting with managed elements (in this case, Derby), retrieving managed data, and displaying that managed data.

A client for the Derby touchpoint

Download and install a copy of Derby. The Derby distribution resides on the Apache Derby Web site. The help that comes with Derby is excellent and provides detailed instructions on the overall installation as well as the execution of example programs. You can also carefully change the source code and see how doing so affects the operation of these Derby applications.

One area I found a bit weak in the distribution were the instructions related to configuring the DOS console environment -- namely, the variables DERBY_BIN, PATH, and CLASSPATH. So, in an effort to save you any bother, the following sections provide the bare minimum you need to get Derby up and running. Please note that this is completely separate from the touchpoint in that it relates only to the downloaded version of Derby.

Set the DERBY_BIN environment variable for Derby

To set the DERBY_BIN environment variable for Derby in Windows XP, complete these steps:

  1. Click Start, and then click Control Panel.
  2. Click System > Advanced > Environment Variables.
  3. Create a new system variable called DERBY_BIN.
  4. Assign DERBY_BIN the location of the Derby installation.

Note: The value I gave to DERBY_BIN on my Windows XP computer is C:\java\derby\db-derby-

Set the PATH variable for Derby

Derby includes a useful DOS batch file utility called sysinfo.bat. This batch file resides in one of the folders beneath the main Derby installation. I recommend adding this file to the PATH variable so that you don't have to type a long path name. So, the setting is %DERBY_BIN%\frameworks\NetworkServer\bin.

I added this setting to the PATH user variable rather than as a system variable on my computer. The fully qualified path name on my computer is C:\java\derby\db-derby-\frameworks\NetworkServer\bin.

Note: If you want the Derby settings to be available to other users on your system, make DERBY_BIN a system environment variable.

Set the CLASSPATH for Derby

Tip for installing Java software

It's a good idea to install Java software in short path names -- something like C:\java\package_name, where package_name is the name of the software you're installing. This technique pays dividends when you add new Java software, and then have to add other entries to the DOS PATH environment variable. The short name above helps to avoid long PATH variables. Remember: Environment variable management is an important part of IT management!

Another reason for short installation paths is avoiding spaces in PATH names. Using spaces in path names necessitates the clunky insertion of quotation marks in the path, which is time-consuming and unrewarding. If you use short path entry names, you can get up and running more quickly. The same considerations apply for CLASSPATH, DERBY_BIN, and other variables.

I find it convenient to add four Derby-specific Java Archive (JAR) files to my CLASSPATH variable. Relative to DERBY_BIN, these files are:

  • lib\derby.jar
  • lib\derbynet.jar
  • lib\derbytools.jar
  • lib\derbyclient.jar

You must also add the current execution directory to the CLASSPATH variable, which is described in the next section.

Run a Derby client program

You're nearly there. To run the Derby client program:

  1. Open a DOS console.
  2. Change the directory to %DERBY_BIN% by typing cd %DERBY_BIN%.
  3. Change the directory to %DERBY_BIN%\demo\nserverdemo.
  4. Add the current directory to the CLASSPATH variable by typing set CLASSPATH=%CLASSPATH%;.
  5. Type java SimpleNetworkClientSample.

At this point, you might see something like Listing 4. If you do, don't panic! It simply means that you must run the Derby touchpoint.

Listing 4. Unsuccessfully running the client program
Starting Sample client program
Failure making connection: org.apache.derby.client.am.DisconnectException:
  java.security.PrivilegedActionException :
  Error opening socket to server localhost on port 1527 with message : null
org.apache.derby.client.am.DisconnectException: java.security.PrivilegedActionException :
  Error opening socket to server localhost on port 1527 with message : null
    at org.apache.derby.client.net.NetAgent.<init>(Unknown Source)
    at org.apache.derby.client.net.NetConnection.newAgent_(Unknown Source)
    at org.apache.derby.client.am.Connection.<init>(Unknown Source)
    at org.apache.derby.client.net.NetConnection.<init>(Unknown Source)
    at org.apache.derby.jdbc.ClientDriver.connect(Unknown Source)
    at java.sql.DriverManager.getConnection(Unknown Source)
    at java.sql.DriverManager.getConnection(Unknown Source)
    at SimpleNetworkClientSample.getClientDriverManagerConnection(
    at SimpleNetworkClientSample.startSample(SimpleNetworkClientSample.java:112)
    at SimpleNetworkClientSample.main(SimpleNetworkClientSample.java:92)

If your touchpoint is running and you've clicked Create & browse (see Figure 2), you should see something similar to Listing 5.

Listing 5. Successfully running the client program
Starting Sample client program
Got a client connection via the DriverManager.
connection from datasource; getDriverName = Apache Derby Network Client JDBC Driver
Got a client connection via a DataSource.
Testing the connection obtained via DriverManager by executing a sample query
number of rows in sys.systables = 16
Testing the connection obtained via a DataSource by executing a sample query
number of rows in sys.systables = 16

If you still see errors, it's possible you might be running into a firewall issue, assuming you use a firewall. If this is the case, it might be time to contact someone in system administration. Before making the call, however, try temporarily turning off your firewall.

You know that the Derby sample program can successfully communicate with the touchpoint. Now, use a Derby client that modifies the Derby database in the touchpoint.

Running a modifying Derby client against the touchpoint

There isn't much more to running this Derby program against the touchpoint than what you saw above. Listing 6 shows the output from this program. As you can see, it actually makes SQL changes to the database. The program finishes by removing the changes and closing out the transaction. So, you're left with a clean database.

Listing 6. Modifying the touchpoint database
SimpleApp starting in derbyclient mode.
Loaded the appropriate driver.
Connected to and created database derbyDB
Created table derbyDB
Inserted 1956 Webster
Inserted 1910 Union
Updated 1956 Webster to 180 Grand
Updated 180 Grand to 300 Lakeshore
Verified the rows
Dropped table derbyDB
Closed result set and statement
Committed transaction and closed connection
SimpleApp finished

Let's take a look at some of the code in Listing 6.

Some Derby Java code

I mentioned earlier that Derby is an important piece of software. Anyone who has wrestled with getting database products up and running will appreciate its simplicity.

First required change

The code from Listing 6 includes good comments that make it easy to understand. I give an overall description of the program a bit later. I had to make a few minor changes to this program to get it to interoperate with the Derby touchpoint, and I explain these changes as I go:

  • Change the directory to %DERBY_BIN%\demo\simple.
  • Open SimpleApp.java in a text editor.

    Note: SimpleApp.java is available for download from Downloads.

  • Scroll down to the beginning of the SimpleApp class.
  • Add the line as shown at the bottom of Listing 7.

That's the first required change. The Java client program now uses the same database as the touchpoint.

Listing 7. Modifying the Java client class -- first required change
public class SimpleApp
/* the default framework is embedded*/
public String framework = "embedded";
public String driver = "org.apache.derby.jdbc.EmbeddedDriver";
public String protocol = "jdbc:derby:";
public String dbName = "TestDB";  // **** New line you must add ****

Second required change

For the second required change, complete these steps:

  1. Scroll down to the lines shown in Listing 8.
  2. Comment out the line as shown.
  3. Add the new lines shown at the bottom of Listing 8.
  4. Save the modified file.
Listing 8. Modifying the Java client class -- second required change
// **** Comment out the following two lines ****
//  conn = DriverManager.getConnection(protocol +
//           "derbyDB;create=true", props);
//  System.out.println("Connected to and created database TestDB");
// **** Add the next two lines ****
conn = DriverManager.getConnection(protocol +
             dbName + ";create=true", props);
System.out.println("Connected to and created database " + dbName);

Build the file

Build the file by typing javac SimpleApp.java. Then, run the Java client by typing java SimpleApp derbyclient.

You should now see the slightly modified form (the database name has changed) of Listing 6 as illustrated in Listing 9.

Listing 9. Connecting to and using the touchpoint database
SimpleApp starting in derbyclient mode.
Loaded the appropriate driver.
Connected to and created database TestDB
Created table derbyDB
Inserted 1956 Webster
Inserted 1910 Union
Updated 1956 Webster to 180 Grand
Updated 180 Grand to 300 Lakeshore
Verified the rows
Dropped table derbyDB
Closed result set and statement
Committed transaction and closed connection
SimpleApp finished

Now, look at the SimpleApp.java Derby client source code.

The Derby client Java code

The Derby client consists of the following main functional blocks with the associated implementing Java code:

  • Command-line parsing:parseArguments(args)
  • Program mode selection: Set by the framework variable
  • Derby driver instantiation:Class.forName(driver).newInstance()
  • Connect to the required Derby database:conn = DriverManager.getConnection()
  • Create an SQL statement:Statement s = conn.createStatement()
  • Execute the SQL statement:s.execute()
  • Process the results of the executed statement:ResultSet rs = s.executeQuery()
  • Release the result and statement resources:rs.close();s.close()
  • Commit any transactions:conn.commit()
  • Close the connection:conn.close()

This probably sounds like a lot to take on board. Like anything complicated, simply break it down and study the source code, and everything becomes clear. Derby is a Java-based, small-footprint database technology for the masses. So, it's well worth some of your valuable time.

Mapping Derby to the management interface

One question left unanswered is how you add something like the Derby touchpoint into the management API you've been developing over the past few tutorials. Recall that this API was a simple one with nothing more than Java placeholder methods for SET, GET, and NOTIFICATION operations. The surprising thing is that this is a simple exercise when you follow a fairly simple design exercise.


A SET operation is anything that creates, deletes, or modifies the state of a managed element. If you take the Derby driver as an example, you instantiate (create) a driver to communicate with a Derby database. So, the driver is a managed element. The Derby database is a persistent (stored to disk) entity that can be read from and modified. So, the database itself is a managed entity. Likewise, when you read from a Derby database, you're performing GET operations. And in the same vein, when you modify a database element (such as a row in a table), the database can emit a notification. You can configure the latter to be recorded by your NOTIFICATION handler.

So, it's not a huge intellectual effort to map a Derby touchpoint into your ultra-simple management API. It just takes a little imagination. If you're interested in pursuing this API, refer to the detailed steps in Part 3. A brief description is provided below.

Implement a SET operation

To implement a SET operation in the touchpoint for driver instantiation, you can execute the following steps. You can perform these steps on the Derby touchpoint model:

  1. Create a new model method called, for example, createDriverInstance in the capability editor.
  2. Define any required parameters, such as org.apache.derby.jdbc.EmbeddedDriver.

You can follow similar steps for methods to manipulate (create, read data from, and write data to) the Derby database entity. Then, to run the management API as a touchpoint, complete the following steps:

  1. Regenerate the code from the model.
  2. Incorporate the Java code into the touchpoint.
  3. Export the Web Archive (WAR) file.
  4. Exercise the touchpoint code.

It's important to realize that the Derby touchpoint you've used in this tutorial is itself a management program. The main difference between the Derby touchpoint and the management API described in this section is that the latter is more generic. As a result, you can extended it to manage other entities, such as MySQL and Linux®.


You can manage applications such as Derby in several ways: through ad hoc management, JMX instrumentation, touchpoints, and so on. Ad hoc management essentially uses the vendor-specific tools that come either with the product or as downloadable add-ons. JMX instrumentation involves adding JMX code to the Java code base for the product. (You saw JMX in operation earlier in this series.) This tutorial describes Derby management using touchpoint technology. The touchpoint in question displays and allows modification of the values of a few key Derby attributes.

The touchpoint can act as a Derby network server for clients, which is an interesting way of managing an application. The application is packaged inside a touchpoint, which is reminiscent of one of the features offered by the de facto network management standard application, HP OpenView. OpenView allows users to run external application instances.

Client applications can easily use the touchpoint Derby instance. With just a few minor code changes, you can make the code examples that come as part of the Derby distribution communicate with the touchpoint. This communication facilitates extension of the management API to include Derby and similar applications. Upcoming tutorials in this series will expand upon these and other topics in autonomic computing.


Client access to a Derby database serverac-aidetut5source.zip4KB



Get products and technologies

  • Autonomic Computing Toolkit: The Toolkit is a collection of IBM self-managing autonomic computing technology components, tools, scenarios, and documentation designed for users wanting to learn, adapt, and develop autonomic behavior in their products and systems.
  • IBM Autonomic Integrated Development Environment (AIDE): A set of software development tools that embrace the Web Services Distributed Management (WSDM) standard. Includes tools such as the IBM Manageability Endpoint Builder (for building endpoints that allow products to expose manageability interfaces) and the IBM Manageability Endpoint Simulator (previously known as IBM Touchpoint Simulator).
  • Java Management Extensions: Download the Java API for management.
  • Java 2 Platform, Standard Edition: Download this platform and learn more about J2SE, a complete environment for application development and deployment on desktops and servers.
  • Apache Tomcat version 5.0: Go to this site for all the latest releases for Apache Tomcat.
  • IBM trial products for download: Build your next development project with IBM trial software, available for download directly from developerWorks.


  • developerWorks blogs: Participate in developerWorks blogs and get involved in the developerWorks community.


developerWorks: Sign in

Required fields are indicated with an asterisk (*).

Need an IBM ID?
Forgot your IBM ID?

Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.


All information submitted is secure.

Dig deeper into Tivoli (service management) on developerWorks

Zone=Tivoli (service management), Tivoli, SOA and web services, XML, Java technology
ArticleTitle=Hit the ground running with AIDE, Part 5: Build an autonomic computing system