/* * Licensed Materials - Property of Perforce Software, Inc. * © Copyright Perforce Software, Inc. 2014, 2021 * © Copyright IBM Corp. 2009, 2014 * © Copyright ILOG 1996, 2009 * All Rights Reserved. * * Note to U.S. Government Users Restricted Rights: * The Software and Documentation were developed at private expense and * are "Commercial Items" as that term is defined at 48 CFR 2.101, * consisting of "Commercial Computer Software" and * "Commercial Computer Software Documentation", as such terms are * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4, * as applicable. */ package integration; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; /** * The request handler that handles requests issued from clients and directly * interacts with the backend system. * <p> * The client only knows the dispatcher, which integrates all access to a * simulated backend system. * <p> * * It is responsible for client registration. Before * sending requests, a client needs to register through the * <code>registerClientSystem</code> method to receive an unique * <i>system identifier</i>, which is used to uniquely identify * one client from others. * <p> * Requests are buffered in a request queue and handled in a FIFO * (first-come-first-serve) order. Once a request is handled, it is * removed from the request queue. * <p> * Requests are handled in separated threads. */ public abstract class RequestHandler { /** * Thread used to process requests. */ protected Thread processRequestThread; /** * Request queue. */ protected Vector<IntegrationRequest> requestQueue = new Vector<IntegrationRequest>(); /** * Logger used by the request handler. */ protected Logger log; /** * Number of request handler threads. */ protected static int requestHandlerThreadCount = 0; public RequestHandler(Logger logger) { logger.log(Level.INFO, "RequestHandler initialized"); this.log = logger; } /** * Should handle one request. */ protected abstract void handleRequest(Object request); /** * Should register a client and return an unique system identifier that * identifies that client. * * @param prefix The system identifier prefix to be used * @return An unique system identifier to be used by the client */ public abstract String registerClientSystem(String prefix); /** * Should unregister a client by releasing its unique system identifier. * * @param systemId the client's system identifier. */ public abstract void unregisterClientSystem(String systemId); /** * Returns the logger used by this instance. * * @return Logger */ protected Logger getLogger() { return this.log; } /** * Empties the request queue. */ public void clearRequests() { requestQueue.clear(); } /** * Adds request to the request queue. * * If the <code>processRequestThread</code> does not exist or is * dead, this method will start a new thread to process all the * pending requests. Otherwise, no new thread will be started * because the <code>processRequestThread</code> will process all * the pending requests. * * @param request The request acknowledged by the request handler */ public synchronized void addRequest(IntegrationRequest request) { if (request != null) { // Appends to the queue. requestQueue.add(request); // If the processRequestThread not initialized or is dead, start a // new thread to process the request. Else do nothing because // processRequestThread will automatically process all the requests in // the queue. if ((this.processRequestThread == null) || (!this.processRequestThread.isAlive())) { Thread newThread = new Thread(new Runnable() { Override public void run() { processingPendingRequest(); } }); // Assign new thread this.processRequestThread = newThread; //Name it processRequestThread.setName("Integration Request Handler - " + requestHandlerThreadCount++); // Start thread this.processRequestThread.start(); } //endif } } /** * This method returns the first pending request from queue. */ protected IntegrationRequest getPendingRequest() { IntegrationRequest req = null; synchronized (requestQueue) { if (!requestQueue.isEmpty()) { req = requestQueue.get(0); if (req != null) { // Remove it from the queue. requestQueue.remove(0); } } } return req; } /** * Processes all the requests in the request queue. * This method must be invoked from a Runnable object. */ protected void processingPendingRequest() { while (true) { IntegrationRequest req = getPendingRequest(); if (req != null) { handleRequest(req); } else { break; } } //end while } }