mq5.1-source.src.share.cclient.io.PortMapperTable.cpp Maven / Gradle / Ivy
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2000-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
/*
* @(#)PortMapperTable.cpp 1.3 06/26/07
*/
#include "PortMapperTable.hpp"
#include "../util/UtilityMacros.h"
/*
*
*/
PortMapperTable::PortMapperTable()
{
CHECK_OBJECT_VALIDITY();
init();
}
/*
*
*/
PortMapperTable::~PortMapperTable()
{
CHECK_OBJECT_VALIDITY();
reset();
}
/*
*
*/
void
PortMapperTable::init()
{
CHECK_OBJECT_VALIDITY();
brokerInstance = NULL;
brokerVersion = NULL;
version = NULL;
}
/*
*
*/
void
PortMapperTable::reset()
{
CHECK_OBJECT_VALIDITY();
DELETE( brokerInstance );
DELETE( brokerVersion );
DELETE( version );
serviceTable.reset();
}
/*
*
*/
iMQError
PortMapperTable::add(PortMapperEntry * portMapperEntry)
{
CHECK_OBJECT_VALIDITY();
iMQError errorCode = IMQ_SUCCESS;
UTF8String * entryName = NULL;
NULLCHK( portMapperEntry );
NULLCHK( portMapperEntry->getName() );
MEMCHK( entryName = (UTF8String*)portMapperEntry->getName()->clone() );
ERRCHK( serviceTable.addEntry(entryName, portMapperEntry) );
entryName = NULL; // owned by the serviceTable now
return IMQ_SUCCESS;
Cleanup:
DELETE( entryName );
return errorCode;
}
/**
* This reads the portmapper data from the specified string. (These
* comments were copied from PortMapperTable.java")
* The format of the data is:
*
*
* packet version>
*
* <.>
*
* Where:
*
* Portmapper numeric version string (ie "100").
* Packet version string (e.g. "2.0").
* Newline character (octal 012)
* Alphanumeric string. No embedded whitespace.
* A single space character
* Transport protocol. Typically "tcp" or "ssl"
* Service type. Typically "NORMAL", "ADMIN" or
* "PORTMAPPER"
* Numeric string. Service port number
* <.> The '.' (dot) character
*
* An example would be:
*
* 101 jmqbroker 2.0
* portmapper tcp PORTMAPPER 7575
* jms tcp NORMAL 59510
* admin tcp ADMIN 59997
* ssljms ssl NORMAL 42322
* .
*
*
*
*/
iMQError
PortMapperTable::parse(const UTF8String * const portServerOutput)
{
CHECK_OBJECT_VALIDITY();
ObjectVector * lineVector = NULL;
ObjectVector * fieldVector = NULL;
UTF8String * firstLine = NULL;
UTF8String * serviceLine = NULL;
UTF8String * portMapperVersionStr = NULL;
UTF8String * brokerInstanceName = NULL;
UTF8String * packetVersionStr = NULL;
PortMapperEntry * portmapperEntry = NULL;
iMQError errorCode = IMQ_SUCCESS;
reset();
RETURN_ERROR_IF_NULL( portServerOutput );
// Split portServerOutput into lines
ERRCHK( portServerOutput->tokenize(PORTMAPPER_LINE_SEPARATOR, &lineVector) );
CNDCHK( lineVector->size() == 0, IMQ_PORTMAPPER_INVALID_INPUT );
// Split off the first line which contains versioning information
ERRCHK( lineVector->remove(0, (void**)&firstLine) );
// Now tokenize into
// broker version>
// And make sure that we got the number of fields that we expected.
ERRCHK( firstLine->tokenize(PORTMAPPER_FIELD_SEPARATOR, &fieldVector) );
CNDCHK( fieldVector->size() < PORTMAPPER_VERSION_NUM_FIELDS,
IMQ_PORTMAPPER_INVALID_INPUT );
// Now get the portmapper version, broker instance name, broker version
ERRCHK( fieldVector->remove(0, (void**)&portMapperVersionStr) );
ERRCHK( fieldVector->remove(0, (void**)&brokerInstanceName) );
ERRCHK( fieldVector->remove(0, (void**)&packetVersionStr) );
// Return if the portMapperVersion isn't what we expect
CNDCHK( STRCMP( portMapperVersionStr->getCharStr(), PORTMAPPER_VERSION ) != 0,
IMQ_PORTMAPPER_WRONG_VERSION );
// Process each service name/port number value pair
while (lineVector->size() > 0) {
ERRCHK( lineVector->remove(0, (void**)&serviceLine) );
// We're done if we've reached the service description terminator
if (STRCMP( serviceLine->getCharStr(), PORTMAPPER_SERVICE_TERMINATOR ) == 0 ) {
DELETE( serviceLine );
break;
}
// Add this service description to the table
MEMCHK( portmapperEntry = new PortMapperEntry() );
ERRCHK( portmapperEntry->parse(serviceLine) );
ERRCHK( this->add(portmapperEntry) );
DELETE( serviceLine );
}
// Cleanup
portmapperEntry = NULL;
DELETE( lineVector );
DELETE( fieldVector );
DELETE( firstLine );
// Set member variables
this->brokerVersion = portMapperVersionStr;
this->brokerInstance = brokerInstanceName;
this->version = packetVersionStr;
return IMQ_SUCCESS;
// Cleanup everything in case there was an error
Cleanup:
DELETE( lineVector );
DELETE( fieldVector );
DELETE( firstLine );
DELETE( serviceLine );
DELETE( portMapperVersionStr );
DELETE( brokerInstanceName );
DELETE( packetVersionStr );
DELETE( portmapperEntry );
reset();
return errorCode;
}
/*
*
*/
iMQError
PortMapperTable::get(const char * serviceName,
const PortMapperEntry ** const portMapperEntry) const
{
CHECK_OBJECT_VALIDITY();
UTF8String serviceStr(serviceName);
return get(&serviceStr, portMapperEntry);
}
/*
*
*/
iMQError
PortMapperTable::get(const UTF8String * serviceName,
const PortMapperEntry ** const portMapperEntry) const
{
CHECK_OBJECT_VALIDITY();
RETURN_ERROR_IF_NULL( serviceName );
RETURN_ERROR_IF_NULL( portMapperEntry );
*portMapperEntry = NULL;
RETURN_IF_ERROR( serviceTable.getValueFromKey( serviceName,
(const Object** const)&(*portMapperEntry)) );
return IMQ_SUCCESS;
}
/*
*
*/
iMQError
PortMapperTable::getPortForProtocol(const UTF8String * protocol,
const UTF8String * type,
const PortMapperEntry ** const portMapperEntry)
{
CHECK_OBJECT_VALIDITY();
RETURN_ERROR_IF_NULL( protocol );
RETURN_ERROR_IF_NULL( type );
RETURN_ERROR_IF_NULL( portMapperEntry );
*portMapperEntry = NULL;
// Iterate through all of the entries looking for the entry that
// matches the given protocol and type.
RETURN_IF_ERROR( serviceTable.keyIterationStart() );
while (serviceTable.keyIterationHasNext()) {
const BasicType * serviceName = NULL;
const PortMapperEntry * entry = NULL;
RETURN_IF_ERROR( serviceTable.keyIterationGetNext(&serviceName) );
RETURN_IF_ERROR( serviceTable.getValueFromKey(serviceName,
(const Object**const)&entry) );
ASSERT( entry != NULL );
ASSERT( entry->name->equals(serviceName) );
if (entry->protocol->equals(protocol) &&
entry->type->equals(type))
{
*portMapperEntry = entry;
return IMQ_SUCCESS;
}
}
return IMQ_NOT_FOUND;
}
/*
* These are different port mapper outputs used for testing.
*/
const char * PORT_MAPPER_OUTPUT =
"101 jmqbroker 2.0\n"
"cluster tcp CLUSTER 59135\n"
"admin tcp ADMIN 59134\n"
"portmapper tcp PORTMAPPER 7676\n"
"jms tcp NORMAL 59133\n"
"httpjms http NORMAL 0\n"
".\n";
const char * PORT_MAPPER_OUTPUT_BOGUS_1 =
"101 jmqbroker2.0\n"
"cluster tcp CLUSTER 59135\n"
"admin tcp ADMIN 59134\n"
"portmapper tcp PORTMAPPER 7676\n"
"jms tcp NORMAL 59133\n"
"httpjms http NORMAL 0\n"
".\n";
const char * PORT_MAPPER_OUTPUT_BOGUS_2 =
"101 jmqbroker 2.0\n"
"cluster tcp CLUSTER 59135\n"
"admin tcp ADMIN59134\n"
"portmapper tcp PORTMAPPER 7676\n"
"jms tcp NORMAL 59133\n"
"httpjms http NORMAL 0\n"
".\n";
const char * PORT_MAPPER_OUTPUT_BOGUS_3 =
"101 jmqbroker 2.0\n"
"cluster tcp CLUSTER 59135\n"
"admin tcp ADMIN 59134 HELLO\n"
"portmapper tcp PORTMAPPER 7676\n"
"jms tcp NORMAL 59133\n"
"httpjms http NORMAL 0\n"
".\n";
const char * PORT_MAPPER_OUTPUT_BOGUS_4 =
"";
/*
*
*/
iMQError
PortMapperTable::test()
{
PortMapperTable pmt;
const PortMapperEntry * pme = NULL;
iMQError errorCode = IMQ_SUCCESS;
// Parse the valid input
UTF8String strToParse(PORT_MAPPER_OUTPUT);
RETURN_IF_ERROR( pmt.parse(&strToParse) );
// These are valid port names
RETURN_IF_ERROR( pmt.get("cluster", &pme) );
RETURN_IF_ERROR( pmt.get("admin", &pme) );
RETURN_IF_ERROR( pmt.get("portmapper", &pme) );
RETURN_IF_ERROR( pmt.get("jms", &pme) );
RETURN_IF_ERROR( pmt.get("httpjms", &pme) );
// These are invalid port names, so they should fail
RETURN_ERROR_IF( pmt.get("", &pme) == IMQ_SUCCESS, IMQ_PORTMAPPER_ERROR );
RETURN_ERROR_IF( pmt.get("jmsbogus", &pme) == IMQ_SUCCESS, IMQ_PORTMAPPER_ERROR );
// Now try parsing invalid input, each of the parses should fail
PortMapperTable pmt1,pmt2,pmt3,pmt4;
UTF8String strToParse1(PORT_MAPPER_OUTPUT_BOGUS_1);
UTF8String strToParse2(PORT_MAPPER_OUTPUT_BOGUS_2);
UTF8String strToParse3(PORT_MAPPER_OUTPUT_BOGUS_3);
UTF8String strToParse4(PORT_MAPPER_OUTPUT_BOGUS_4);
RETURN_ERROR_IF( pmt1.parse(&strToParse1) == IMQ_SUCCESS, IMQ_PORTMAPPER_ERROR );
RETURN_ERROR_IF( pmt2.parse(&strToParse2) == IMQ_SUCCESS, IMQ_PORTMAPPER_ERROR );
RETURN_ERROR_IF( pmt3.parse(&strToParse3) == IMQ_SUCCESS, IMQ_PORTMAPPER_ERROR );
RETURN_ERROR_IF( pmt4.parse(&strToParse4) == IMQ_SUCCESS, IMQ_PORTMAPPER_ERROR );
return IMQ_SUCCESS;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy