Forum Discussion

wimjan's avatar
wimjan
New Contributor
5 years ago
Solved

Calling java class from mock script

Hi,

 

I have a mock soap service and want to  do some magic with basic auth headers. When I try to import the java.utils.Base64 I get class not found errrors. Are the std java classes not on the classpath? 

 

Searching for this problem only gives examples of custom classes.  The documentation and API suggest only a limited set of XML/SOAP/JSON/REST classes.

 

Thnx,

Wim-Jan

 

 

Adding relevant piece of groovy:

note that it is to help clarify the issue and  imcomplete since I cut out or substituted sensitive info

 

import java.utils.Base64

def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def alert = com.eviware.soapui.support.UISupport;

log.info("------------- begin call -----------------------------");

def soapRequest = mockRequest.requestContent;
def headers = mockRequest.requestHeaders;
def incommingBasicAuth = headers.get("Authorization", "defaultAuth");
if (incommingBasicAuth == "defaultAuth") {
	log.info("no basicAuth header found!");
} else {
	String decodedAuth = Base64.getDecoder().decode;
	def uNamePw = decodedAuth.split(":");
  
	log.info("basicAuth header for " + uNamePw + " found!");
}

log.info("--- request will be forwarded to actual service ----")
  
String basicAuth = "";

if (incommingBasicAuth == "defaultAuth") {
	log.info("Set hardcoded username,password");
	String userCredentials = "someuser:somepw";
	basicAuth = "Basic " + new String(Base64.getEncoder().encode(userCredentials.getBytes()));
} else {
	log.info("use username password form incomming request");
	basicAuth = incommingBasicAuth;
}

def soapUrl = new URL("https://somewebservice.nl/")
def connection = soapUrl.openConnection()

// insert the basic auth header
connection.setRequestProperty("Authorization", basicAuth);

connection.setRequestMethod("POST")
connection.setRequestProperty("Content-Type", "text/html")
connection.setRequestProperty("SOAPAction", "")
connection.doOutput = true

Writer writer = new OutputStreamWriter(connection.outputStream);
writer.write(soapRequest)
writer.flush()
writer.close()
connection.connect()


def soapResponse = connection.content.text

// work as proxy, i.e. just return response recieved from https://somewebservice.nl/
requestContext.responseMessage = soapResponse

 

 

 

 

  • To use a Java class such as Base64 you must have the import and the jdk must be on the class path.  Goovy does include the following classes by default.

     

    import java.lang.*
    import java.util.*
    import java.io.*
    import java.net.*
    import groovy.lang.*
    import groovy.util.*
    import java.math.BigInteger
    import java.math.BigDecimal

     

    However in this case Groovy already has built in base64 encoding/decoding.  http://docs.groovy-lang.org/2.4.3/html/api/org/codehaus/groovy/runtime/EncodingGroovyMethods.html

     

    String encoded = 'AUTHORISATION-TOKEN'.bytes.encodeBase64().toString()
    log.info encoded

    byte[] decoded = encoded.decodeBase64()
    log.info new String(decoded)

     

    I'd question the need for mock to actually need to authorisatise, in most cases I test for their presence not their values.

4 Replies

  • nmrao's avatar
    nmrao
    Champion Level 3
    What if you ignore that particular import?
    • wimjan's avatar
      wimjan
      New Contributor

      I dont understand what you mean.

       

      If I dont use the class - java.utils.Base64 in this case - the mock works fine, but then I cannot mess around with the username password.

      If I use Base64 without the import It will throw a class not found error 

      idem if I use the import

       

      The only difference is the line where the class not found exception is thrown, the line with the import statement or the line where the Base64 is used...

      • MartinSpamer's avatar
        MartinSpamer
        Frequent Contributor

        To use a Java class such as Base64 you must have the import and the jdk must be on the class path.  Goovy does include the following classes by default.

         

        import java.lang.*
        import java.util.*
        import java.io.*
        import java.net.*
        import groovy.lang.*
        import groovy.util.*
        import java.math.BigInteger
        import java.math.BigDecimal

         

        However in this case Groovy already has built in base64 encoding/decoding.  http://docs.groovy-lang.org/2.4.3/html/api/org/codehaus/groovy/runtime/EncodingGroovyMethods.html

         

        String encoded = 'AUTHORISATION-TOKEN'.bytes.encodeBase64().toString()
        log.info encoded

        byte[] decoded = encoded.decodeBase64()
        log.info new String(decoded)

         

        I'd question the need for mock to actually need to authorisatise, in most cases I test for their presence not their values.