Saturday, February 18, 2023

The OpenAI chatGBT

I have been seeing chatGBT show up in my new feed for several months now. 

I went to chat.openai.com and tried it out.  I asked it to tell me about a hotel in Europe and it gave me great report. I was impressed. It would not tell me who would win 2023 world series though!

I regularly use MSN.com and I heard last year it was turning site over AI to generate the news content. 

Now, there is Microsoft getting into the game via Bing.com soon with the Bing chat .





Wednesday, December 28, 2022

KMS


KMS keys Documentation 


  •  AWS KMS replaced the term customer master key (CMK) with AWS KMS key and KMS key. The concept has not changed. To prevent breaking changes, AWS KMS is keeping some variations of this term.

Managing keys  - creating a KMS key
  • symmetric encryption KMS keys - "When you create an AWS KMS key, by default, you get a KMS key for symmetric encryption. This is the basic and most commonly used type of KMS key." 
  • asymmetric KMS keys - encryption or signing, as well as generate and validate HMAC tags using HMAC KMS keys
  • A logical representation of a cryptographic key is an AWS KMS key. 
  • Metadata of a KMS key includes 
    • the key ID
    • key specification
    • key use
    • creation date
    • description
    • key status
  • Most crucially, it includes a reference to the key material used when performing cryptographic operations with the KMS key.
  • Symmetric KMS keys and asymmetric KMS private keys are never left unprotected in AWS KMS. 
  • We must utilize AWS KMS to use or manage the KMS keys.
  • AWS KMS generates the key material for a KMS key by default. 
  • We are unable to extract, export, see, or handle this critical material. 
  • The public key of an asymmetric key pair is the lone exception, which we may export for usage outside of AWS.

More on keys:

The KMS keys that you create customer managed keys

The KMS keys that AWS services create in your AWS account are AWS Managed keys  

- You don't have to create or maintain the key or its key policy, and there's never a monthly fee for an AWS managed key.

- view the aws managed key 

- view the  key policies

- audit the keys use in AWS CloudTrail logs

-AWS managed keys appear on the AWS managed keys page of the AWS Management Console for AWS KMS. 

-You can also identify AWS managed keys by their aliases, which have the format aws/service-name

What is AWS CloudFormation? - AWS CloudFormation (amazon.com)

CloudFormation AWS KMS Key: Explained 

AWS KMS CloudFormation resources are accessible in all Regions that support AWS KMS and AWS CloudFormation. 

We may make advantage of AWS: KMS:: Key resource for creating and managing all KMS key types supported in a Region


Creating a key policy - AWS Key Management Service (amazon.com)


aws-kms-developer-guide/creating-resources-with-cloudformation.md at master · awsdocs/aws-kms-developer-guide · GitHub



AES - advanced encryption standard
CMK - customer master key
- asymetric - has public (encrpyt data) and private key (decrypt data) and must be used together 
- symetric - same key used for encryption and decryption
Customer manages or aws managed keys

KMS Access management : Control access using different AWS approaches including 
  • key policy (policy attached to key)
  •  iam policy (policy attached to principal user/role), 
  • grants [link] (attached programmatically)

KMS policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html)

  • administrator - admin actions ... add/enable etc a key
  • user - crypt actions... crypt/decypt etc

principal  who can perform actions is either an  iam user, iam role, root user

KMS requires policy for each customer managed key

can view key policy among other things for a key

Statement Id (SID) : Enable IAM User Permissions
- indicates explicitly that the root user  (or specific user) of this account is allowed which actions on specified resources. By specifying this root user here, allows to  enableIAM policy for all users in this account
. without this statement root user does not have access to key
Statement Id (SID) :  Allow access for key Administrators  
-for an administrator, allows for the administration actions of the key

Statement Id (SID) :  Allow use of the key 
- for a user, allow for cryptographic actions for the key

Statement Id (SID) :  Allow attachment of persistent resources
- for grants, manage who can do what action


Sunday, October 16, 2022

Stages and Futures



API:
  1. https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/CompletionStage.html
  2. https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/CompletableFuture.html


public class CompletableFuture<T> implements Future<T>, CompletionStage<T> 
- execute on ForkJoinPool.commonPool or pass own pool

runAsync - returns CompletableFuture<Void> ,takes Runnable<T>   
-  i.e. doesn't bring back an result

supplyAsync -  returns CompletableFuture<T>, takes Supplier<T>   
-  i.e.  brings back a result

Methods from CompletableFuture you can call once it is done completing its work:

theApply  :   CompletionStage<U> thenApply​(Function<? super T,​? extends U> fn)
- transform the response you received after Computable Future returns
- specify Function<T,R> as argument
- thenApplyAsync method is for running on different thread pool than the default

thenAccept:   CompletionStage<Void> thenAccept​(Consumer<? super T> action)
- its simply just consumes, it takes response Consumer<T> as argument but does not return anything
- thenAcceptAsync method is for running on different thread pool than the default


thenRun:  CompletionStage<Void> thenRun​(Runnable action)
- takes Runnable as argument, doesn't leverage the response
-  thenRunAsync  method is for running on different thread pool than the default

dependent future-  a stage takes in result of a stage it has dependency on:

thenCompose :  CompletionStage<U> thenCompose​(Function<? super T,​? extends CompletionStage<U>> fn)
- consumes, it takes  Function<T,R> as argument , and returns a Completable Future
- chains Futures and run them sequentially
- thenComposeAsync  method is for running on different thread pool than the default
 
combining future-  a stage takes in results of independent stage(s)

thenCombine  :  <U,​V> CompletionStage<V> thenCombine​(CompletionStage<? extends U> other, BiFunction<? super T,​? super U,​? extends V> fn)
- takes BiFunction<U,V,R> as argument and used to run multiple stages in parallel
- thenCombineAsync  method is for running on different thread pool than the default


-returns CompletableFuture<Void>

-returns CompletableFuture<Void>


-its simply just consumes and returns exception 

- its simply just consumes exception as argument





"CompletableFuture ... it allows you to build a pipeline of steps which can each be executed asynchronously, each step depending on the result of one or more previous steps."


"CompletionStage, the superinterface of CompletableFuture, which declares most of the methods that comprise the functionality of CompletableFuture."

" A stage completes upon termination of its computation, but this may in turn trigger other dependent stages"

"CompletionStage specifies most of the functionality of CompletableFuture. Class CompletableFuture adds a number of extra methods"

  • thenApply: Apply a function to the result of the previous stage 
  • thenAccept : Let a consumer deal with the result of the previous stage 
  • thenCombine: Apply a function to the results of both of two previous stages 
  • thenAcceptBoth: Let a consumer deal with the results of both of two previous stages thenCompose: Similar to thenApply, except that the function returns CompletionStage instead of MyClass
  • whenComplete : Handle the outcome of a stage, whether it's a result value or an exception
  • exceptionally: When an exception happened, replace the exception with a result value
  • handle : Handle the outcome of a stage and return a new value
  • toCompletableFuture : Convert the CompletionStage to a CompletableFuture


Sunday, July 24, 2022

Kubernetes world



I am learning about containers,  kubernetes, and cloud...

Microservices definition says it's a design approach to break up a monolith application into small independent components. 

containers : 

"A container is a standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another. "

"A Docker container image is a lightweight, standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries and settings."

"Containers are an abstraction at the app layer that packages code and dependencies together."  

"Virtual machines (VMs) are an abstraction of physical hardware turning one server into many servers."


Kubernetes is an open source technology to manage and orchestrate containers at enterprise scale.  



Container management is the process of organizing, adding, removing, or updating a significant number of containers 

For Kubernetes to run containers, it needs a container runtime, like Docker or containerd. The container runtime is the object that's responsible for managing containers

Architecture :

Cluster is a set of computers that you configure to work together and view as a single system. 

The cluster uses centralized software that's responsible for scheduling and controlling these tasks.

For example the cluster software may also respond to to changes in compute resource needs.

Kubernetes abstracts away complex container management tasks, and provides you with declarative configuration to orchestrate containers in different computing environments.


The computers in a cluster that run the tasks are called nodes.

"A node is the smallest unit of computing hardware in Kubernetes." [link]

The control planes  are the computers that run the scheduling software.

Kubernetes cluster contains at least one main plane and one or more nodes. Both the control planes and node instances can be physical devices, virtual machines, or instances in the cloud. The default host OS in Kubernetes is Linux, with default support for Linux-based workloads.

At least 1 master node and couple worker nodes (referred to just nodes)

A node in Kubernetes cluster is where compute workloads run. Each node communicates with control plane via the API serve Tom inform it about state changes in node.


 each node has kublet process running on it 

Kublet is a Kubernetes process that makes it possible for a cluster to communicate to each other and execute tasks on each nodes 

You package the container into a Kubernetes object called a pod. 

A pod is the smallest object that you can create in Kubernetes.



"Although working with individual nodes can be useful, it’s not the Kubernetes way. In general, you should think about the cluster as a whole, instead of worrying about the state of individual nodes" [link]

Resources

Tuesday, May 24, 2022

Java 8 streams

String[] keys = Arrays.stream(ShareModeType.values()).map(ShareModeType::getCode).toArray(String[]::new);

Optional<String> match = Arrays.stream(keys).filter(shareMode::equals).findAny();

actionTypeList = Stream.of(ActionType.values()).map(ActionType::getId).collect(Collectors.toSet());

public enum ResultStatusCode {
SUCCESS("I-FCP-REGREPO-0000", "Success", "Success"),
FAIL("F-FCP-REGREPO-0001", "Failed", "Failed"),
CUSIP_INVALID("F-FCP-REGREPO-0002", "Validation Error", "Invalid CUSIP"),
CUSIP_EMPTY("F-FCP-REGREPO-0003", "Validation Error", "Missing CUSIP"),
E_IND("F-FCP-REGREPO-0004", "Validation Error", "Invalid eIndicator"),
SRC_SYS_IND("F-FCP-REGREPO-0005", "Validation Error", "Invalid srcSysIndicator"),
FUND_TY("F-FCP-REGREPO-0006", "Validation Error", "Invalid Fund Type"),
CORE_TY("F-FCP-REGREPO-0007", "Validation Error", "Invalid Core Type"),
EFF_DATE("F-FCP-REGREPO-0008", "Validation Error", "Invalid date range"),
VER_DATE("F-FCP-REGREPO-0009", "Validation Error", "Invalid version date range"),
ORDER_BY("F-FCP-REGREPO-0010", "Validation Error", "Invalid Orderby"),
ORDER_DIR("F-FCP-REGREPO-0011", "Validation Error", "Invalid Order Direction"),
LIMIT_VAL("F-FCP-REGREPO-0012", "Validation Error", "Invalid limit"),
OFFSET_VAL("F-FCP-REGREPO-0013", "Validation Error", "Invalid offset value"),
DOC_EVENT_IND("F-FCP-REGREPO-0014", "Validation Error", "Invalid docEventIndicator"),
DOC_TY("F-FCP-REGREPO-0015", "Validation Error", "Invalid Document Type"),

PROCESSDATE_INVALID("F-FCP-REGREPO-0016", "Validation Error", "Invalid Process Date"),
PROCESSDATE_EMPTY("F-FCP-REGREPO-0017", "Validation Error", "Missing Process Date"),
GENERIC_ERR_MSG("F-FCP-REGREPO-0018", "System unavailable", "System unavailable");
//DB_EXC_ERR("F-FCP-REGREPO-0019", "Database Exception", "Database Exception"),


private final String code;
private final String title;
private final String detail;

private static Map<String, ResultStatusCode> map = new HashMap<String, ResultStatusCode>();

private ResultStatusCode(String code, String title, String detail) {
    this.code = code;
    this.title = title;
    this.detail = detail;
}

public String getTitle() {
return title;
}

public String getCode() {
return code;
}

public String getDetail() {
return detail;
}

static {
        for (ResultStatusCode resultStatusCode : ResultStatusCode.values()) {
            map.put(resultStatusCode.code, resultStatusCode);
        }
    }

public static ResultStatusCode valueOfGivenCode(String code) {
        return map.get(code);
    }

@Override
public String toString() {
return code + ": " + title;
}
}




https://howtodoinjava.com/swagger2/swagger-spring-mvc-rest-example/




List <ResultStatusCode> filteredList = errorList.stream().filter(x -> x.getTitle().equalsIgnoreCase("Validation Error")).collect(Collectors.toList());


static final String[] ORDERBY_ARRAY = { "CUSIP", "FUND_IND", "EFF_D", "VERSION_D", "E_FUND_IND", "DOC_TY_C",
"CORE_FUND_IND", "ACCESSKEY", "SRC_SYS_IND", "DOC_UPD_IND", "EXP_D" };



if (StringUtils.isNotEmpty(cusipParameters.getOrderBy())) {
if (!Arrays.stream(ORDERBY_ARRAY).anyMatch(cusipParameters.getOrderBy()::equals))
return ErrorCode.ORDER_BY;
}



public boolean RegexValidation(String cusip) {
String regex = "^[a-zA-Z0-9]{9}";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(cusip);

return matcher.matches();
}

public boolean DateValidation(String date) {
String rgx = "^((?:(?:1[6-9]|[2-9]\\d)?\\d{4})(-)(?:(?:(?:0[13578]|1[02])(-)31)|((0[1,3-9]|1[0-2])(-)(29|30))))$|^(?:(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(-)02(-)29)$|^(?:(?:1[6-9]|[2-9]\\d)?\\d{4})(-)(?:(?:0[1-9])|(?:1[0-2]))(-)(?:0[1-9]|1\\d|2[0-8])$";
Pattern pattern = Pattern.compile(rgx);
Matcher matcher = pattern.matcher(date);
return matcher.matches();
}



public boolean DateRangeValidation(String fromDate, String toDate) {
try {
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date1 = new SimpleDateFormat("yyyy-MM-dd").parse(fromDate);
Date date2 = new SimpleDateFormat("yyyy-MM-dd").parse(toDate);

if (date1.equals(date2))
return true;
else
return date1.before(date2);
} catch (Exception e) {
return false;
}
}




Tuesday, April 13, 2021

Spring paging

https://reflectoring.io/spring-boot-paging/ ; "Paging is the act of loading one page of items after another from a database, in order to preserve resources. This is what most of this article is about. Pagination is the UI element that provides a sequence of page numbers to let the user choose which page to load next."


https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/web/PagedResourcesAssembler.html

few tweaks to make it work with the spring

import org.springframework.data.web.PageableHandlerMethodArgumentResolver; 
import org.springframework.hateoas.client.LinkDiscoverer; 
import org.springframework.hateoas.client.LinkDiscoverers; 
import org.springframework.hateoas.mediatype.collectionjson.CollectionJsonLinkDiscoverer; 
import org.springframework.plugin.core.SimplePluginRegistry; 
import org.springframework.web.method.support.HandlerMethodArgumentResolver; 



 
@Configuration 
@EnableSwagger2  
MySwaggerConfig extends WebMvcConfigurationSupport { 
      @Override public void addArgumentResolvers(List argumentResolvers) {
             argumentResolvers.add(new PageableHandlerMethodArgumentResolver()); 
 } 


//https://stackoverflow.com/questions/58431876/why-hateoas-starts-creating-issue-for-spring-boot-version-2-2-x-during-startu 

 @Bean public LinkDiscoverers discoverers() { 
    List plugins = new ArrayList<>(); 
    plugins.add(new CollectionJsonLinkDiscoverer()); 
    return new LinkDiscoverers(SimplePluginRegistry.create(plugins)); 
 }



The pageable default page and size


page -
The default-pagenumber the injected Pageable should get if no corresponding parameter defined in request (default is 0). 

size -
The default-size the injected Pageable should get if no corresponding parameter defined in request (default is 10). 

sort -
The properties to sort by by default. 

value -
Alias for size() 






adding pagination with mongo

pass in size,page,sort...

?page=0&size=2
?sort=name&sort=email,asc

Saturday, March 14, 2020

Kafkanomics



Intro to Kafka link

Kafka install

https://towardsdatascience.com/tagged/kafka

http://cloudurable.com/blog/kafka-tutorial-kafka-consumer/index.html

http://cloudurable.com/blog/kafka-tutorial/index.html

https://kafka.apache.org/quickstart

https://www.javainuse.com/misc/apache-kafka-hello-world

https://www.confluent.io/blog/tutorial-getting-started-with-the-new-apache-kafka-0-9-consumer-client/

https://www.devglan.com/apache-kafka/apache-kafka-java-example

kafka consumer java  example
https://www.dataneb.com/post/kafka-producer-consumer-example-java

https://dev.to/thegroo/spring-kafka-producer-and-consumer-41oc

https://docs.spring.io/spring-kafka/reference/html/

https://www.baeldung.com/spring-kafka


kafka consumer KafkaTemplate

https://programming.vip/docs/spring-boot-integration-kafka-spring-kafka-in-depth-exploration.html



https://codenotfound.com/spring-kafka-consumer-producer-example.html

code: https://github.com/code-not-found/spring-kafka/tree/master/spring-kafka-hello-world/src/main/java/com/codenotfound/kafka

pom.xml key dependencies:



<dependency>

      <groupId>org.springframework.kafka</groupId>

      <artifactId>spring-kafka</artifactId>

    </dependency>



<dependency>

      <groupId>org.springframework.kafka</groupId>

      <artifactId>spring-kafka-test</artifactId>

      <scope>test</scope>

    </dependency>





For sending messages we will be using the KafkaTemplate which wraps a Producer and provides convenience methods to send data to Kafka topics



The template provides asynchronous send methods which return a ListenableFuture



https://docs.spring.io/spring-kafka/docs/2.2.0.RELEASE/reference/html/_reference.html#kafka-template



- ListenableFuture<SendResult<K, V>> send(String topic, V data);



 kafkaTemplate.send("helloworld.t", payload);



In the Sender class, the KafkaTemplate is auto-wired as the creation will be done further below in a separate SenderConfig class.


@Autowired
  private KafkaTemplate<String, String> kafkaTemplate;



Note: Note that the Kafka broker default settings cause it to auto-create a topic when a request for an unknown topic is received.


The creation of the KafkaTemplate and Sender is handled in the SenderConfig class.:

@Bean
  public KafkaTemplate<String, String> kafkaTemplate() {
    return new KafkaTemplate<>(producerFactory());
  }


@Bean
  public Sender sender() {
 

    return new Sender();

  }


In order to be able to use the Spring Kafka template, we need to configure a ProducerFactory and provide it in the template’s constructor.

@Bean
  public ProducerFactory<String, String> producerFactory() {
    return new DefaultKafkaProducerFactory<>(producerConfigs());
  }


the 'BOOTSTRAP_SERVERS_CONFIG' property that specifies a list of host:port pairs used for establishing the initial connections to the Kafka cluster


@Bean
  public Map<String, Object> producerConfigs() {
    Map<String, Object> props = new HashMap<>();
    // list of host:port pairs used for establishing the initial connections to the Kakfa cluster

    props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,
        bootstrapServers);
    props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,
        StringSerializer.class);
    props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,
        StringSerializer.class);
    
    


    return props;

  }



Above, a message in Kafka is a key-value pair with a small amount of associated metadata. As Kafka stores and transports Byte arrays, we need to specify the format from which the key and value will be serialized.

In this example we are sending a String as payload, as such we specify the StringSerializer class which will take care of the needed transformation


Other configs: https://kafka.apache.org/20/javadoc/org/apache/kafka/clients/producer/ProducerConfig.html





Like with any messaging-based application, you need to create a receiver that will handle the published messages. The Receiver is nothing more than a simple POJO that defines a method for receiving messages.


@KafkaListener(topics = "helloworld.t")
  public void receive(String payload) {
    LOGGER.info("received payload='{}'", payload);
    latch.countDown();
  }



Above, see the @KafkaListener annotation that creates a ConcurrentMessageListenerContainer message listener container behind the scenes for each annotated method
https://docs.spring.io/spring-kafka/api/org/springframework/kafka/annotation/KafkaListener.html :

Annotation that marks a method to be the target of a Kafka message listener on the specified topics.

To make this happen, a factory bean kafkaListenerContainerFactory

@Bean
  public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>> kafkaListenerContainerFactory() {
    ConcurrentKafkaListenerContainerFactory<String, String> factory =
        new ConcurrentKafkaListenerContainerFactory<>();
    factory.setConsumerFactory(consumerFactory());

    return factory;
  }

Above is CountDownLatch. This allows the POJO to signal that a message is received. This is something you are not likely to implement in a production application.

@EnableKafka
enables the detection of the @KafkaListener annotation that was used on the Receiver class.

defines the boostrap servers define din application properties file:

  @Value("${kafka.bootstrap-servers}")
  private String bootstrapServers;


@Bean
  public ConsumerFactory<String, String> consumerFactory() {
    return new DefaultKafkaConsumerFactory<>(consumerConfigs());
  }


We also specify a 'GROUP_ID_CONFIG' which allows to identify the group this consumer belongs to. Messages will be load balanced over consumer instances that have the same group id. see helloworld

'AUTO_OFFSET_RESET_CONFIG' to "earliest". This ensures that our consumer reads from the beginning of the topic even if some messages were already sent before it was able to startup.

@Bean
  public Map<String, Object> consumerConfigs() {
    Map<String, Object> props = new HashMap<>();
    // list of host:port pairs used for establishing the initial connections to the Kafka cluster
    props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,
        bootstrapServers);
    props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG,
        StringDeserializer.class);
    props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,
        StringDeserializer.class);
    // allows a pool of processes to divide the work of consuming and processing records
    props.put(ConsumerConfig.GROUP_ID_CONFIG, "helloworld");
    // automatically reset the offset to the earliest offset
    props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");

    return props;
  }

https://kafka.apache.org/20/javadoc/index.html?org/apache/kafka/clients/consumer/ConsumerConfig.html



Tuesday, November 20, 2018

Cloud Factorize



https://developers.redhat.com/blog/2017/06/22/12-factors-to-cloud-success/

  1. CodeBase i.e. GIT
All pieces of code tracked by revision identifier (code base same across all deploys, but diffent versions may be active in diffent deploys)
  1. Configuration
Anything different bewteen environments is externalized and fetched at run time (config vs code seperation) - config stored in environment
  1. Backing Service (attached resources)
All endpoints (web services, databases, queues) available thru abstraction layer (i.e. URL)
  1. Build, release, run
Strict separation of stages 1) building the app, combining app with configuration, starting app
  1.  Port Binding
App is self healing to automatically make available resources and remove failed resources
 
  1. Concurrency

Concurrency by scaling app horizontally  (Horizontal scaling means that you scale by adding more machines into your pool of resources whereas Vertical scalingmeans that you scale by adding more power (CPU, RAM) to an existing machine).
7. Disposibility
Robustness better when start and shut down quickly - allows for rapid elasticity scaling, deployment of changes, and recovery from crash
8. Logs
Treat logs as event streams  (consolidate logs to allow analytics to be added)

  1. Dependency

Declare and isolate dependency via tooling

  1. Processes

App executes as stateless processes (share nothing)
  1. Dev Prod parity
Keep env close as possible

  1. Admin Services
Run in replicated envoronment migrations

Sunday, June 25, 2017

Logi Reports

I have been doing Logi Reports since end of 2016. I continue to gain more knowledge in this area.

Resources:
https://devnet.logianalytics.com/
http://learninglogireport.blogspot.com/

Thursday, December 26, 2013

ACID and Eventual Consistency hoopla

We don't care if it takes a while for our post to show up on a blog or a social media outlet, but what about our balance in our bank account?

Good article on that topic linked to here:
http://bitmason.blogspot.com/2013/12/relearning-past-lessons.html

It is interesting after playing around with Cassandra's command line tool and how much it reminds you of SQL.  The fact that Cassandra allows you to tweak the consistency level is what you want I would think.

I think Relational is not what we always need.


Sunday, October 6, 2013

MongoDB - and so it begins...

I plan to start this course. I am not sure how far I will take it with all the things I have going on. But here is the details  M101J - MongoDB for Java Developers:
Learn everything you need to know to get started building a MongoDB-based app. This course will go over basic installation, JSON, schema design, querying, insertion of data, indexing and working with language drivers. In the course, you will build a blogging platform, backed by MongoDB. Our code examples will be in Java.
https://education.mongodb.com/courses

https://education.mongodb.com/dashboard

http://ed-blog.mongodb.com/

Friday, September 27, 2013

Walkthrough in learning Cassandra and Big Data

How much data is created in minute?

What Is a Big Data?

Big data is making us think of ways to harness the excessive amount of unstructured data that is generated on a daily basis.  Moreover, it is no surprise we have seen the introduction of many new Big Data technologies

There are now open source technologies now available to handle the more and more data created every day. Examples of companies who make use of these technologies to process large amounts of data on daily basis: Craigslist, Facebook, Twitter, eBay, wordpress.com, etc.

We learned OO programming, and told relational databases is what you use! Tear apart objects so they fit into relational!

Object databases came along. You didn’t have to tear apart objects so they fit into database. The failure of OO databases related to corporate controlling of data and the challenges evolving the schema

What do you do when data wont fit onto one server?

Distributed databases

Sharding : with a relational db might have to split tables into multiple partitions among servers to handle excessive amount of data .

Approach is to de-normalize since relationships spread across many servers, but what is the point of using relational database then?

Partitioning: Split data based on keys (i.e. use name to split keys among partition. However, distribution unbalanced. Solution is “Consistent Hashing” which equally distributes the data Highly available.

For example, why is it applications like Facebook and Twitter are always available? Handle this by making replicas among data in case a server node goes down. Replicating is sharing . Every time we update, make copy over another node.

Hadoop – a Big Data technology

Back in the day, Google wanted to crawl the entire internet and perform calculations on the data. At the time, they did not have enough money for a machine to handle this – They used cheap machines and linked the computers together.

Google wrote a paper on what they were doing known as Map Reduce. Nutch (a search engine) was doing similar work lead by computer scientist Doug Cutting. He read Google’s paper and created a prototype. Yahoo hired Cutting. He created the open source Hadoop platform and named the technology after his son’s yellow stuffed-elephant toy, which went on to become the platform’s logo.

Yahoo eventully spun off this side of the company into Hortonworks which would put Hadoop on Microsoft OS.


The NoSQL databases provide infinite scalability, fault  tolerance, high availibilty,  design-friendly lack of schema.

NoSql is the wrong name, but catchy. Really, it means not a rigid schema, more flexible to work with

Polyglot persistence – means can use multiple databases types to build an application

Need consistency with enterprise data. Eventual Consistency important? Bank yes, blog no .

With Enterprise data, NoSQL  is NOT an option. NoSQL appropriate for application data.

ACID is out of the equation, replaced by CAP.

CAP Theorem was developed by Professor Eric Brewer, Co-founder and Chief Scientist of Inktomi.

The theorem states, that a distributed system design, can offer at most two out of three desirable properties:

Consistency - Is the data I’m looking at now the same if I look at it somewhere else? if someone writes a value to a database, there after other users will immediately be able to read the same value back,

Availability – What happens if my database goes down? If a number of nodes fail in your cluster the distributed system can remain operational

Partition Tolerance - What if my data is on different networks? means that if the nodes in your cluster are divided into two groups that can no longer communicate by a network failure, again the system remains operational.

Big Table

The kind of processing that Google does required a high performance and reliable, but weak on consistency.

At time no database like this existed. Google created their own calling it Big Table  . Products such as web indexing, Orkut, blogger, Google earth , and part of Goggle App Engine use this.

Big table is a sparse, distributed, persistent multidimensional sorted map. The map is indexed by a row key, column key, and a timestamp; each value in the map is an uninterrupted array of bytes.

Several technologies were created based on the Big Table paper concepts. Examples include Dynamo from Amazon, the  Google App Engine (which is built on top of the lower level Big Table with extra capabilities), and many others such as Cassandra.

For example, Amazon uses Dynamo for many of their products such as their shopping cart. Their is a paper written by Amazon on this technology that is readily available.

Facebook created Cassandra which they open sourced and had used it in their email search tool.  HBase is a near-clone of Google’s BigTable, whereas Cassandra is a “BigTable/Dynamo hybrid”.


Cassandra is a column family database : grouping of columns . It is similar but not the same as a relational. For example, a customer may have data such as name address phone number, some might not have music data. Or some wont supply age.  Known as sparse where each row may not have same columns.


The Cassandra data model is a 4 or 5 dimensional hash described as follows:

 Column – a name /value / time stamp tuple

 { name: “twitter_handle”
    value: “RandysPizzaRtp”
    timestamp: “2013-03-20 11:30:00” }

Super Column
http://arin.me/post/40054651676/wtf-is-a-supercolumn-cassandra-data-model http://www.datastax.com/docs/1.0/ddl/column_family#about-super-columns

Super Column – a name /map tuple where value consists of an unlimited number of columns. No timestamp on these.

 colFamily1 = {
 name: “twitter_account”
 value: {
            {  name:” twitter_handle”,
                value:”DaveSportsfan”, “2013-03-20 11:32:00”
            }
            {name:” twitter_email”,
               value:”dbloom@nc.rr.com”, “2013-03-20 11:32:00”
            }
            {name:” twitter_language”,
             value:”English”,
            “2013-03-20 11:32
            }
  }
}


Column Family– a structure to group both the Columns and Super Columns. In other words, a slice of data corresponding to a particular key. Like a table in relational

 allTweets = {
tweet1: {
               handle: “davidmbloom", tweet: “Gators won today!"
 },
 tweet2 : {
              handle: “spurrier",
              tweet: “@davidmbloom That’s Great!",
             replytohandle: “davidmbloom"
 }
}



Keyspace - the outer grouping of the data. Like a schema in relational model. All the Column Families go inside the Keyspace.

Node - is a single server instance within a group of Nodes. In most cases, this is a single physical computer or a single virtual machine instance. 

Cluster - is a group of Nodes that distributes your work amongst them. Partitioner - responsible for distributing rows (by key) across nodes in the cluster.

Replication Factor - how many Nodes in the cluster you want a copy of the data to be on. Eventual Consistency - weak consistency by default . But, configurable.

The data type for a column name is called a comparator.

Within a row, columns are always stored in sorted order by their column name. The comparator specifies the data type for the column name, as well as the sort order in which columns are stored within a row.

The comparator may not be changed after the column family is defined.

 The data type for a column (or row key) value is called a validator.

 For static column families, you should define each column and its associated type when you define the column family using the column_metadata property.

 For dynamic column families (where column names are not known ahead of time), you should specify a default_validation_class (default validator for columns not in the column_metadata) instead of defining the per-column data types.

The Cassandra framework has evolved since it first was open sourced.

A few good links on the topic:


How to Get Cassandra
http://cassandra.apache.org/download/

CASSANDRA_HOME = C:\Java\apache-cassandra-1.2.8

 C:\Java\apache-cassandra-1.2.8\bin>cassandra-cli.bat

 Third party install of Cassandra:  http://planetcassandra.org/Download/DataStaxCommunityEdition

select your version of windows and msi installer

After the install. you should have the services listed on this page: http://www.datastax.com/documentation/gettingstarted/index.html?pagename=docs&version=quick_start&file=quickstart#getting_started/../getting_started/gettingStartedWindowsTrblShooting_c.html

 You will find C:\Program Files\DataStax Community\python\python.exe

 From the command line: > python cqlsh


git clone https://github.com/datastax/java-driver


package com.example.cassandra;

/*
 http://www.datastax.com/documentation/developer/java-driver/1.0/webhelp/index.html


*/

import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.Host;
import com.datastax.driver.core.Metadata;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Row;
import com.datastax.driver.core.Session;

public class SimpleClientQuery {
   private Cluster cluster;
   private Session session;
 
   private final String ksName = "cardinal02";

   public void connect(String node) {
      cluster = Cluster.builder()
            .addContactPoint(node).build();
      Metadata metadata = cluster.getMetadata();
      System.out.printf("Connected to cluster: %s\n",
            metadata.getClusterName());
      for ( Host host : metadata.getAllHosts() ) {
         System.out.printf("Datatacenter: %s; Host: %s; Rack: %s\n",
               host.getDatacenter(), host.getAddress(), host.getRack());
      }
      session = cluster.connect();
   

   }

   public void close() {
      cluster.shutdown();
   }

   public static void main(String[] args) {
      SimpleClientQuery client = new SimpleClientQuery();
      client.connect("127.0.0.1");
      client.createSchema();
      client.loadData();
      client.close();
   }
 
   public void createSchema() {
  session.execute("CREATE KEYSPACE " + ksName + " WITH replication " +
     "= {'class':'SimpleStrategy', 'replication_factor':3};");

  session.execute(
     "CREATE TABLE " + ksName + ".songs (" +
           "id uuid PRIMARY KEY," +
           "title text," +
           "album text," +
           "artist text," +
           "tags set<text>," +
           "data blob" +
           ");");
session.execute(
"CREATE TABLE " + ksName +  ".playlists (" +
           "id uuid," +
           "title text," +
           "album text, " +
           "artist text," +
           "song_id uuid," +
           "PRIMARY KEY (id, title, album, artist)" +
           ");");



   }
 
   public void loadData() {
  session.execute(
     "INSERT INTO " + ksName + ".songs (id, title, album, artist, tags) " +
     "VALUES (" +
         "756716f7-2e54-4715-9f00-91dcbea6cf50," +
         "'Way Cool Jr.'," +
         "'Reach For Sky'," +
         "'Ratt'," +
         "{'jazz', '2013'})" +
         ";");
session.execute(
"INSERT INTO " + ksName + ".playlists (id, song_id, title, album, artist) " +
     "VALUES (" +
         "2cc9ccb7-6221-4ccb-8387-f22b6a1b354d," +
         "756716f7-2e54-4715-9f00-91dcbea6cf50," +
         "'Way Cool Jr.'," +
         "'Reach For Sky'," +
         "'Ratt'" +
         ");");
ResultSet results = session.execute("SELECT * FROM " + ksName  + ".playlists " +
       "WHERE id = 2cc9ccb7-6221-4ccb-8387-f22b6a1b354d;");

System.out.println(String.format("%-30s\t%-20s\t%-20s\n%s", "title", "album", "artist",
      "-------------------------------+-----------------------+--------------------"));
for (Row row : results) {
   System.out.println(String.format("%-30s\t%-20s\t%-20s", row.getString("title"),
   row.getString("album"),  row.getString("artist")));
}
System.out.println();
   }
}


Cassandra Java Driver API - https://datastax-oss.atlassian.net/browse/JAVA