Search This Blog

Tuesday, February 2, 2016

WebSphere MQ Tech Reference Guide

WebSphere MQ Tech Reference Guide

Every now and then IBM puts out a tech note document that carries in it 'How-Tos'. These are simple and informative knowledge shares. I have put together a list that can be used as a reference.

Example of configuring a WMQ Requester-Sender channel pair

You want to see an example of how to configure a WebSphere MQ (WMQ) Requester-Sender channel pair

WMQ Commands to setup two way communication between two queue managers on Sender and Receiver channels

You want to see a complete set of commands to setup the full (both ways) communication between 2 Websphere MQ (WMQ) queue managers, using Sender and Receiver channels.

Commands to create a queue manager and to configure it for remote administration via MQ Explorer

This document provides details of the line commands for WebSphere MQ to create a queue manager and to configure it for remote administration using MQ Explorer

Using WMQ line commands to define a local queue, to put, browse and get a message

You want to know how to use line commands in WebSphere MQ (WMQ) to define a local queue, to put, browse and get a message, and to clear a queue.

MQ V7: How to view the message properties and, or RFH2 header from a message

It is possible to use WebSphere MQ Explorer V7 and the C sample "amqsbcg" to display the RFH2 header for JMS messages and to display message properties created by non-JMS applications. This document shows the different output that can be obtained with the different choices from the Explorer and the sample amqsbcg.

How to determine if a WebSphere MQ queue has messages that are being held in an open transaction by an application (uncommitted messages)

How to check to determine, if a WebSphere MQ queue has messages that are being held in an open transaction by an application.

You can not delete uncommitted messages from an MQ Queue used by CICS transactions

You want to delete some messages from a WebSphere MQ for z/OS queue. The messages are uncommitted. There is no thread attached to the queue. A recycle of the queue manager does not clear the problem.

How do you tell if there are uncommitted messages on a queue?

In WebSphere MQ, the MQGET or MQPUT of a message is uncommitted if the operation is done within SYNCPOINT (MQGMO_SYNCPOINT or MQPMO_SYNCPOINT), and the unit of work is not committed. How do you tell if there are uncommitted messages on a queue?

How do I query the WebSphere MQ queue depth, messages on queues, or queues?

How do I query the WebSphere MQ queue depth, messages on queues, or queues?

WebSphere MQ error logs

Directions to find WebSphere MQ and MQSeries error logs.

2035 MQRC_NOT_AUTHORIZED Connecting to WebSphere MQ from WebSphere Application Server via CLIENT Bindings

This article covers the most common reasons why an application running in WebSphere Application Server receives a 2035 MQRC_NOT_AUTHORIZED error when connecting to MQ as a client over a network. Quick steps to work around the MQRC_NOT_AUTHORIZED errors during development are provided in the 'Resolving the problem' section, as well as considerations for implementing security in production environments. A summary is also provided of behavior for outbound scenarios with container-managed and component-managed security, as well as inbound behavior for listener ports and activation specifications

2035 MQRC_NOT_AUTHORIZED in WMQ

You are getting MQRC 2035, Not Authorized in your WebSphere MQ application or channel. You need to understand what causes this failure.

2035 0x000007f3 MQRC_NOT_AUTHORIZED

AMQ5540 and AMQ5541, application did not supply a user ID and password, 2035 MQRC_NOT_AUTHORIZED

As an MQ administrator you create a new queue manager in WebSphere MQ version 8.0.
You can access the queue manager by using WebSphere MQ Explorer or MQ client applications in bindings mode.

You are aware of the default behavior for the channel authentication records in which an MQ administrator cannot remotely access the queue manager. To gain access an administrator can either set the queue manager attribute CHLAUTH to DISABLED, or add the appropriate records to allow remote access. 

WMQ 7.1 / 7.5 queue manager RC 2035 MQRC_NOT_AUTHORIZED or AMQ4036 when using client connection as an MQ Administrator

You try to remotely access the queue manager as an MQ administrator and you get the return code 2035 MQRC_NOT_AUTHORIZED.
You expected that the issue with the channel authentication records had been addressed.

AMQ4036 When trying to connect a client to queue manager

You have WebSphere MQ Client and Server installed on two Windows 2000 systems. You add a new user to a group that has access to connect to the queue manager. When you try to connect to the queue manager as this new user, the WebSphere MQ Client gets the following error:

AMQ4036 Access not authorized. You are not authorized to perform this operation.

Remote connection to v7.1 queue manager on IBMi fails with AMQ4036, Access not permitted

You have created a queue manager on IBMi WebSphere MQ (WMQ) v7.1, and when you attempt to connect to the queue manager via WMQ Explorer, to perform remote administration, or a WMQ client application using a WMQ administrator profile, you receive an AMQ4036,"Access not permitted. You are not authorized to perform this operation." on the client.

On iSeries, in the error log for the queue manager, you may see either an AMQ9776, Channel was blocked by userid, or an AMQ9777, Channel was blocked, followed by an AMQ9999, Channel 'SYSTEM.ADMIN.SVRCONN' to host 'x (9.49.x.x)' ended abnormally.

START CHANNEL command on a receiver or server-connection channel, only enables the channel. Why is the channel not started?

You start a WebSphere MQ (WMQ ) receiver (RCVR) or a server-connection (SVRCONN) channel and you expect that the STATUS of the channel to be RUNNING, however the channel is not actually running.
You look at the error logs for the queue manager and you do not see any errors.

Using telnet to test connectivity between MQ Client and MQ server

You are having trouble connecting a WebSphere MQ client to a MQ server, receiving errors that you can not connect to the MQ queue manager.
One of the first things to determine is if the two machines can communicate, and using the telnet tool is one way to accomplish it.

2058 Queue Manager name error

Your program attempts to connect to WebSphere MQ and fails.

Troubleshooting MQ channels

Your IBM MQ system is having problems with channels and you need to know how to troubleshoot the problem. This document describes several common channel problems and how to address them.

Setting the TCP/IP KeepAlive interval to be used by WebSphere MQ

The method of setting the keep alive interval is different on each platform. What is the method for the most commonly used platforms?

AMQ9513: Maximum number of channels reached

You would like to know more details regarding the following WebSphere MQ error message:
AMQ9513: Maximum number of channels reached

Finding the number of running channels

How do I determine the number of channels that are running for my queue manager?

WebSphere MQ Clustering - Cluster hints and tips

This is a compilation of the most common problems and questions regarding WebSphere MQ Clustering and it is intended for new MQ Cluster users.

AMQ9513 Maximum number of channels reached

Your system reaches the maximum number of channels allowed (AMQ9513 Maximum number of channels reached). You edit the qm.ini to add more channels but the system still fails at the default level of 100.

Number of client channels increasing

The number of client channels increase over time and never decreases.

AMQ9213 2009 MQRC_CONNECTION_BROKEN on MQ clients

You have WebSphere MQ clients which connect to several different MQ servers. The MQ clients are quite frequently disconnected with rc=2009, MQRC_CONNECTION_BROKEN. The clients are able to reconnect immediately. The queue managers are running well. You see no problems when issuing 'runmqsc' commands on the server.

MQ connection is terminating with error code 2009

MQ connection is terminating with error code 2009.

MQRC and MQCC Understanding MQ reason codes and completion codes 2030, 2033, 2035, 2080, 2085, 2092, 2110, 2189

WebSphere MQ program fails to process an MQ API call. MQ notifies the program of the failure, by returning a completion code (MQCC), and a reason code (MQRC). These completion codes, and reason codes are documented in the WebSphere MQ Messages manual.

Example of using the qload utility (SupportPac MO03: WebSphere MQ Queue Load / Unload Utility)

You want to see a detailed example of using the qload utility, provided with the SupportPac MO03: WebSphere MQ Queue Load / Unload Utility

Enterprise applications, the WebSphere Application Server WebSphere MQ messaging provider connection factories and Authentication Aliases explained

I am using WebSphere Application Server V7 or V8.0, and have configured a WebSphere MQ messaging provider connection factory with an Authentication Alias, that maps to a user identifier and password. How can I configure my enterprise applications so that the information in the Authentication Alias is flowed to WebSphere MQ when the activation specification or connection factory is used to create a connection to a queue manager?

How to calculate the total amount of disk space for the recovery logs for one queue manager

You are planning for the file system requirements for one WebSphere MQ (WMQ) queue manager, and you want to understand how to calculate the total amount of disk space for the recovery logs needed for the queue manager

Where's my message? Tool and instructions to use the MQ recovery log to find out what happened to your persistent MQ messages on distributed platforms

Operations performed on persistent messages passing through an IBM WebSphere MQ queue manager are logged. This document provides a tool and set of instructions to read that log data for a distributed MQ queue manager, extract the persistent messages, and see the transactions and operations performed (puts/gets/commits/rollbacks).

2085 0x00000825 MQRC UNKNOWN OBJECT NAME

Your WebSphere MQ application program fails with reason code 2085 (MQRC_UNKNOWN_OBJECT_NAME) when you attempt to open a queue. 

2085 0x00000825 MQRC UNKNOWN OBJECT NAME



Webcast Replay: Using ITCAM to monitor MQ queue managers in Linux and Windows

This WebSphere Support Technical Exchange is designed to present an introduction on basic installation of IBM Tivoli Monitoring (ITM) and IBM Tivoli Composite Application Manager (ITCAM) Agents for WebSphere Messaging to monitor MQ queue managers in Linux and Windows.
This WebSphere Support Technical Exchange is designd to describe the different types of triggering available in WebSphere MQ, and possible uses and techniques for debugging problems that may occur.
This WSTE discusses the details on how to setup a small WebSphere MQ cluster using versions 7.0, 7.1 and 7.5. It also provides the details on the basic usage of clustered queues and clustered topics.
This WebSphere Support Technical Exchange is designed to focus on how the WebSphere MQ message descriptor is handled in a message that is sent from a remote queue definition to a transmission queue. Additional topics related to the transmission queues are also covered, such as basic troubleshooting, clusters and triggering of channels.


You have a JMS application that generates request messages with a string based correlation id and a reply ( response) message is generated with the same correlation id as the request using a base Java application. The JMS application waiting for the reply never receives it.


The objective of this techdoc is to show how the Message ID (MsgId) and the Correlation ID (CorrelId) in an MQ Message Descriptor (MQMD) are handled in a message that is sent from a Remote Queue Definition to a Transmission Queue, and from there to the destination queue.


Scenarios that are addressed in this technote:

1) You are using point-to-point (queues) with your putting and getting applications. You want to use WebSphere MQ (WMQ) V7 Pub/Sub under the covers and you do not want your putting and getting applications to be aware of Pub/Sub. That is, the application that puts messages into a queue continues to put messages into a queue, and the getting applications keep getting messages from a queue.

2) You are using point-to-point and you want to create "duplicate" messages that will be stored in queues Q1 and Q2, when the message is put into the queue "DESTINATION"


This WebSphere Support Technical Exchange presents the different mechanisms to browse messages in WebSphere MQ. It discusses how to view the message fields, message properties, the contents of the message and reason codes from dead letter queue using sample executables and the MQ Explorer. 

The first and second parts of the presentation focus on methods that work in both V6 and V7. These parts are targeted for beginners.

The third part, showing only the methods that work with V7, is targeted for intermediate users.


To demonstrate the use of a simple but functional Message Driven Bean (MDB) in WebSphere Application Server V7, V8.0 and V8.5, which interacts with WebSphere MQ V7 as the Java™ Messaging Service (JMS) provider. WAS 9.0 ships with MQ RA 9.0.



The objective of this technical document is to describe in detail how to configure the connection between a WebSphere Application Server V7 with a WebSphere MQ Queue Manager V7 using Secured Sockets Layer (SSL).


Demonstrate the steps to develop and test a Message Driven Bean (MDB) using Rational Application Developer (RAD) 7.5 and WebSphere Application Server V7, while using WebSphere MQ V7 as Java ™ Messaging Service (JMS) Provider.


When setting up Windows Explorer to do administration on WebSphere MQ queue managers on remote UNIX machines there are a number of actions that need to be done.
The most common problem is an authorization failure. The characteristic of this is an error box which displays:
Access not authorized. You are not authorized to perform this operation (AMQ4036).


Question
You have a WebSphere MQ V6 Base Java™ application that gets different types of messages (JMS, C-based from amqsput, etc) from a queue in an MQ V6 queue manager. The application uses the method:

MQMessage.format
This method returns "MQHRF2" when dealing with JMS messages. It returns "MQSTR" when dealing with messages from C-based applications such as amqsput. Thus, you use this fact to easily distinguish between JMS and non-JMS messages.

However, after you upgrade to V7 both client and queue manager, now the application returns "MQSTR" for both JMS and C messages, and now it seems that you can no longer use this approach to distinguish between JMS and non-JMS messages.


You need a cron job in UNIX to automate the clearing of all messages on a queue in a WebSphere MQ queue manager, and for that cron job to run at the same time every day.


To demonstrate the use of a simple Message Driven Bean (MDB) in WebSphere Application Server V7 / V8.x, which interacts with WebSphere MQ V7.x as the Java™ Messaging Service (JMS) provider. 

This MDB has in its Deployment Descriptor the specification of a JMS message selector for the following user-defined property and value:
color=”blue”


How can I find the time of the last put or get in WebSphere MQ (WMQ) for a specific queue?


There is a known design limitation with Message Driven Bean (MDB) support in WebSphere MQ, when multiple Java Virtual Machines (JVMs) attempt retrieving a message from the same queue. This will also be the case if you use multiple application servers, or if you are accessing a queue, hosted on a central queue manager, from several application server instances. 

This limitation is specified in the DeveloperWorks article below: 
( See "Scaling up: the source queue")



Demonstrate the use of a simple Message Driven Bean (MDB) in WebSphere Application Server V7, which interacts with WebSphere MQ V7 as the Java™ Messaging Service (JMS) provider. This MDB always rolls back a message and therefore indicating it as a “poison message”. This MDB can be used to better understand the handling of poison messages by the WebSphere Application Server and MQ.

Message persistence FAQs

This is intended to answer frequently asked questions regarding WebSphere MQ handling of persistent and nonpersistent messages. 
You want to understand the reason for the most common WebSphere MQ error messages.
The objective of this document is to show the steps and the screen captures to specify a userid and a password in MQ Explorer 8 when defining a connection to a remote queue manager.
Your applications using the WebSphere MQ classes for JMS that subscribe to the same topic each receive a copy of the same message.
Here are some questions and answers about WebSphere MQ Publish/Subscribe options with JMS classes :
To demonstrate the use of a simple but functional Message Driven Bean (MDB) in WebSphere Application Server V7, V8.0 and V8.5, which interacts with WebSphere MQ V7 as the Java™ Messaging Service (JMS) provider. WAS 9.0 ships with MQ RA 9.0.








Wednesday, January 13, 2016

Using Channel compression in WebSphere MQ

Preface

Starting with WebSphere MQ v6.1 IBM introduced the channel compression for the data that flows between queue managers. This is a good feature that makes optimum use of the network bandwidth by using high end systems to compress the data. In this post I will try to take a stab at using message compression.

Create the queue managers and objects

Create two queue managers with the following details - 
Queue Manager Name Listener Port
WQM1 2221
WQM2 2222

Create transmission queues on both the queue managers as follows - 



Queue Manager Name
Transmission Queue
WQM1
WQM2
WQM2
WQM1

Next up, create the sender and the receiver channel that will communicate with each other

Queue Manager Name Sender Channel Receiver Channel
WQM1 WQM1.TO.WQM2 WQM2.TO.WQM1
WQM2 WQM2.TO.WQM1WQM1.TO.WQM2

Create the local queue definition in WQM2 as 'LOCAL.Q' and create a remote queue definition as 'REMOTE.Q.OF.LOCAL.Q' in WQM1. 


If all the objects are created and the channels and listener are running then the message written to REMOTE.Q.OF.LOCAL.Q should end up in LOCAL.Q .

NetTool

For this exercise to keep a tab on the size of the data and the time it takes to send the packets from one queue manager to another, I decided to use NetTool. To know more about NetTool and download, follow this link. Download the zip file and unzip it as a folder in the system.

Protocol Tunneling

Start NetTool by click on the following 'start-nettool.bat' on windows and 'start-nettool.sh' on unix systems and switch to the second tab. This tab allows us to protocol tunnel by having NetTool listen on the port 2222-the listener port for WQM2- and directing the traffic coming on port 2220 to 2222 and click on the 'Listen' button. This will start the tunnel.


With the protocol tunneling in place change the sender channel on WQM1 to use port 2220 instead of 2222. This way we know the time and the data being sent from WQM1 to WQM2.

Without compression

Using RFHUtil, send the message to REMOTE.Q.OF.LOCAL.Q and here is what we see - 



In this scenario a file of 100298 bytes is used to send to the remote queue from WQM1 to WQM2. After the message has been changed, change the compression, right click the channel name and select properties. Change the compression to RLE and save it. Do this to the receive channel as well and restart both the channels. For the sake of parity all the 4 channels have been changed to RLE and need to be restarted.

I changed it across the 2 different message compression and here are the results - 


Starting from top down the order has been ZLIBHIGH, ZLIBFAST, RLE and no compression. The statistics show the progressive message bytes being lowered as the message compression is changed.  







Wednesday, January 6, 2016

IBM Integration Bus using Aggregation Nodes for fan out/fan in

Preface

One of the common requirements that I have come across is having to request data from different systems and present it in a single place. An example of this is when you login on your bank page and you get a single dashboard that will show your -
  1. Checking account summary.
  2. Saving account summary.
  3. Credit Card transaction summary.
  4. Auto loan summary.
  5. Home mortgage summary.
All these details may be residing on a different system and the single denominator may be the customer id that is using these services. Another close use case is if a particular operation needs data for multiple denominations but the external service allows only one request at a time. A case in point is the co-ordinates of the ATM a bank has in the vicinity of a particular zip code while the end system - google maps possibly- only allows one request per service.

One way to work around for this is to use the Aggregation nodes with IBM Integration Bus. In this scenario,the back end application allows only one request at a time. The service we have built receives multiple stock symbols and we use the fan out mechanism to create multiple request for stock quote and then collect them as one response in fan out.

I am using the following web service as the back end application to request the stock quote and the WSDL for that operation is available here.


External/Backend service

In this instance we are using the WSDL to create the external service that will be called from IBM Integration Bus(IIB formerly IBM WebSphere Message Broker). The service receives a request for a stock quote and then replies with the response in SOAP. Create a shared library that will have the web service to get the stock quote. I have named it as 'MFL_StockQuote'



Create the message model that will have the WSDL specification. 



Select the SOAP XML option as our's is a WSDL.



The WSDL already exist, so specify that one for the message model.



Specify the location of the WSDL, in this case the HTTP URL from where you can get the WSDL.



Select the operation that we intend to use for our application. In this case it is the SOAP operations. Click on 'Finish' to complete the operation and import the WSDL.



With the WSDL imported, create the sub flows that will invoke the external service and encapsulate the service invocation.



Named as 'SF_StockQuoteInvoke'

 

Drag and drop the WSDL onto the canvas.


The service will be invoking the web service from the sub flow and the operation will be GetQuote.


To keep things simple I have kept this subflow named as SF_StockQuote. 


After this is done the library content should look like this. To simplify it I have moved the subflows from their schemas to the top level to not use any schemas. 


SF_StockQuote

SF_StockQuote invokes the external service using the WSDL defined details.



The properties of the SOAP Request node.



SF_StockQuoteInvoke

Coming back to SF_StockQuoteInvoke, I have made the following changes to the flow after having had dragged the WSDL onto the canvas- 



The SaveMQHdr compute node will save the incoming MQ Header from the message the Aggregate Request flow is sending. The code snippet used is -

CREATE LASTCHILD OF Environment DOMAIN 'MQMD' NAME 'MQMD' ;
SET Environment.MQMD = InputRoot.MQMD;
SET OutputRoot = InputRoot;

The CreateMQResp compute node is reattaching the will save the incoming MQ Header from the message the Aggregate Request flow is sending. The response that is being sent from the service is being parsed to create a proper XMLNSC message. The code snippet used is -

SET OutputRoot.MQMD = Environment.MQMD;

DECLARE sh NAMESPACE 'http://www.webserviceX.NET/';
DECLARE data CHAR;
SET data  = InputRoot.XMLNSC.sh:GetQuoteResponse.sh:GetQuoteResult;

IF (data = 'exception') THEN
SET OutputRoot.XMLNSC.StockQuotes.Stock = 'exception'; 
ELSE
CREATE LASTCHILD OF OutputRoot 
DOMAIN 'XMLNSC' PARSE (data 
CCSID InputRoot.Properties.CodedCharSetId 
ENCODING 0 ); 
END IF;

Aggregation(Putting it together) 

Till now we have created the service that is going to be invoked. This service will give the stock quote. Next up create the Message Flow application that will have the Aggregation(Fan Out/In). The application is named as 'MFA_AggregationStockQuote'.

Refer the library that has the stock quote service application subflow.


After the Application has been created it should seem like this -


Create the flows that will be needed.

MF_AggReq

This flow will receive the request from service consumer on WebSphere MQ. The format of the message will be like - 

<StockQuote>
<Symbol>WASIX</Symbol>
<Symbol>VDAIX</Symbol>
</StockQuote>

The flow structure looks like this - 


The Aggregate Control is the start of the fan out. The compute node will create the individual request. After all the request are sent to AGG.IN, it will then send the actual message to AGG.CONT.IN. This actual message can be used to relate the actual request to the response.

The request from the consumer may contain the reply to queue and this is also saved for the Aggregate Reply.

DECLARE inRef REFERENCE TO InputRoot.XMLNSC.StockQuote.Symbol[1];
DECLARE sh NAMESPACE 'http://www.webserviceX.NET/';
WHILE LASTMOVE(inRef) DO
SET OutputRoot.MQMD = InputRoot.MQMD;
SET OutputRoot.XMLNSC.sh:GetQuote.sh:symbol = inRef;
PROPAGATE TO TERMINAL 'out';
MOVE inRef NEXTSIBLING REPEAT TYPE NAME;
END WHILE;

CALL CopyMessageHeaders();
SET OutputRoot.BLOB.BLOB = ASBITSTREAM(InputRoot.MQMD, InputRoot.Properties.Encoding, InputRoot.Properties.CodedCharSetId);
PROPAGATE TO TERMINAL 'out1';

MF_AggRep

MF_AggRep flow receives all the response from the services and then fan ins them using Aggregate Reply node. In this flow we also receives the reply from the control flow that contains the request. This request will be used to restore the MQMD of the request. If that is done and it contains the reply to queue the AGG.REP MQOutput node can be discarded and you may use the MQReply node.

Here is the code snippet used in the compute node -

DECLARE inRef REFERENCE TO InputRoot.ComIbmAggregateReplyBody.StockRep;
DECLARE I INT 1;
 
WHILE LASTMOVE(inRef) DO
IF EXISTS(inRef.XMLNSC.StockQuotes[]) THEN
SET OutputRoot.XMLNSC.StockQuotes.Stock[I]=inRef.XMLNSC.StockQuotes.Stock;
SET I = I+1;
ELSE
CREATE NEXTSIBLING OF OutputRoot.Properties 
DOMAIN('MQMD') 
PARSE(inRef.BLOB.BLOB
CCSID inRef.Properties.CodedCharSetId
TYPE 'MQMD');

END IF;
MOVE inRef NEXTSIBLING REPEAT TYPE NAME;
END WHILE;

MF_SvcInvoke

This flow will call the backend service and then send the response back to the queue specified in the MQReply to queue.


MF_AggCont

This flow just sends the message as it received.



If the flow runs successfully the output in the AGG.REP queue should be something like this - 

<StockQuotes>
<Stock>
<Symbol>WASIX</Symbol>
<Last>11.03</Last>
<Date>11/11/2015</Date>
<Time>6:45pm</Time>
<Change>-0.05</Change>
<Open>N/A</Open>
<High>N/A</High>
<Low>N/A</Low>
<Volume>0</Volume>
<MktCap>N/A</MktCap>
<PreviousClose>11.03</PreviousClose>
<PercentageChange>-0.45%</PercentageChange>
<AnnRange>N/A</AnnRange>
<Earns>N/A</Earns>
<P-E>N/A</P-E>
<Name>Wasatch Strategic Income Fund</Name>
</Stock>
<Stock>
<Symbol>VDAIX</Symbol>
<Last>31.23</Last>
<Date>11/11/2015</Date>
<Time>6:45pm</Time>
<Change>-0.11</Change>
<Open>N/A</Open>
<High>N/A</High>
<Low>N/A</Low>
<Volume>0</Volume>
<MktCap>N/A</MktCap>
<PreviousClose>31.23</PreviousClose>
<PercentageChange>-0.35%</PercentageChange>
<AnnRange>N/A</AnnRange>
<Earns>N/A</Earns>
<P-E>N/A</P-E>
<Name>Vanguard Dividend Appreciation </Name>
</Stock>

</StockQuotes>

The code base used for this can be found in the following location.