4 Haziran 2023 Pazar

Tomcat Session Manager

Giriş
Tomcat Session Manager sanırım hem server.xml hem de context.xml içinde tanımlanabilir

HazelcastSessionManager
Örnek
Şöyle yaparız
<Context>
  ...
  <Manager className="com.hazelcast.session.HazelcastSessionManager"/>
  ...
</Context>
Tomcat İle Gelen Session Manager Sınıfları
Açıklaması şöyle
A session manager is a component that creates and maintains HTTP sessions for a web application. Tomcat provides two standard implementations of session manager: StandardManager and PersistentManager
StandardManager 
Açıklaması şöyle
The StandardManager is the default session manager for Tomcat. It stores active sessions in memory and optionally persists them to a file across application restarts1. You can configure the StandardManager by using the <Manager> element inside the <Context> element of your web application2
Örnek
Şöyle yaparız
<Manager>
  <SessionManager>
    <className>org.apache.catalina.session.StandardSessionManager</className>
    <maxActive>100</maxActive>
    <maxIdle>30</maxIdle>
    <sessionTimeout>30</sessionTimeout>
  </SessionManager>
</Manager>
Örnek
Şöyle yaparız
<Context>
  <Manager className="org.apache.catalina.session.StandardManager"
           maxActiveSessions="100"
           pathname="myapp_sessions.ser"
           persistAuthentication="true"/>
</Context>
PersistentManager 
Açıklaması şöyle
The PersistentManager is an optional session manager that stores active sessions that have been swapped out to a storage location, such as a file or a database. You can configure the PersistentManager by using the <Manager> element with a nested <Store> element inside the <Context> element of your web application
Örnek - FileStore
Hem PersistentManager hem de StandardManager session bilgisini diske yazabiliyor. Aradaki fark şöyle
StandardManager ... it stores all sessions in a single file of an applications temporary directory. 

With PersistentManager using FileStore the situation is different: every session is saved in a separate file, according to its JSESSIONID.
Şöyle yaparız
<Context>
  <Manager className="org.apache.catalina.session.PersistentManager"
           maxActiveSessions="100"
           maxIdleSwap="10">
    <Store className="org.apache.catalina.session.FileStore"
           directory="/tmp/sessions"/>
  </Manager>
</Context>
Örnek - JDBCStore
Session bilgisini saklamak için JDBC kullanır. Açıklaması şöyle
It will then use the store to maintain the session on each http request. Note that the documentation assumes that only one http request will be made by the same client at a time.

This will allow you to use non sticky session load balancer in front of your java ee servers.
Şöyle yaparız
<Valve className="org.apache.catalina.valves.PersistentValve" />
<Manager className="org.apache.catalina.session.PersistentManager"
  distributable="true"  processExpiresFrequency="1" maxIdleBackup="1" maxIdleSwap="0"
   minIdleSwap="0" >
  <Store className="org.apache.catalina.session.JDBCStore"
    driverName="org.postgresql.Driver"
    connectionURL="jdbc:postgresql://localhost:5432/develop_4_5_0?currentSchema=datasuite"
    connectionName="*" connectionPassword="*"
    sessionAppCol="app_name" sessionDataCol="session_data" sessionIdCol="jsession_id"
    sessionLastAccessedCol="last_access" sessionMaxInactiveCol="max_inactive"
    sessionTable="tomcat_session" sessionValidCol="valid_session" />
</Manager>

31 Mayıs 2023 Çarşamba

List.subList metodu

Sabit Büyüklüğe Ayırmak
Partition by Size diyelim
Örnek
Şöyle yaparız
public static <T> List<List<T>> partitionList(List<T> list, int partitionSize) {
  List<List<T>> partitionedList = new ArrayList<>();
  int size = list.size();

  for (int i = 0; i < size; i += partitionSize) {
    int end = Math.min(size, i + partitionSize);
    partitionedList.add(list.subList(i, end));
  }
  return partitionedList;
}
Örnek - Guava
Lists.partition() kullanılabilir

Örnek - Apache Commons
ListUtils.partition() kullanılabilir

Sabit Sayıda Parçalara Ayırmak
Number of Partitions diyelim
Örnek
Şöyle yaparız. Listeyi 6 parçaya ayırırız
List<Integer> mylist = ...
int size = mylist.size();
int parts = 6;
int partSize = size / parts;
List<List<Integer>> result = 
    IntStream.range(0, parts)
             .mapToObj(i -> mylist.subList(i * partSize, (i + 1) * partSize)))
             .collect(Collectors.toList());

30 Mayıs 2023 Salı

ArchUnit ClassFileImporter Sınıfı

Giriş
Şu satırı dahil ederiz
import com.tngtech.archunit.core.importer.ClassFileImporter;
importPackages metodu
Açıklaması şöyle
The returned object of type JavaClasses represents a collection of elements of type JavaClass, where JavaClass in turn represents a single imported class file. You can in fact access most properties of the imported class via the public API
Yani şöyle yapabiliriz
JavaClass clazz = classes.get(Object.class);
System.out.print(clazz.getSimpleName()); // returns 'Object'
Örnek
Şöyle yaparız
JavaClasses jc = new ClassFileImporter()
  .importPackages("com.baeldung.archunit.smurfs");


26 Mayıs 2023 Cuma

Monad

Giriş
Functional dillerde Monad, Function Composition için kullanılır

Örnek
Şöyle yaparız
bread = bake( mill(wheat) )
Java'da Monad yok. Ancak benzer bir sonucu iki farklı şekilde yapabiliriz.

1. Chaining Methods
2. Optional Kullanarak

1. Chaining Methods
Örnek
Şöyle yaparız
public Optional<Flour> mill(Wheat wheat) {
   // ...
}

public Optional<Bread> bake(Flour flour) {
   // ...
}

Optional<Bread> oopBread = harvest()
      .flatMap(wheat -> mill(wheat))
      .flatMap(flour -> bake(flour));
2. Optional Kullanarak
Diğer dillerde Maybe<>, Either<>, Optional<> gibi yapılar var Java'da sadece Optional var. Bu kullanım biraz daha Functional dillere benziyor. Ancak halen exception handling sıkıntısı var. Three Exception-Handling Alternatives Inspired by Functional Programming yazısına bakabilirsiniz

Örnek
Şöyle yaparız
public Optional<Flour> mill(Optional<Wheat> wheat) {
   // ...
}

public Optional<Bread> bake(Optional<Flour> flour) {
   // ...
}

Optional<Bread> fpBread = bake( mill( harvest() ) );

Reading Large Tables In Batches

1. SpringBoot Kullanıyorsak
PageRequest kullanılabilir
Örnek
Şöyle yaparız
PageRequest pageRequest = PageRequest.of(0,10);
Page<Account> page; List<Account> list; do { page = accountRepository.findAll(pageRequest); list = page.getContent(); page = page.next(); } while (!page.isEmpty());
2. JPA Kullanıyorsak
TypedQuery kullanılabilir
Örnek
Şöyle yaparız
int startPosition = 0;
int batchSize = 10;

while(true) {

  TypedQuery<Account> query = em.createQuery("SELECT a FROM Account a", Account.class);
  query.setFirstResult(startPosition);
  query.setMaxResults(batchSize_size);
  
   List<Account> list = query.resultList();
    if (list.size() == 0) {
      break;
    }
    startPosition += batchSize; 
}
3. SQL ile Offset + Limit
TypedQuery kullanılabilir
Örnek
Şöyle yaparız
Session session = em.unwrap(Session.class);
session.doReturningWork(new ReturningWork<>() {
    @Override
    public Integer execute(Connection connection) throws SQLException {
      int offsetPos = 0;
      
      PreparedStatement preparedStatement = connection
                .prepareStatement("SELECT * FROM ACCOUNTS LIMIT ? OFFSET ?");
      while (true) {
        preparedStatement.setInt (1, 10);
        preparedStatement.setInt (2, offsetPos);
        ResultSet resultSet = preparedStatement.executeQuery();
        if(!resultSet.next()) break; // break when finish reading
        do {
          System.out.println(resultSet.getString("user_id"));
        } while (resultSet.next());
        offsetPos += 10;
      }
    }
}
4. Statement.setFetchSize kullanılabilir
JDBC Statement Arayüzü yazısına bakınız


23 Mayıs 2023 Salı

Reading Large Files Line By Line

Giriş
Kullanılabilecek yöntemler şöyle
1. Files Sınıfı
2. BufferedReader Sınıfı
3. Scanner Sınıfı

Test İçin Büyük Dosya Yaratmak
Şöyle yaparız
public void prepFile() throws IOException {
  BufferedWriter bufferedWriter = Files.newBufferedWriter(Path.of(TARGET_FILE),
    StandardOpenOption.CREATE);
  IntStream.rangeClosed(1,100000000)
    .forEach(a-> write(bufferedWriter, a));
  bufferedWriter.flush();
}

public void write(BufferedWriter bufferedWriter, int a) {
  try {
    bufferedWriter.write(a + "\n");
  } catch (IOException e) {
    ...
    throw new RuntimeException(e);
  }
}
1. Files Sınıfı
Örnek
Şöyle yaparız
Path filePath = Paths.get("C:/temp/file.txt")
 
//try-with-resources
try (Stream<String> lines = Files.lines( filePath )) {
  lines.forEach(...); // Process the line
} catch (IOException e) { ... }
2. BufferedReader Sınıfı
Bu sınıf 2 şekilde kullanılabilir.
1. lines metodu
2. readLine metodu

lines metodu
Aslında bunun yerine Files.lines() çok daha kolay

Örnek
Şöyle yaparız
public void usingBufferedReaderAndLambda() throws IOException {
  try (BufferedReader bufferedReader = Files.newBufferedReader(Path.of(TARGET_FILE))) {
    bufferedReader.lines()
    .forEach(...);  // Process the line
  }
}
readLine metodu
Örnek
Şöyle yaparız
public void usingBufferedReader() throws IOException {
  try(FileReader fileReader = new FileReader(new File(TARGET_FILE))){
    BufferedReader bufferedReader = new BufferedReader(fileReader);
    String readLine;
    while((readLine = bufferedReader.readLine())!=null){
      // Process the line
    }
  }
}
3. Scanner Sınıfı
Bir örnek burada


Eski ElasticSearchHighLevel IndicesClient Sınıfı

exists metodu
Örnek
Şöyle yaparız
GetIndexRequest request = new GetIndexRequest(props.getIndex().getName());
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);

if (!exists) {
  CreateIndexRequest indexRequest = new CreateIndexRequest(props.getIndex().getName());
  indexRequest.settings(Settings.builder()
       .put("index.number_of_shards", props.getIndex().getShard())
       .put("index.number_of_replicas", props.getIndex().getReplica())
  );

  CreateIndexResponse createIndexResponse = client.indices()
    .create(indexRequest, RequestOptions.DEFAULT);
  if (createIndexResponse.isAcknowledged()&& createIndexResponse.isShardsAcknowledged()) {
      log.info("{} index created successfully", props.getIndex().getName());
  } else {
    log.debug("Failed to create {} index", props.getIndex().getName());
  }
}