quarta-feira, 1 de novembro de 2023

OAuth in B2B

While exposing APIs for integration with 3rd party applications, if the security authorization option falls to OAuth authorization framework then the proper grant to use is the Client Credentials.


One should try to ensure that the partner application is confidential, id est, deployed in a secure environment with restricted access to the application client credentials.


Client authentication is used as the authorization grant, no additional authorization request is needed. The access token that allows the application to consume the resources (under the scope) is generated immediately with no further steps.


Diagram from: https://alexbilbie.github.io/guide-to-oauth-2-grants/

OAuth RFC: https://datatracker.ietf.org/doc/html/rfc6749#section-10.8





segunda-feira, 30 de janeiro de 2023

Corporate alert notification SPAM

One thing that plagues modern companies is the misuse of alerting notifications. 

There are managers and run teams that every day receive hundreds of automated mails/SMS/mobile notifications. 

Is this meaningful in any manner? Do you believe that you can manage this amount of alerts in a proper manner? 

My view is that if you get any more than 1-3 alerts per day then this is not an alert it is either one of the following:

- A structural problem that needs to be fixed immediately  

- An incorrect notification set up that is meaningless for your business

For mail channel a good symptom that your alert notification is meaningless is if you create (or feel that you can create) a separate inbox for it with an automated rule. 

Alert notification should be only used for high priority and critical issues, otherwise it is best to build a nice dashboard that you can consult various times throughout the day. 


sexta-feira, 27 de janeiro de 2023

HTTP versioning

 What option are out there for Versioning in HTTP?


  1. media type versioning -> header accept:application/vnd.service.v2+json
  2. headers versioning -> custom header apiVersion=1
  3. URI versioning -> the version goes in the uri path /v1/uri
  4. request parameter versioning  -> the version goes in a argument  server/uri?version=1
The first two reduce the URI pollution. They might not work if client is behind a proxy that potentially blocks some headers of the HTTP request.
The bottom two allow caching and bookmarking. 

Easy choice it's to stick to bottom ones, more academic approach is to use top ones as one resource should have one and just one endpoint.

https://stackoverflow.com/questions/18905335/rest-versioning-url-vs-header

sexta-feira, 5 de agosto de 2022

Codility ParityDegree

I did this one by counting all the '0' at the right until we find the first 1.


For example 24 is 11000, we have 3 zeros this gives us the highest power of 2 that divides N.


For 28 we have 11100, we can only divide it by 2^2=4, for 10 we have 1010 we can only divide it by 2^1=2.
For 15 that is 1111, we cannot divide it by 2 but only by 2^0=1

// you can also use imports, for example: // import java.util.*; // you can write to stdout for debugging purposes, e.g. // System.out.println("this is a debug message"); class Solution { public int solution(int N) { // write your code in Java SE 8 String bin=Integer.toBinaryString(N); char binChar[]=bin.toCharArray(); int count=0; for (int i=bin.length()-1;i>=0 ;i--){ if (binChar[i]=='0') count++; else return count; } return count; } }

quarta-feira, 13 de julho de 2022

Codility MaxSliceSum

LocalMax > 0 this will be the interactions.



If local max never is >0 this will  be the result.




class Solution {

public int solution(int[] A) { // write your code in Java SE 8 int n=A.length; int maxSum=A[0]; int localMax=A[0]; for (int i =1;i<n;i++){ if(localMax>0) localMax=Math.max(0, localMax+A[i]); else localMax=Math.max(localMax, A[i]); maxSum= Math.max(maxSum, localMax); } return maxSum; }}

terça-feira, 12 de julho de 2022

Codility Fish problem

After some research I did find this exercice is meant to be solved with stacks. But for me in the context of the problem it doesn't make any sense.


I solved it with a queue, a new fish arrives downstream, then we should include it in the **tail**.


In problem for some reason they want us to make it in the head, althoug they specify the fishs all swim at the same speed. More anoying is that the samples work perfectly well like this.


  

50% solution

import java.util.*;


// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");

class Solution {
     public static int solution(int[] A, int[] B) {

            // write your code in Java SE 8
            int n = A.length;
            Queue<Integer> downstream = new LinkedList<>();
            int survUpstrean = 0;
            for (int i = 0; i < n; i++) {

                if (B[i] == 1) {
                    downstream.add(A[i]);
                }
                if (B[i] == 0 && downstream.size() > 0) {
                    while (downstream.size() > 0) {
                        if (A[i] > downstream.peek()) {
                            downstream.remove();
                        } else if (A[i] < downstream.peek()) {

                            break;

                        }
                    }
                }
                if (downstream.size() == 0) {
                    survUpstrean++;
                }
            }

            return survUpstrean+downstream.size();
        }
}


    

            return survUpstrean + downstream.size();

        }



100% replacing queue with stack


// you can also use imports, for example: import java.util.*; // you can write to stdout for debugging purposes, e.g. // System.out.println("this is a debug message"); class Solution { public static int solution(int[] A, int[] B) { // write your code in Java SE 8 int n = A.length; Stack<Integer> downstream = new Stack<>(); int survUpstrean = 0; for (int i = 0; i < n; i++) { if (B[i] == 1) { downstream.push(A[i]); } if (B[i] == 0 && downstream.size()>0) { while (downstream.size() > 0) { int currFish=downstream.pop(); if (A[i] < currFish) { downstream.push(currFish); break; } } } if (downstream.size() == 0) { survUpstrean++; } } return survUpstrean + downstream.size(); } }

segunda-feira, 11 de julho de 2022

Codility various from lessons

 


Nesting

// you can also use imports, for example: import java.util.*; // you can write to stdout for debugging purposes, e.g. // System.out.println("this is a debug message"); class Solution { public int solution(String S) { // write your code in Java SE 8 int res=0; Stack s = new Stack(); int n= S.length(); if (n%2!=0) return 0; for (char c: S.toCharArray()) { if (isOpenBracket(c)) s.push(c); else{ if (s.isEmpty()) return 0; char l = (char) s.pop(); if (!isPair(l,c)) return 0; } } if (s.isEmpty()) return 1; else return 0; } static Boolean isOpenBracket( char c){ if ( c=='(') return true; else return false; } public static Boolean isPair(char l, char r){ return l == '(' && r == ')'; } }


MaxProductOfThree

// you can also use imports, for example: import java.util.*; // you can write to stdout for debugging purposes, e.g. // System.out.println("this is a debug message"); class Solution { public int solution(int[] A) { // write your code in Java SE 8 int n=A.length; Arrays.sort(A); int max = Math.max((A[n-1]*A[n-2]*A[n-3]), (A[0]*A[1]*A[n-1])); max = Math.max(max, (A[0]*A[1]*A[n-2])); max = Math.max(max, (A[0]*A[1]*A[n-3])); return max; } }

PassingCars

O(N) 100% solution

// you can also use imports, for example:
// import java.util.*;

// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");

class Solution {
    public int solution(int[] A) {
        // write your code in Java SE 8
        final int MAXPASS=1000000000;
        int n= A.length;
        int pc=0;
        int carsPassed=0;
        int firstCar= Integer.MAX_VALUE;      

        int k=0; // number of ones - cars going west
        //count zeros
        for (int i=0; i<n; i++){
        // only count for 0 ≤ P < Q < N -> after first time a 0 appears    
        if (A[i]==1 && firstCar!= Integer.MAX_VALUE){
            k++;
        }    
       
        if(firstCar== Integer.MAX_VALUE && A[i]==0 )
            firstCar=i;
        }
        // all cars head the same way
        if (k==0 || k==n)
        return 0;

        // only count for 0 ≤ P < Q < N -> first time a 0 appears
        for (int i=firstCar; i<n; i++){
            if (A[i]==1)
            carsPassed++;

            if (A[i]==0){
                pc= pc+ (k-carsPassed);
            }

            if (pc>MAXPASS){
                return -1;
            }

        }


        return pc;
    }
}
O()