Sunday, December 1, 2019

Design Patterns

Singleton 
---------------
class App{
    private App(){}
    static App createInstance(){}
}


Factory
---------------
interface App{
    public void develop();
    public void test();
    public void debug();
    public void deliver();
}
public class IOSApp implements App{}
public class TVApp implements App{}
public class WatchApp implements App{}

class AppStoreFactory{
   public App createApp(AppType type) {
       App app;
       switch (type) {
       case IOS:
           app = new IOSApp();
           break;
       case TV:
           app = new TVApp();
           break;
       case GLASS:
           app = new GlassApp();
           break;
       default:
           app = new GlassApp();
           break;
       }
       return app;
   }
}

Composite
---------------
Compose objects into tree structures to represent part-whole hierarchies. Composite lets client treat individual objects and compositions of objects uniformly.

Employee
Manager implements Employee
VP extends Manager
SectionManager extends Manager
TeamLeader extends Manager
Developer implements Employee

Adapter
---------------
Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces.


Prototype
---------------
public abstract class App implements Cloneable {}
public class IOSApp extends App {}
public class WatchApp extends App {}


public class BasicAppCache {
     public void load() {}
     public App get(AppType type) {}
}

or

public class AdvancedAppCache {
    private App load(AppType type) {}
    public App get(AppType type) {}
}


public class AppFactory {
    BasicAppCache appCache;
    public App createApp(AppType type) {
        return this.appCache.get(type);
    }
}

public class AppStore {
    public static void main(String... args) {
        final App app = new AppFactory().createApp(AppType.WATCH));
    }
}


Proxy
--------------
Allows for object-level access control by acting as a pass-through entity or a placeholder object.

public interface Book {}
public class RealBook implements Book {}
public class ProxyBook implements Book {}
public class LibraryService {

}

Object-Oriented Design Principles (OODP)



1. DRY (Don't repeat yourself) : Don't duplicate code reusability is the best approach.

2. Encapsulate What Changes: Use the access specified wisely and not everything should be public (class/object/variable).

3. Open Closed Design Principle: Classes, methods or functions should be Open for extension (new functionality) and Closed for modification.

4. Single Responsibility Principle (SRP) : There should not be more than one reason for a class to change, or a class should always handle single functionality.

5. Dependency Injection or Inversion principle

6. Favor Composition over Inheritance : Always favor composition over inheritance. Composition allows changing the behavior of a class at run-time by setting property during run-time and by using Interfaces to compose a class we use polymorphism which provides flexibility to replace with better implementation at any time.

7. Liskov Substitution Principle (LSP) : Methods or functions which use the superclass type must be able to work with the object of subclass without any issue.

8. Interface Segregation Principle (ISP) : A client should not implement an interface if it doesn't use that. This happens mostly when one interface contains more than one functionality, and the client only needs one functionality and no other.

9. Programming for Interface not implementation 

10. Delegation principles : Don't do all stuff by yourself,  delegate it to the respective class. Classical example of delegation design principle is equals() and hashCode() method in Java.

Tuesday, July 16, 2019

Apache Reverse Proxy with mod_proxy

Follow the steps to install and configure apache as a reverse proxy. 

1. Install apache2 

    sudo apt-get update; sudo apt-get upgrade; sudo apt-get install apache2


2. Enable apache2 modules 

     sudo a2enmod proxy
     sudo a2enmod proxy_http
     sudo a2enmod proxy_balancer
     sudo a2enmod lbmethod_byrequests

3. Update apache2 default configuration file 

     sudo vi /etc/apache2/sites-available/000-default.conf

       <VirtualHost *:80>
              ProxyPreserveHost On
              ProxyPass / http://localhost:8080/
              ProxyPassReverse / http://localhost:8080/

              ErrorLog ${APACHE_LOG_DIR}/error.log
              CustomLog ${APACHE_LOG_DIR}/access.log combined
       </VirtualHost>

Multiple hosts:

<VirtualHost *:80>
    ProxyPreserveHost On
    ProxyPass /web http://localhost:8080/web
    ProxyPassReverse /web http://localhost:8080/web

    ProxyPass /micro http://localhost:8081/micro
    ProxyPassReverse /micro http://localhost:8081/micro
        
#ServerAdmin webmaster@localhost
#DocumentRoot /var/www/html

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>

4. Restart the apache2 server 
        sudo systemctl restart apache2





Saturday, March 2, 2019

Enable CORS on Wildfly

Cross-Origin Resource Sharing (CORS) response headers to Camunda REST engine in wildfly (standalone.xml) distribution.

<subsystem xmlns="urn:jboss:domain:undertow:3.0">

    <buffer-cache name="default"/>
    <server name="default-server">
        <http-listener name="default" socket-binding="http" redirect-socket="https"/>
        <host name="default-host" alias="localhost">
            <location name="/" handler="welcome-content"/>
            <filter-ref name="server-header"/>
            <filter-ref name="x-powered-by-header"/>
            <filter-ref name="Access-Control-Allow-Origin"/>
            <filter-ref name="Access-Control-Allow-Methods"/>
            <filter-ref name="Access-Control-Allow-Headers"/>
            <filter-ref name="Access-Control-Allow-Credentials"/>
            <filter-ref name="Access-Control-Max-Age"/>
        </host>
    </server>
    <servlet-container name="default">
        <jsp-config/>
        <websockets/>
    </servlet-container>
    <handlers>
        <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
    </handlers>
    <filters>
        <response-header name="server-header" header-name="Server" header-value="WildFly/10"/>
        <response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow/1"/>
        <response-header name="Access-Control-Allow-Origin" header-name="Access-Control-Allow-Origin" header-value="*"/>
        <response-header name="Access-Control-Allow-Methods" header-name="Access-Control-Allow-Methods" header-value="GET, POST, OPTIONS, PUT"/>
        <response-header name="Access-Control-Allow-Headers" header-name="Access-Control-Allow-Headers" header-value="accept, authorization, content-type, x-requested-with"/>
        <response-header name="Access-Control-Allow-Credentials" header-name="Access-Control-Allow-Credentials" header-value="true"/>
        <response-header name="Access-Control-Max-Age" header-name="Access-Control-Max-Age" header-value="1"/>
    </filters>
</subsystem>


For Testing: http://www.apirequest.io/



Monday, August 13, 2018

Migrate an Enterprise Capture Workspace


This can be accomplished by using the WLST commands "exportWorkspace" on the source Enterprise Capture system and "importWorkspace" on the target Enterprise Capture system.

The exact steps are :

1) Run the wlst command (.sh for Linux, .cmd for Windows) from the Middleware home /common/bin directory:

  wlst.sh

2) Connect to the Capture managed server:

    wls:/offline> connect("weblogic","welcome1","t3://localhost:16400")

3) Retrieve Workspace ID, which is passed to the export command.  To get a list of current workspaces and their IDs:

    wls:/content/serverConfig>listWorkspaces()

The list will look like the following:

         8 wkspace1

         6 fred-wk2

         7 test-capture1

4) Run the export command:

    wls:/content/serverConfig>exportWorkspace(8,'/home/isyed/wkspace1.xml')

5) Import the workspace to the same instance (only if you deleted the workspace since exporting) or a different Capture instance:

   wls:/content/serverConfig>importWorkspace('/home/isyed/wkspace1.xml')


Sunday, August 12, 2018

Multiple eclipse instances on Mac

OSX Eclipse Launcher utility plugin

Follow these simple instructions
  1. Go to help --> Eclipse Marketplace...
  2. Search for "OS X Eclipse laucher utility"
  3. Cick Install, Next, Finish and restart your eclipse.
Once the plugin is installed, click on File --> Open Workspace.  Here you go, a new instance of eclipse is opened with a new workspace.

Thursday, July 12, 2018

Advance Scripts for Oracle WebCenter Capture

More documentation can be found here: https://docs.oracle.com/cd/E29542_01/doc.1111/e28275/c01_intro.htm

Script to generate the logs:

----------------------------------------------------------------------------------------------
load("nashorn:mozilla_compat.js");

function logRPCEvent (rpc, funcName) {
var logger = rpc.getLogger();
logger.info("PrintRecogProcEvents.js entered function: " + funcName);
}

function initialize(rpc) { // RecognitionProcessorContext
logRPCEvent(rpc, "initialize");
}

function processBatch(rpc) { // RecognitionProcessorContext
logRPCEvent(rpc, "processBatch");
}

function restoreCaptureBatch(rpc) { // RecognitionProcessorContext
logRPCEvent(rpc, "restoreCaptureBatch");
}

function beginPhase(rpc) { // RecognitionProcessorContext
logRPCEvent(rpc, "beginPhase");
}

function endPhase(rpc) { // RecognitionProcessorContext
logRPCEvent(rpc, "endPhase");
}

function extractBatchItem(rpc) { // RecognitionProcessorContext
logRPCEvent(rpc, "extractBatchItem");
}

function barcodesFoundOnItem(rpc) { // RecognitionProcessorContext
logRPCEvent(rpc, "barcodesFoundOnItem");
}

function batchItemAllValidBarcodes(rpc) { // RecognitionProcessorContext
logRPCEvent(rpc, "batchItemAllValidBarcodes");
}

function determineSeparatorPage(rpc) { // RecognitionProcessorContext
logRPCEvent(rpc, "determineSeparatorPage");
}

function batchItemValidBarcode(rpc) { // RecognitionProcessorContext
logRPCEvent(rpc, "batchItemValidBarcode");
}

function determineDocType(rpc) { // RecognitionProcessorContext
logRPCEvent(rpc, "determineDocType");
}

function beginDatabaseLookup(rpc) { // RecognitionProcessorContext
logRPCEvent(rpc, "beginDatabaseLookup");
}

function determineIndexValues(rpc) { // RecognitionProcessorContext
logRPCEvent(rpc, "determineIndexValues");
}

function renameOrigCaptureDocTitle(rpc) { // RecognitionProcessorContext
logRPCEvent(rpc, "renameOrigCaptureDocTitle");
}

function createCaptureDoc(rpc) { // RecognitionProcessorContext
logRPCEvent(rpc, "createCaptureDoc");
}

function postProcess(rpc) { // RecognitionProcessorContext
logRPCEvent(rpc, "postProcess");
}

function endBatchProcess(rpc) { // RecognitionProcessorContext
logRPCEvent(rpc, "endBatchProcess");
}
----------------------------------------------------------------------------------------------

Script to Update the Date format 

----------------------------------------------------------------------------------------------
load("nashorn:mozilla_compat.js");
importClass(java.text.SimpleDateFormat);
importClass(java.util.Date);

function logRPCEvent(rpc, logText) {
    var logger = rpc.getLogger();
    logger.info("[WWW] - " + logText);
}

function determineIndexValues(rpc) { // RecognitionProcessorContext
    logRPCEvent(rpc, "determineIndexValues");
    convertDateFormat(rpc);
}



function convertDateFormat(rpc) {
    logRPCEvent(rpc, "convertDateFormat");
    var DOCUMENT_DATE_FIELD = "Document Date";

    var documentDate = getIndexID(rpc, DOCUMENT_DATE_FIELD);
    logRPCEvent(rpc, "Get Index Field Id: " + documentDate);

    var capturedDocument = rpc.getBle().getBatch().getDocuments().get(0);
    logRPCEvent(rpc, "Captured Document : " + capturedDocument);

    var indexValues = rpc.getDocument().getIndexValues();
    for (var i = 0; i < indexValues.size(); i++) {
        var iv = indexValues.get(i);
        if (iv.getFieldID().equals(documentDate)) {
            logRPCEvent(rpc, "FieldID: [" + iv.getFieldID() + "] FieldValue: [" + iv.getFieldValue() + "]");
            var documentDateCapturedValue = iv.getFieldValue();
            iv.setFieldValue(formatRequiredDate(documentDateCapturedValue));
        }
    }
}

// @Format the date to yyyy-MM-dd'T'HH:mm:ss'Z'
function formatRequiredDate(currentDate) {

    var REQUIRED_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'";
    var LOOKUP_DATE_PATTERN = "MM-dd-yyyy";
    var currentDateFormat = new SimpleDateFormat(LOOKUP_DATE_PATTERN);
    var inputDate = currentDateFormat.parse(currentDate);
    currentDateFormat.applyPattern(REQUIRED_PATTERN);

    return currentDateFormat.format(inputDate);
}

// @Return the field object from document
function getFieldDefination(document, field) {
    return document.getParentBatch().getWorkspace().getFieldDefinitions().findByName(field);
}

// @Get the index Id
function getIndexID(rpc, indexName) {
    var workspace = rpc.getWorkspaceEntity();
    var indexDef = findIndexDefinitionByName(workspace, indexName, rpc);

    if (indexDef != null) {
        var indexID = indexDef.getIndexFieldID();
    }
    logRPCEvent(rpc, " In getIndexID : indexID [" + indexID + "]");
    return indexID;
}

// @Get the index definition by name
function findIndexDefinitionByName(workspace, indexName, rpc) {
    logRPCEvent(rpc, " In findIndexDefinitionByName : Workspace [" + workspace + "], Index Name: [" + indexName + "]");
    var indexDefs = workspace.getIndexDefinitions();
    var size = indexDefs.size();
    var foundIndexDef = null;
    for (var i = 0; i < size; i++) {
        var indexDef = indexDefs.get(i);
        if (indexName.equals(indexDef.getFieldName())) {
            foundIndexDef = indexDef;
            break;
        }
    }
    logRPCEvent(rpc, " In findIndexDefinitionByName : foundIndexDef [" + foundIndexDef + "]");
    return foundIndexDef;
}
----------------------------------------------------------------------------------------------

Steps to configure in Capture:


  1. Copy the following code to a text file.
  2. Open the WebCenter Workspace Console.
  3. Select the desired Workspace.
  4. Select the "Advanced" train stop / tab.
  5. Click the "Add New Script" button.
  6. Select type "Recognition Processor" and name the script appropriately. For example, LogsRecProcEvents.
  7. Select the file created above and click submit.
  8. Select the "Processing" tab.
  9. Select the desired Recognition Processor job and click the Edit (pencil) icon.
  10. Go to the "Extensions" train stop / tab.
  11. Click the "Script" pulldown menu.
  12. Select the script created in the Advanced Tab, (e.g. LogsRecProcEvents).
  13. Click "Submit" to apply the script.



AWS EC2 - SSH locked with UFW

Need to update the instance's user data: 1. Stop the instance 2. Right click (windows) or ctrl + click (Mac) on the instance to open a c...