Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Scala: Proxy Design Pattern

DZone 's Guide to

Scala: Proxy Design Pattern

Want to learn more about structural design patterns in Scala? Check out this post where we look at using the Proxy design pattern.

· Java Zone ·
Free Resource


In our previous blogs, we discussed the decorator design pattern and the adapter design pattern. Now, its time to discuss another structural design pattern, the Proxy design pattern. We will implement the same EUGDPR problem using the Proxy design pattern, which we implemented using the adapter design pattern from our previous blog.

Problem Statement

Earlier, in many applications, all the user-specific details, like username, IP addresses, phone number, etc., were logged directly without scrambling itBut, after new data protection law, i.e. EUGDPR, it is now mandatory to scramble any user-specific data.

Solution

We will add a proxy class between our logging framework(slf4j) and our client.

What Is the Proxy Design Pattern?

proxy is a class functioning as an interface to something else.

The proxy design pattern focuses on providing a surrogate or placeholder for another object to control access to it.

We will create a  LoggerProxy class, which will be called before calling the Logging framework, and it will scramble the logs and call the logging framework methods.

ProxyDesignPatternUml

The build.sbt is a file that describes project settings. We are using the slf4j dependency to add a logging framework to our application.

name := "ProxyDesignPattern"

version := "0.1"

scalaVersion := "2.12.6"

// https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12
libraryDependencies ++= Seq("org.slf4j" % "slf4j-api" % "1.7.5",
    "org.slf4j" % "slf4j-simple" % "1.7.5")


The Client class is the class that will actually call the logging methods.

package com.knoldus

object Client extends App {
    val logger  = LoggerProxy.getLogger(this.getClass.getName)
    logger.info("Log Contains IP address: 127.0.0.1")
    logger.debug("UserName: jainnancy trying to sign in")
    logger.error("Password: abxyz is wrong ")
}


The  LoggerHelper class will scramble the logs.

package com.knoldus

class LoggerHelper {
    private val regex = "\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b"
    private val password = "Password: "
    private val userName = "UserName: "

    def scramble(message : String) = scrambleUsername(scrambleIp((scramblePassword(message))))

    private def scrambleUsername(message : String) = {
        if(message.contains(userName)) {
            val index = message.indexOf(userName) + userName.length()
            val textStartedPassword = message.substring(index)
            message.substring(0, index) + "X" + textStartedPassword.substring(textStartedPassword.indexOf(" "))
        }
        else {
            message
        }
    }

    private def scrambleIp(message : String) = message.replaceAll(regex, "XXX.XXX.XXX.XXX")

    private def scramblePassword(message : String) = {
        if(message.contains(password)) {
            val index = message.indexOf(password) + password.length()
            val textStartedPassword = message.substring(index)
            message.substring(0, index) + "X" + textStartedPassword.substring(textStartedPassword.indexOf(" "))
        }
        else {
            message
        }
    }
}


The LoggerProxy is the new class that will act as a proxy between the client  and logging framework and will make sure that logs are scrambled before logging.
 LoggerProxy will implement the Logger interface, which is defined in the slf4j framework.

package com.knoldus

import org.slf4j.{Logger, LoggerFactory, Marker}

object LoggerProxy extends Logger {
    private var logger : Logger = _
    private val loggerHelper = new LoggerHelper

    def getLogger(name : String) : Logger = {
        logger = LoggerFactory.getLogger(name)
        LoggerProxy
    }

    def getName : String = logger.getName

    def debug(msg : String) : Unit = logger.debug(loggerHelper.scramble(msg))

    def debug(format : String, arg : scala.Any) : Unit = logger.debug(loggerHelper.scramble(format),arg)

    def debug(format : String, arg1 : scala.Any, arg2 : scala.Any) : Unit = logger.debug(loggerHelper.scramble(format), arg1, arg2)

    def debug(format : String, arguments : AnyRef*) : Unit = logger.debug(loggerHelper.scramble(format), arguments)

    def debug(msg : String, t : Throwable) : Unit = logger.debug(loggerHelper.scramble(msg), t)

    def debug(marker : Marker, msg : String) : Unit = logger.debug(marker, loggerHelper.scramble(msg))

    def debug(marker : Marker, format : String, arg : scala.Any) : Unit = logger.debug(marker, loggerHelper.scramble(format), arg)

    def debug(marker : Marker, format : String, arg1 : scala.Any, arg2 : scala.Any) : Unit =
        logger.debug(marker, loggerHelper.scramble(format), arg1, arg2)

    def debug(marker : Marker, format : String, arguments : AnyRef*) : Unit = logger.debug(marker, loggerHelper.scramble(format), arguments)

    def debug(marker : Marker, msg : String, t : Throwable) : Unit = logger.debug(marker, loggerHelper.scramble(msg), t)

    def isWarnEnabled : Boolean = logger.isWarnEnabled

    def isWarnEnabled(marker : Marker) : Boolean = logger.isWarnEnabled(marker)

    def error(msg : String) : Unit = logger.error(loggerHelper.scramble(msg))

    def error(format : String, arg : scala.Any) : Unit = logger.error(loggerHelper.scramble(format), arg)

    def error(format : String, arg1 : scala.Any, arg2 : scala.Any) : Unit = logger.error(loggerHelper.scramble(format), arg1, arg2)

    def error(format : String, arguments : AnyRef*) : Unit = logger.error(loggerHelper.scramble(format), arguments)

    def error(msg : String, t : Throwable) : Unit = logger.error(loggerHelper.scramble(msg), t)

    def error(marker : Marker, msg : String) : Unit = logger.error(marker, loggerHelper.scramble(msg))

    def error(marker : Marker, format : String, arg : scala.Any) : Unit = logger.error(marker, loggerHelper.scramble(format), arg)

    def error(marker : Marker, format : String, arg1 : scala.Any, arg2 : scala.Any) : Unit =
        logger.error(marker, loggerHelper.scramble(format), arg1, arg2)

    def error(marker : Marker, format : String, arguments : AnyRef*) : Unit = logger.error(marker, loggerHelper.scramble(format), arguments)

    def error(marker : Marker, msg : String, t : Throwable) : Unit = logger.error(marker, loggerHelper.scramble(msg), t)

    def warn(msg : String) : Unit = logger.warn(loggerHelper.scramble(msg))

    def warn(format : String, arg : scala.Any) : Unit = logger.warn(loggerHelper.scramble(format), arg)

    def warn(format : String, arguments : AnyRef*) : Unit = logger.warn(loggerHelper.scramble(format), arguments)

    def warn(format : String, arg1 : scala.Any, arg2 : scala.Any) : Unit = logger.warn(loggerHelper.scramble(format), arg1, arg2)

    def warn(msg : String, t : Throwable) : Unit = logger.warn(loggerHelper.scramble(msg), t)

    def warn(marker : Marker, msg : String) : Unit = logger.warn(marker, loggerHelper.scramble(msg))

    def warn(marker : Marker, format : String, arg : scala.Any) : Unit = logger.warn(marker, loggerHelper.scramble(format), arg)

    def warn(marker : Marker, format : String, arg1 : scala.Any, arg2 : scala.Any) : Unit =
        logger.warn(marker, loggerHelper.scramble(format), arg1, arg2)

    def warn(marker : Marker, format : String, arguments : AnyRef*) : Unit = logger.warn(marker, loggerHelper.scramble(format), arguments)

    def warn(marker : Marker, msg : String, t : Throwable) : Unit = logger.warn(marker, loggerHelper.scramble(msg), t)

    def trace(msg : String) : Unit = logger.trace(loggerHelper.scramble(msg))

    def trace(format : String, arg : scala.Any) : Unit = logger.trace(loggerHelper.scramble(format), arg)

    def trace(format : String, arg1 : scala.Any, arg2 : scala.Any) : Unit = logger.trace(loggerHelper.scramble(format), arg1, arg2)

    def trace(format : String, arguments : AnyRef*) : Unit = logger.trace(loggerHelper.scramble(format), arguments)

    def trace(msg : String, t : Throwable) : Unit = logger.trace(loggerHelper.scramble(msg), t)

    def trace(marker : Marker, msg : String) : Unit = logger.trace(marker, loggerHelper.scramble(msg))

    def trace(marker : Marker, format : String, arg : scala.Any) : Unit = logger.trace(marker, loggerHelper.scramble(format), arg)

    def trace(marker : Marker, format : String, arg1 : scala.Any, arg2 : scala.Any) : Unit =
        logger.trace(marker, loggerHelper.scramble(format), arg1, arg2)

    def trace(marker : Marker, format : String, argArray : AnyRef*) : Unit = logger.trace(marker, loggerHelper.scramble(format), argArray)

    def trace(marker : Marker, msg : String, t : Throwable) : Unit = logger.trace(marker, loggerHelper.scramble(msg), t)

    def isInfoEnabled : Boolean = logger.isInfoEnabled

    def isInfoEnabled(marker : Marker) : Boolean = logger.isInfoEnabled(marker)

    def isErrorEnabled : Boolean = logger.isErrorEnabled

    def isErrorEnabled(marker : Marker) : Boolean = logger.isErrorEnabled(marker)

    def isTraceEnabled : Boolean = logger.isTraceEnabled

    def isTraceEnabled(marker : Marker) : Boolean = logger.isTraceEnabled(marker)

    def isDebugEnabled : Boolean = logger.isDebugEnabled

    def isDebugEnabled(marker : Marker) : Boolean = logger.isDebugEnabled(marker)

    def info(msg : String) : Unit = logger.info(loggerHelper.scramble(msg))

    def info(format : String, arg : scala.Any) : Unit = logger.info(loggerHelper.scramble(format), arg)

    def info(format : String, arg1 : scala.Any, arg2 : scala.Any) : Unit = logger.info(loggerHelper.scramble(format), arg1, arg2)

    def info(format : String, arguments : AnyRef*) : Unit = logger.info(loggerHelper.scramble(format), arguments)

    def info(msg : String, t : Throwable) : Unit = logger.info(loggerHelper.scramble(msg), t)

    def info(marker : Marker, msg : String) : Unit = logger.info(marker, loggerHelper.scramble(msg))

    def info(marker : Marker, format : String, arg : scala.Any) : Unit = logger.info(marker, loggerHelper.scramble(format), arg)

    def info(marker : Marker, format : String, arg1 : scala.Any, arg2 : scala.Any) : Unit =
        logger.info(marker, loggerHelper.scramble(format), arg1, arg2)

    def info(marker : Marker, format : String, arguments : AnyRef*) : Unit = logger.info(marker, loggerHelper.scramble(format), arguments)

    def info(marker : Marker, msg : String, t : Throwable) : Unit = logger.info(marker, loggerHelper.scramble(msg), t)

}


Hope you liked the blog. Thanks for reading!

References

Topics:
java ,proxy ,design patterns ,functional programming ,tutorial ,logger ,scala

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}