Saturday, July 17, 2021

django - adding Bootstrap to django website

What Is Bootstrap?

Bootstrap is a front-end development framework. It is a library of HTML, CSS, and JS, which is used to create modern websites and web applications.

Adding Bootstrap starter template:

Go to the https://getbootstrap.com/ and navigate to docs tab --starter template and copy and paste to index.html page.

Starter template:

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

    <title>Hello, world!</title>
  </head>
  <body>
    <h1>Hello, world!</h1>

    <!-- Optional JavaScript; choose one of the two! -->

    <!-- Option 1: Bootstrap Bundle with Popper -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

    <!-- Option 2: Separate Popper and Bootstrap JS -->
    <!--
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>
    -->
  </body>
</html>

Adding Navigation Bar :Adding Navigation Bar :
components --navbar
<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <div class="container-fluid">
    <a class="navbar-brand" href="#">Navbar</a>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav me-auto mb-2 mb-lg-0">
        <li class="nav-item">
          <a class="nav-link active" aria-current="page" href="#">Home</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">Link</a>
        </li>
        <li class="nav-item dropdown">
          <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
            Dropdown
          </a>
          <ul class="dropdown-menu" aria-labelledby="navbarDropdown">
            <li><a class="dropdown-item" href="#">Action</a></li>
            <li><a class="dropdown-item" href="#">Another action</a></li>
            <li><hr class="dropdown-divider"></li>
            <li><a class="dropdown-item" href="#">Something else here</a></li>
          </ul>
        </li>
        <li class="nav-item">
          <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
        </li>
      </ul>
      <form class="d-flex">
        <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
        <button class="btn btn-outline-success" type="submit">Search</button>
      </form>
    </div>
  </div>
</nav>

adding alerts: components--alerts
<div class="alert alert-warning alert-dismissible fade show" role="alert">
  <strong>Holy guacamole!</strong> You should check in on some of those fields below.
  <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
Adding Text Area :
Copy and paste the code given below to add text area:

 <div class="form-group">
    <label for="exampleFormControlTextarea1">Enter your text here and let Text Utils do the magic</label>
    <textarea class="form-control" name='text' id="exampleFormControlTextarea1" rows="9"></textarea>
  </div>
 Adding Switches :
Copy the below code and paste in the index.html file.

<div class="custom-control custom-switch">
  <input type="checkbox" name="removepunc" class="custom-control-input" id="customSwitch1">
  <label class="custom-control-label" for="customSwitch1">Remove Punctuations</label>
</div>

Adding Analyze Text Button :
Type the code given below to add the analyze text button :

<button type="submit" class="btn btn-dark mt-2">Analyze Text</button>
After successfully adding buttons and switches, add action attribute in the form tag. Write the following code :

<form action='/removepunc' method='get'>

Adding Bootstrap To analyze.html:
Copy the below code and paste it in analyze.html file : 
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">

<title>Text Utils</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="#">TextUtils.in</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavDropdown">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About Us</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contact Us</a>
</li>

</ul>
</div>
<form class="form-inline">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</nav>


<div class="alert alert-success alert-dismissible fade show" role="alert">
<strong>Success!Your Text Has Been Analyzed</strong>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>


<div class="container mt-5">
<h1>Your Analyzed Text -- {{purpose}}</h1>
<p>
{{ analyzed_text}}
</p>
</div>


<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
</body>
</html>

views.py code:

from django.http import HttpResponse
from django.shortcuts import render

def removePunc(request):
text=request.GET.get('text','default')
check=request.GET.get('removepunc','off')
if check == "on":
puncList= '''!()-[]{};:'"\,<>./?@#$%^&*_~'''
newText=''
for char in text:
if char not in puncList:
newText=newText + char

param= {"purpose": "Text after removed punctuation","analyzed_text": newText}
return render(request,'analyze.html',param)

# return HttpResponse(newText)

else:
param = {"purpose": "No Changes", "analyzed_text": text}
return render(request, 'analyze.html', param)
# return HttpResponse(text)
def navigationBar(request):
return render(request, 'navigationUrls.html')
def index(request):
# return HttpResponse("Hello")
return render(request,'index.html')

def about(request):
return HttpResponse("<h1>about</h1>")
def textAnalyze(request):
ttext = request.GET.get('text','default')
print(ttext)
return HttpResponse(ttext)
index.html:
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

<title>Text Analyzer</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="d-flex">
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</div>
</nav>
<div class="alert alert-warning alert-dismissible fade show" role="alert">
<strong>Welcome to Text Analyzer</strong> You can analyze your text here.
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<form action="/removePunctuation" methlod="get">
<div class="form-group">
<label for="exampleFormControlTextarea1">Enter your text here and let Text Utils do the magic</label>
<textarea class="form-control" name='text' id="exampleFormControlTextarea1" rows="9"></textarea>
</div>
<div class="custom-control custom-switch">
<input type="checkbox" name="removepunc" class="custom-control-input" id="customSwitch1">
<label class="custom-control-label" for="customSwitch1">Remove Punctuations</label>
</div>
<button type="submit" class="btn btn-dark mt-2">Analyze Text</button>
</form>


<!-- Optional JavaScript; choose one of the two! -->

<!-- Option 1: Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

<!-- Option 2: Separate Popper and Bootstrap JS -->
<!--
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>
-->
</body>
</html>

website:




Thursday, July 15, 2021

Fine grained APIs vs Coarse grained APIs

In coarsed grained API, your data is typically housed in a few large components while a fine grained API spreads it across a large number of smaller components. 

If your components are equal in size but vary in complexity and feature, this could lead to a coarse grained granularity. To build a fine grained API, you divide your components based on the cohesiveness and coordination of their functionalities.

Following considaration will you to pick the right granularity level:

1. Reusability: Fine grained win.

Since more information is spread across a large number of APIa, they typically offer greater reusability than their coarse grained counterparts.

2. Scalability: fine graned win.

Fine grained APIs are designed to easily scale and improve the performance of your APIs.

3. Security & analytics: Fine grained win.

A fine grained approach enables you to provide security at a more granular level. It also collects detailed analytics to help resolve prod issues.

4. Management Overhead: Coarse grained win

Fine grained means you end up with managing more APIs, it typically increases overhead 

5. Ability to deploy: fine grained win

Since a coarse grained API is more destructive, it is more difficult to move changes and advance new functionalities towards production.

6. Agility & innovation: fine grained win.

7. Resource usage: coarse grained win.

Fine grained ressources consume infrastructure resources at a faster pace than coarse grained API.

8. Complexity: fine grained win

With a fine grained approach complexity at your node or leave leavel is simple.

9. Performance: tie

With a fine grained API,you only expose the information needed by the client. Therefore saving bandwidth, offers reliable performence, risk slowing down the client application since they will need to make multiple calls to get the information they need. With a coarse grained approach clients make fewer calls for the information they need. But it comes with the risk of potentially exposing unwanted data.

10. Latency: fine grained.


Tuesday, July 13, 2021

OIC - Schedule parameters to get last run Date and Time

Introduction of schedule parameters:
  • Scheduled parameters are available across all scheduled runs of an integration and can be used to facilitate processing of data from one run to the next run for example, When performing batch processing, a scheduled parameter can be used to track the current position of batched data between runs.
  • Max 5 variables can be added.
  • Last time and date of the schedules integration to avoid the duplicate processing of data.

UseCase: We will create a schedule parameter lastRunDateTime and initialize with '' and log the last run date time and update the lastrundatetime with the schedulestartTime.

Detailed Steps:

Step1: Create a schedule orchestration integration and clicked on the Schduled icon and select Edit.



Step2: In the parameter name, click plus icon and enter a name lastRunDateTime and default value like ''. And close it.


Step3: drop logger activity and select Always as radio button and click on edit expression icon and below expression:
concat("last run date and time: ", $lastRunDateTime)




Step4: From the actions, add a assign activity and select the created selected parameter "lastRunDateTime" and add the value as startTime of the schedule. Validate and close.





Step5: add the tracking , save and activate and test



Run 1st time and see , lastRuntime is empty



Run 2nd time and see, lastRuntime is last start time of the schedule.



Run again and see, lastRunDateTime is the last start time of the schedule.


Run again and we can also update the lastRunDateTime.





Monday, July 12, 2021

OIC - log file naming convention

In the integrations, in error handling we need to create a log file to store the error details in a computing directory for support perspective. Basically we follow the below log file naming convention.

Naving convention:

<Integration name>_<current date yyyy-mm-dd><hours from date time>.<minutes from date time>.<seconds from date time>.log

In assign

Concat($self/nsmpr0:metadata/nsmpr0:integration/nsmpr0:name,"_",fn:current-date(),fn:hours-from-dateTime(fn:current-dateTime()),".",fn:minutes-from-dateTime(fn:current-dateTime()),".",fn:seconds-from-dateTime(fn:current-dateTime()),".log")

For example:

POC_RestServiceTest_2021-07-12z12.0.3.599.log


OIC - Integration Metadata Access

Many times we want to use the name of the integration, its version, Identifier and Instance id ans other environment and runtime specific  information inside the OIC integration flow. With this new feature called "Integration Meta data" we can dynamically fetch these details and we dont need to hardcode them.

Following metadata are available:

Self-integration:

  • Name
  • Identifier
  • Version
Self-runtime data:
  • Instance ID
  • Invoked by name
Self-environment data:
  • Service instance name
  • Base URL
Where we can use them:
These read only fields can be used in any orchestration like Assign, Log activity, Notificaton activity etc.

Steps to use meradata:

Step1: Create a new integration or edit an existing integration flow

Step2: Add a new Log action

Step3: Edit the log message and in the source tree you can see the list of metadata. Drag and drop the required metadata to the expression builder

Step4: Save and activate the integration

Step5: Trigger the integration flow using the endpoint. Go to Monitoring > Tracking page. Open the particular run and click on 'View Activity Stream' and you should see the Log message which logs the integration name etc.

Sunday, July 11, 2021

OIC - Common Integration Pattern Pitfalls and Design Best Practices

Common Integration Pattern Pitfalls and Design Best Practices:

Note the following best practices and integration pattern pitfalls to avoid when designing an integration.

  • Avoid Common Integration Pattern Pitfalls
  • Avoid Creating Too Many Scheduled Integrations
  • Synchronous Integration Best Practices
  • Design Long-Running or Time-Consuming Integrations as Asynchronous Flows
  • Time Outs in Service Calls During Synchronous Invocations
  • Parallel Processing in Outbound Integrations

Avoid Common Integration Pattern Pitfalls

  • Chatty Integrations
  • Scheduled Job that Never Stops Trying to Process
  • lmport an Externally Updated IAR File
  • Synchronous Integration Doing Too Much
  • Too Many Connections in an Integration
  • Read Files with Many Records'
  • Integrations Running Unchanged Despite Changing Business Needs

1. Chatty Integrations:

Use case: 
Synchronise records in a file or large data set with an external system.

Pitfall:
Use an invoke activity within a looping constuct to call external APIs for every record.

Why pitfall:
Downstream apps are receiving a large number of atomic requests. This puts the entire system under duress.

Best practices:
  • Leverage application capabilities to accept multiple records in a single request.
  • Leverage adapter capabilities to send a large data set as attachements or files.
  • Use a stage file action and use apend file option to send the file to the destination.

2. Scheduled job that never stops trying to process:

Use case:
Process records within a set of files with a tight SLA.

Pitfall:
The scheduled integration looks for all files to process and loops over all to sequentially process until no files remain.

Why pitfall:
If a large number of files exist, one run of a sheduled job executes for a long time and starves other jobs and may get terminated by the framework.

Best Practice:
  • Limit the number of files to process in a single scheduled run.
  • Use scheduled parameters to remember the last processed file foe the next run.
  • Invoke the run now command to trigger processing of the next file if waiting for the next scheduled run is not feasible. 

3. Import an externally updated IAR file:

Use case:
Need to leverage advanced XSL constructs that may not be avaialble in the mapper.

Pitfall:
Updating the IAR file externally and then importing it into Oracle integration.

Why pitfall:
Activation failures may occure.
This can lead to metadata inconsistency and validation failures.

Best Practice:
Use import map feature in oracle integration.


4. Synchronous Integration doing too much:

Use case: 
A request triggers complex processing involving enrichment and updates across multiple systems.

Pitfall:
Huge synchronous integration modeling a large number of invokes/conditional logic.

Why pitfall:
Susceptible to timeouts.
Blocking call - holds resources and starves other integrationa.

Best Practice:
  • Explore moving completely to an asynchronous integration - fire and forget , async response. Thus it will alao support  resubmission of failures.
  • Optimise sync processing with a coarse grained external API to replace multiple chatty calls.
  • Split into a sync integration containing mandatory processing before sending out a response and triggering separate asyn fire and flrget integrations for other processibg logic.

5. Too many connections in an integration

Use case:
As developers create integrations, they define their own connectiona pointing to the same application. This leads to many duplicate connections.

Pitfall:
Every developer creates their own connection using different set of configurarions/credentials.

Why pitfall:
High number of connections make manageability painful, specially when you need to update the endpoint, credentials etc. 

Best practice:
Have a custodian create needed connections and ensure duplicate connections of the same type are not created. 
Build a best practice for naming conventions and maintaining a set of configurarions.



6. Read files with many records

Use case:
Read a file with a large number of records and process individual records.

Pitfall:
Reading the entire file in memory using the read file option and processing record by record.

Why pitfall:
Consumes large amounts of momory and impacts other system procesing.

Best practice:
Download the file to the stage location using the download file option. 
Use the read file with segments options. Platform automatically processes segments in parallel. Platform brigs in only the portions of the file to the memory, as needed.

7. Integrarions running unchanged despite changing business needs

Use case:
Integrations/schedules created during the initial implementation continue to run even though your business requirements have changed over time.

Pitfall:
Integrations and scheduled jobs created during the initial product implementation are never re-evaluated against changing business needs.

Why pitfall:
Unnecessary runs of jobs that handle no work.
Clutter with dead integrations, life cycle management overheads and developer confusion.

Best practice:
Periodically analyze existing integrarions or schedules against current business needs.
Deactivate integrations that are no longer needed.


TBD.

Reference: Common Integration Pattern Pitfalls and Design Best Practices


Featured Post

11g to 12c OSB projects migration points

1. Export 11g OSB code and import in 12c Jdeveloper. Steps to import OSB project in Jdeveloper:   File⇾Import⇾Service Bus Resources⇾ Se...