18 Kasım 2020 Çarşamba

Primes Sınıfı

Giriş
Şu satırı dahil ederiz
 import org.apache.commons.math3.primes.Primes;
Maven
Şu satırı dahil ederiz
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-math3</artifactId>
  <version>3.6.1</version>
</dependency>
isPrime metodu
Örnek ver

17 Kasım 2020 Salı

PassiveExpiringMap Sınıfı

Giriş
Şu satırı dahil ederiz
import org.apache.commons.collections4.map.PassiveExpiringMap;
constructor
Şöyle yaparız
PassiveExpiringMap.ConstantTimeToLiveExpirationPolicy<String, Integer>
  expirationPolicy = new PassiveExpiringMap.ConstantTimeToLiveExpirationPolicy<>(
            5, TimeUnit.SECONDS);

PassiveExpiringMap<String, Integer> expiringMap = new PassiveExpiringMap<>(expirationPolicy,
new HashMap<>());
get metodu
Örnek
Şöyle yaparız
expiringMap.put("one", Integer.valueOf(1));
expiringMap.put("two", Integer.valueOf(2));
expiringMap.put("three", Integer.valueOf(3));
int initialCapacity = expiringMap.size(); //Size is 3
System.out.println("initialCapacity = " + initialCapacity);
Assert.assertEquals(3, initialCapacity);

System.out.println("Sleeping...");
try { Thread.sleep(10000L); } catch (InterruptedException e) { }

int updatedCapacity = expiringMap.size(); //Size is 0
System.out.println("updatedCapacity = " + updatedCapacity);
Integer one = expiringMap.get("one");
Assert.assertNull(one);
Assert.assertEquals(0, updatedCapacity);

CLI Options Sınıfı

Giriş
Şu satırı dahil ederiz.
import org.apache.commons.cli.Options;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.DefaultParser; import org.apache.commons.cli.HelpFormatter;
Kullanım
- Options sınıfının add(), addOption(), addOptionGroup() metodları kullanılarak Option eklenir
- Daha sonra şu çağrı başarılıysa elimize parse edilmiş bir CommandLine nesnesi geçer. 
CommandLine cmd = CommandLineParser.parse(Options,args);
- Bu nesnenin getOptionValue() metodlarını kullanarak komut satırı parametrelerini alabiliriz.

Benim Kullandıklarım
Örnek
- Sıfır argument ile çağırabilirim. Ancak bu durumda bunu kontrol etmek lazım
- Tek argument ile çağırabilirim
- İki argument ile çağırabilirim
- Üç argument ile çağırırsam, sonuncusunu dikkate almaz
Option piuTypeOption = Option.builder("piuType")
  .required()
  //.hasArgs() //unlimited number of args
  .numberOfArgs(2)
  .optionalArg(true)
  .desc("...")
  .build();

Örnek
Şöyle yaparız
Options options = new Options();
Option token = new Option("t", "token", true, "token");
token.setRequired(true);
options.addOption(token);

Option projectname = new Option("p", "projectname", true, "project");
projectname.setRequired(true);
options.addOption(projectname);
     
Option branch = new Option("b", "branchname", true, "branch");
branch.setRequired(true);
options.addOption(branch);
     
Option pullreq = new Option("PR", "pullreq", true, "pullreq");
pullreq.setRequired(true);
options.addOption(pullreq);
CommandLineParser parser = new DefaultParser(); HelpFormatter formatter = new HelpFormatter(); CommandLine cmd = null; try { cmd = parser.parse(options, args); } catch (ParseException e) { System.out.println(e.getMessage()); formatter.printHelp("utility-name", options); System.exit(1); } String token1 = cmd.getOptionValue("token"); String projectname1 = cmd.getOptionValue("projectname"); String branch1 = cmd.getOptionValue("branchname"); String pullreq1 = cmd.getOptionValue("pullreq");
add metodu
Option ekler

Örnek - Argument Kullanmayan Mecburi Olmayan Option
Şöyle yaparız. OptionsBuilder deprecate edildi.
Options options = new Options();
options.add(OptionsBuilder.withLongOpt("help").create("h"));
options.add(OptionsBuilder.withLongOpt("version").create());
Örnek - Argument Kullanan Mecburi Olmayan Option
Şöyle yaparız. Yani -a şeklinde geçilebilir.
Option remove = new Option("a", true, "a description");
remove.setRequired(false);
remove.setOptionalArg(false);

Options options = new Options(); options.addOption(remove); try{ CommandLineParser parser = new DefaultParser(); CommandLine cmd = parser.parse(options, args); } catch (ParseException ex) { ... }

addOption metodu
Açıklaması şöyle
The addOption method has three parameters.
- The first parameter is a java.lang.String that represents the option.
- The second parameter is a boolean that specifies whether the option requires an argument or not. In the case of a boolean option (sometimes referred to as a flag) an argument value is not present so false is passed.
- The third parameter is the description of the option.
Örnek - Argument Kullanmayan Mecburi Olan Option
Şöyle yaparız
Options options = new Options();
Option token = new Option("t", "token", true, "token");
token.setRequired(true);
options.addOption(token);
Örnek - Argument Kullanan Mecburi Olmayan Option
Şöyle yaparız
Options options = new Options();
options.addOption("b", true, "some message");
addOptionGroup metodu
Örnek - Argument Kullanan Mecburi Option
Şöyle yaparız. Hem input hem de output parametreleri gerekir
OptionGroup group = new OptionGroup();
group.add(OptionsBuilder.withLongOpt("input").hasArg().create("i"));
group.add(OptionsBuilder.withLongOpt("output").hasArg().create("o"));
group.setRequired(true);

Options options = new Options();
options.addOptionGroup(group);



CLI DefaultParser Sınıfı

Giriş
Şu satırı dahil ederiz.
import org.apache.commons.cli.*;
CommandLineParser arayüzünü gerçekleştirir. Options yazısına bakabilirsiniz.

Örnek - İsteğe Bağlı + Mecburi Parametreler
Şöyle yaparız. Burada önce isteğe bağlı parametreler var mı diye bakılır. Yoksa mecburi parametreler kontrol edilir.
Options options1 = new Options();
options1.add(OptionsBuilder.withLongOpt("help").create("h"));
options1.add(OptionsBuilder.withLongOpt("version").create());

// this parses the command line but doesn't throw an exception on unknown options
CommandLine cl = new DefaultParser().parse(options1, args, true);

if (!cl.getOptions().isEmpty()) {

    // print the help or the version there.

} else {
    OptionGroup group = new OptionGroup();
    group.add(OptionsBuilder.withLongOpt("input").hasArg().create("i"));
    group.add(OptionsBuilder.withLongOpt("output").hasArg().create("o"));
    group.setRequired(true);

    Options options2 = new Options();
    options2.addOptionGroup(group);

    // add more options there.

    try {
        cl = new DefaultParser().parse(options2, args);

        // do something useful here.

    } catch (ParseException e) {
        // print a meaningful error message here.
    }
}

5 Kasım 2020 Perşembe

Avro

Apache Avro
Designing Data Intensive Applications kitabından bazı cümleler şöyle. 
Apache Avro is another binary encoding format that is interestingly different from Protocol Buffers and Thrift. It was started in 2009 as a subproject of Hadoop, as a result of Thrift not being a good fit for Hadoop’s use cases.
Avro also uses a schema to specify the structure of the data being encoded. It has two schema languages: one (Avro IDL) intended for human editing, and one (based on JSON) that is more easily machine-readable.
Apache Avro Thrift ve Protobuf'tan farklı olarak tag number'lar kullanmıyor. Designing Data Intensive Applications kitabından bazı cümleler şöyle. 
The writer’s schema and the reader’s schema
With Avro, when an application wants to encode some data (to write it to a file or database, to send it over the network, etc.), it encodes the data using whatever version of the schema it knows about—for example, that schema may be compiled into the application. This is known as the writer’s schema.

When an application wants to decode some data (read it from a file or database,receive it from the network, etc.), it is expecting the data to be in some schema, which is known as the reader’s schema. That is the schema the application code is relying on —code may have been generated from that schema during the application’s build process.

The key idea with Avro is that the writer’s schema and the reader’s schema don’t have to be the same—they only need to be compatible. When data is decoded (read), the Avro library resolves the differences by looking at the writer’s schema and the
reader’s schema side by side and translating the data from the writer’s schema into the reader’s schema. The Avro specification [20] defines exactly how this resolution works,...

For example, it’s no problem if the writer’s schema and the reader’s schema have their fields in a different order, because the schema resolution matches up the fields by field name. If the code reading the data encounters a field that appears in the writer’s schema but not in the reader’s schema, it is ignored. If the code reading the data expects some field, but the writer’s schema does not contain a field of that name, it is filled in with a default value declared in the reader’s schema.
Avro vs Parquet
Açıklaması şöyle
Avro and Parquet are both compact binary storage formats that require a schema to structure the data that is being encoded. The difference is that Avro stores data in row format and Parquet stores data in a columnar format.
In my experience, these two formats are pretty much interchangeable. In fact, Parquet natively supports Avro schemas i.e., you could send Avro data to a Parquet reader and it would work just fine.
Avro Maven Plugin
Avro dosyalarından java kodu üretmek içindir. Avro Maven Plugin yazısına taşıdım

Maven
Şu satırı dahil ederiz
<dependency>
  <groupId>org.apache.avro</groupId>
  <artifactId>avro</artifactId>
  <version>${avro.version}</version>
</dependency>
Eğer Apache Kafka ile kullanmak istiyorsak şu satırı dahil ederiz
<dependency>
  <groupId>io.confluent</groupId>
  <artifactId>kafka-avro-serializer</artifactId>
  <version>5.5.1</version>
</dependency>
avsc Dosyası
Sınıf ismi.avsc şeklindedir. Plugin ayarlarında sourceDirectory olarak /src/main/avro belirtildiği için 
bu dizindedir.

Aslında avro dosyası bir JSON nesnesidir. Açıklaması şöyle
Any Avro record has the following fields:
1. type
2. namespace
3. name
4. version
5. fields
- type alanı record olarak belirtilir. Başka ne değer alıyor bilmiyorum.
- name alanı sınıf ismini belirtir
- namespace sınıfın paketini belirtir
- version bu dosyanın sürüm sayısıdır
- fields alanı bir dizidir. Her field için name, type ve doc değerleri girilir. 
field type type olarak 
int
string 
kullanılabilir.

Örnek
Şöyle yaparız
{
  "type": "record",
  "name": "SupplierRiskData",
  "fields": [
    {"name": "supplierId", "type": "string"},
    {"name": "riskLevel", "type": "string"},
    {"name": "rating", "type": "int"}
  ]
}

Örnek
Şöyle yaparız. Bu avsc dosyasının üreteceği sınıf com.purnima.jain.avro.dto.PersonDto olur. 
{      
  "namespace": "com.purnima.jain.avro.dto",
  "type": "record",
  "name": "PersonDto",
  "fields": [
    {
      "name": "firstName",
      "type": "string",
      "doc": "the first name of a person"
    },
    {
      "name": "lastName",
      "type": "string",
      "doc": "the last name of a person"
    }
  ]
}
Sınıfı kullanmak için şöyle yaparız
PersonDto personDto = PersonDto.newBuilder()
  .setFirstName(...)
  .setLastName(...)
  .build();
Örnek
Şöyle yaparız
{
  "name": "Transaction",
  "type": "record",
  "namespace": "demo.camel",
  "fields": [
    {
      "name": "userid",
      "type": "string"
    },
    {
      "name": "transactionid",
      "type": "string"
    },
    {
      "name": "transactiontype",
      "type": "string"
    },
    {
      "name": "currency",
      "type": "string"
    },
    {
      "name": "amt",
      "type": "string"
    }
  ]
}
Örnek
Açıklaması şöyle
If we later want to add another field to the schema, we usually want to stay compatible with applications that only have an older version of the schema. In our example we add a field “data” that can either be a string or null (that is, the field data is optional).
Şöyle yaparız. Burada data isimli alan optional
{
  "namespace": "at.willhaben.tech.avro",
  "type": "record",
  "name": "SomeRecord",
  "fields": [
    {"name": "name", "type": "string"},
    {"name": "data", "type": ["null","string"], "default":null}
  ]
}