├── README.md ├── format_of_documents.md ├── sources.yml └── tutorials ├── actuators_and_monitoring_tools.md ├── agile_scrum.md ├── algorithms_complexity.md ├── algorithms_data_structures.md ├── algorithms_data_structures_comparison_table.md ├── algorithms_data_structures_graph.md ├── algorithms_data_structures_map.md ├── algorithms_data_structures_tree.md ├── algorithms_search.md ├── algorithms_sort.md ├── algorithms_sort_comparison_table.md ├── array_native.md ├── broker_platforms_activemq.md ├── broker_platforms_kafka.md ├── broker_platforms_terminology.md ├── c.md ├── c_build_phases.md ├── c_error_codes.md ├── c_memory_structure.md ├── c_plus_plus.md ├── c_sharp.md ├── c_standart_libraries.md ├── c_terminology.md ├── code_page_identifiers.md ├── containers_and_vm.md ├── css.md ├── css_selectors.md ├── database.md ├── database_cassandra.md ├── database_h2.md ├── database_nosql_terminology.md ├── database_pivot_table.md ├── database_sql_commands.md ├── database_sql_commands_quick_examples.md ├── date_time.md ├── elasticsearch_kibana_logstash.md ├── git.md ├── gradle.md ├── groovy.md ├── hardware.md ├── java.md ├── java_aspect.md ├── java_bean.md ├── java_bean_spring.md ├── java_future.md ├── java_hash_code.md ├── java_jdbc_and_orm.md ├── java_jsp_and_jsf.md ├── java_lambda_and_stream.md ├── java_loggers.md ├── java_maven.md ├── java_query_and_criteria_and_predicate.md ├── java_querydsl.md ├── java_reactive_streams.md ├── java_serializers.md ├── java_servlet_stream.md ├── java_spring.md ├── java_spring_and_javaee.md ├── java_spring_data.md ├── java_spring_microservices.md ├── java_spring_page.md ├── java_spring_security.md ├── java_spring_spel.md ├── java_test.md ├── java_test_junit.md ├── java_test_mockito.md ├── java_test_spring.md ├── java_thread.md ├── java_validators.md ├── javascript.md ├── javascript_babel.md ├── javascript_flux_redux_saga.md ├── javascript_new_features_by_version.md ├── javascript_npm.md ├── javascript_react.md ├── javascript_webpack.md ├── jenkins.md ├── language.md ├── language_paradigms.md ├── licences.md ├── literal_length.md ├── long_and_short_scale.md ├── lucene.md ├── mobile.md ├── network.md ├── network_dns.md ├── others.md ├── package_managers.md ├── pattern.md ├── pattern_ddd.md ├── pattern_enterprise_integration.md ├── pattern_mvc.md ├── pattern_types.md ├── payment_system_and_blockchain.md ├── principles_and_laws.md ├── python.md ├── regex.md ├── security.md ├── security_certificate.md ├── security_cryptography.md ├── security_jwt.md ├── security_keycloak.md ├── security_oauth.md ├── security_random_numbers.md ├── security_saml.md ├── security_uuid.md ├── solid.md ├── statistics_benchmarks_speed.md ├── unicode_and_multi_language_apps.md ├── unix_likes.md ├── unix_likes_commands.md ├── unix_likes_shell_syntax.md ├── web.md ├── web_custom_elements.md ├── web_http_headers.md ├── web_http_status_codes_iana.md ├── web_http_status_codes_microsoft.md ├── web_websocket.md ├── web_websocket_spring.md └── yml_xml.md /README.md: -------------------------------------------------------------------------------- 1 | # About this project 2 | 3 | - 💻 My personal tutorials and notes about computer engineering, technology and domain business. 4 | 5 | - 📚 Contents are mixed. Only a high-level index exist based on filename inside ["tutorials"](./tutorials) directory. 6 | 7 | - ✏️ Contents are written in Turkish or English. 8 | 9 | - 📐 All tutorials should follow these standards: ["format of documents"](./format_of_documents.md). 10 | -------------------------------------------------------------------------------- /format_of_documents.md: -------------------------------------------------------------------------------- 1 | 2 | # FORMAT/STANDARTS OF DOCUMENTS 3 | All tutorials should follow all below standards. 4 | 5 | ## TEXT (CONTENT) 6 | - Splitting any paragraph/text in to items is suggested. That makes easier to read and update the sentences. 7 | - All explanations/sentences should be short and simple. Wikipedia's "Simple English" language can be taken reference. 8 | - For above 2 rules [file:"agile_scrum.md"](./tutorials/agile_scrum.md) can be taken as reference example. 9 | 10 | ## MARKDOWN FILE 11 | - There are many Markdown languages (as it is explained on "Markdown" topic inside tutorials). In this project we use only __GitHub Flavored Markdown (or GFM)__ which is being supported by github.com and VSCode as default. 12 | - Bold words should be defined with double underscore character. (Even both CommonMark and GFM supports using double star as well) 13 | - Markdown allows HTML and CSS. However we don't use them. Because github.com ignores them (and other Markdown-viewers may ignore them). 14 | - Do not use > for code blocks. Always prefer ``` even for single-line code. 15 | - Do not break the syntax of the programming language as below example: 16 | 17 | ```java 18 | void methodA(){ 19 | ... 20 | } 21 | ``` 22 | 23 | Prefer below one: 24 | 25 | ```java 26 | void methodA(){ 27 | // other code here 28 | } 29 | ``` 30 | 31 | - All files are in UTF-8 format. But do not use all UTF-8 supported characters. Test each character in different input UI components before use it. Because some characters (especially icons) are not supporting by many document viewers/editors. As an example ▇ (full box) character is supporting by many viewers/editors. But the length is different on different viewer/editor. Therefore prefer # instead of ▇. 32 | - Each file should not be greater than 1 MB. Because of 2 following reasons: 33 | - Github.com does not show Markdown output (preview) files which are greater than 1 MB. 34 | - Better performance when editing and reading files (especially from mobile/tablets). 35 | 36 | ## REFERENCES (SOURCES) 37 | - There may be missing informations (it will always be there anyway), but the accuracy of the available information is very important. If we are not sure about the accuracy of a sentence, it should be mentioned that we have no any sources related to it. 38 | 39 | - The source of every simple sentence should not be specified to prevent the file to be big. 40 | 41 | - Each URL (even they are not source of any content) should be archived/cached on "archive.is" and "web.archive.org". Also they should backup locally as PDF and HTML format. The details (like archive date) should be given in [file:"sources.yml"](./sources.yml) file. 42 | 43 | - The image files should be saved as PDF only. There is no reason to save "PDF" or "image" files in HTML format. In those cases the source should be flag as "no_need_html_backup_of_pdf_or_image_files" on [file:"sources.yml"](./sources.yml) file. 44 | 45 | - All the details about the source file (like title, subtitle...), should be written directly inside articles. If the source file is video and the video player page does not contain extra information, then the page should be flag as "video_only_and_no_other_information_to_backup" on [file:"sources.yml"](./sources.yml) file. 46 | 47 | - If the source file size is too big and it does not contain important data then it should not be backup locally. Those sources should be marked as "content_is_not_important_and_too_big". 48 | 49 | - Source code or any other text output should saved also in multiple formats locally. Because of two reasons: 50 | - In some cases text copying is buggy from PDF files. In this cases we may need HTML file. 51 | - In some cases we may need to search in multiple source files via text based search engines like "grep". In this case, we will need HTML file (which is text based). 52 | - We may also need PDF files in long term. Because some HTML files (which is saved today) may not open %100 properly in the future (after 10 year later). There is no browser backward compatibility standards for web browsers. 53 | 54 | - When searching already archived URL's from "archive.is" or "web.archive.org" all below combinations should be try: 55 | - with and without hashtag (#) 56 | - http or https 57 | 58 | - Source ID's are immutable. They can be deleted but not updated. That means, if the number deleted, it can never be used again. (Otherwise they can be mixed in local backups). 59 | 60 | ## READING TUTORIALS 61 | - On mobile/tablet devices prefer a web browser to open any file (a text editor may freeze the UI on large files). 62 | - Do not export/convert files as PDF (A4) or any landscape file format. Because the tables does not fit on the page. The only stable format is "HTML" which supports landscape tables. 63 | 64 | ## TITLE FORMAT 65 | - Abbreviations should have a prefix "abb-tr", "abb-eng". Abbreviations must be written in the title. That makes easier to search with keywords. But the prefixes are optional. Prefixes (such as "abb-eng") does not have to be added (if not necessary). 66 | - Example-1: "app" is abbreviation of "application". This information is well known. 67 | - Example-2: If the title has Greek characters then we don't need "gr" prefix. 68 | 69 | Valid title examples: 70 | 71 | - > eng:application (or abb-eng:app or tr:uygulama or gr:πρόγραμμα) 72 | 73 | - > application (or app or tr:uygulama or gr:πρόγραμμα) 74 | 75 | - > application (or app or tr:uygulama or πρόγραμμα) 76 | 77 | - If an abbreviation is abbreviation of a proper name (independent of any language) it gets a prefix only: "abb". Example: 78 | 79 | > Kubernetes (or abb:K8s) 80 | 81 | - If a title has an older synonym, it gets "old-name" prefix. Example: 82 | 83 | > Solaris (or old-name:SunOS) 84 | 85 | If a title has an older name, that means the term is proper name. And proper names are independent of any language. Therefor it does not get a language keyword (eng, tr, gr...). 86 | 87 | - Any information about the title terminology should be written in the first sentence after the title. 88 | 89 | - Title should contain exact synonym words. The words in the title should not have close meanings to each other. Otherwise it can be mentioned in the next line. 90 | 91 | - In order to define the word within the paragraph, it needs to be defined same as in title format. Example: 92 | 93 | > Firefox is an open source application (or abb-eng:app or tr:uygulama) 94 | 95 | - Version lists/tables should have a title which suffixed with "version history". Example: 96 | 97 | - > "HTTP version history" 98 | - > "Android version history" 99 | 100 | This makes searching standardized. 101 | -------------------------------------------------------------------------------- /tutorials/actuators_and_monitoring_tools.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # ACTUATORS AND MONITORING TOOLS 5 | ############################ 6 | 7 | ############################ 8 | 9 | # Spring Boot Actuator 10 | Actuator kelime anlamı: 1. işletici, çalıştırıcı 2. uyarıcı 11 | 12 | Spring'e dependency olarak eklendiğinde, o Spring uygulaması içerisinde REST endpoint'leri açıyor ve bu endpoint'ler üzerinden health check, disk usage, heap dump gibi bilgiler dışarıya veriyor. 13 | 14 | http://localhost:8080/actuator -> bize Actuator'ın açtığı tüm metric gruplarının URL listesini döner. Liste aşağıdaki gibidir. Her URL, kendi içerisinde istediği bilgileri dışarıya açabilir. Bazı temel örnekler: 15 | 16 | - http://localhost:8080/actuator/metrics -> current thread count, current memory usage, system update, all Java classes 17 | - http://localhost:8080/actuator/beans -> all Spring beans 18 | - http://localhost:8080/actuator/env -> all environment variables (her prop "app.yml", "bootstrap yml", Kubernetes'ten mi gelip gelmediği detayı ile birlikte yazıyor) 19 | - http://localhost:8080/actuator/info -> information about Spring boot 20 | - http://localhost:8080/actuator/trace -> all REST endpoints 21 | 22 | Örneğin; "Kubernetes Java client"; Pod (container) name, namespace gibi bilgileri actuator/info'dan döndürüyor. Kubernetes isterse farklı bir URL'den bunları sunabilirdi. ama "Kubernetes Java client" geliştiricileri bu URL'den döndürecek şekilde geliştirme yapmış (standart olması açısından). 23 | 24 | • • • • • • • • • • • • • • • • • • • • • • • • 25 | 26 | • • • • • • • • • • • • • • • • • • • • • • • • 27 | 28 | • • • • • • • • • • • • • • • • • • • • • • • • 29 | 30 | # Micrometer 31 | JVM uygulamaları için facade kütüphanesidir. Bu kütüphane JVM based uygulamamız dışarı Spring-Actuator gibi bilgi vermektedir. Spring-Actuator bilgileri dışarı açarken belli bir formatta/standartta sunmaz. oysa Micrometer birçok monitoring tool'a destek verecek şekilde bunları dışarı açar. 32 | 33 | Micrometer'ın support ettiği monitoring tool'lar: 34 | 35 | AppOptics, Azure Monitor, Netflix Atlas, CloudWatch, Datadog, Dynatrace, Elastic, Ganglia, Graphite, Humio, Influx/Telegraf, JMX, KairosDB, New Relic, Prometheus, SignalFx, Google Stackdriver, StatsD, Wavefront. 36 | 37 | Micrometer JVM uygulamalarında Spring-Actuator ile de entegreli çalışabilir. eğer istenirse Spring-Actuator'sız, saf Java projesinde de çalışabilir. 38 | 39 | • • • • • • • • • • • • • • • • • • • • • • • • 40 | 41 | • • • • • • • • • • • • • • • • • • • • • • • • 42 | 43 | • • • • • • • • • • • • • • • • • • • • • • • • 44 | 45 | # Grafana 46 | - birçok kaynaktan verileri çekerek, bunları kendisinin sunduğu web arayüzünden visualise eden bir yazılımdır. Topladığı dataları anlık olarak gösterir. Grafana herhangi bir veriyi toplayabilir. örnekler: 47 | - sadece metric'te okuyabilir: http://localhost:8080/metrics 48 | - PostgreSQL gibi RDBMS'lerde sadece bellirlediğimiz SQL sorguları çalıştırır ve o sorguların sonucunu kendi veritabanında toplar (örnek son 1 dakikadaki toplam siparişler: "SELECT count from Order WHERE date>(now-1m)"). 49 | - Prometheus'tan, PostgreSQL'den okduğu gibi veri okuyablir. Grafana özellikle time-series data yönetimini çok iyi yaptığından dolayı Prometheus gibi data-source'lardan ve __time series DB (or TSDB)__ konularından çok bahsedilir. 50 | 51 | - Grafana sadece şu zamanlarda kaynaktan data okur: 52 | - manuel query çalıştırdığımızda gider ve o data-source'tan bilgiyi alır. 53 | - dashboard'lar arkada query çalıştırır. ne sıklıkla query'nin execute edileceği, yine dashboard'un config'inden ayarlanır. 54 | 55 | - Grafana üzerinden API key oluşturulabilir. Bu key'ler ile, Java gibi client'larımız aracılığı ile Grafana'ya query execute ettirebiliriz. 56 | 57 | - API key yerine, Grafana web-UI üzerinde de query atabiliriz. Bu query'ler zaten dashboard oluşturmak için kullanılan query'lerle aynıdır. 58 | 59 | - "Query Editor", Web-UI'daki "expore" sekmesindeki query oluşturmıza yarayan, auto-complete seçenekleri sunan HTML componentlerdir. 60 | 61 | Query editor bir query generate eder. bu query her data-source için ayrı bir formatta ve mantıktadır. örnek: 62 | 63 | PostgreSQL için query: 64 | 65 | ``` 66 | SELECT hostname FROM host WHERE region IN($region) 67 | ``` 68 | 69 | PromQL için query: 70 | 71 | ``` 72 | query_result(max_over_time([${__range_s}s]) != ) 73 | ``` 74 | 75 | Bu sebeple "query editor" data-source değiştirildiğinde (seçildiğinde) çok farklı bir component halini alabilir. 76 | 77 | - Grafana kendi configurasyonlarını (aşağıdaki liste) kaydetmek için RDBMS (default'ta SQLite) kullanır: 78 | - user list to login Grafana Web UI 79 | - data sources connection info (ip, port, username, password...) 80 | - user generated dashboards 81 | 82 | • • • • • • • • • • • • • • • • • • • • • • • • 83 | 84 | • • • • • • • • • • • • • • • • • • • • • • • • 85 | 86 | • • • • • • • • • • • • • • • • • • • • • • • • 87 | 88 | # Prometheus 89 | Grafana'nın alternatifidir. Grafana ile en temel farkı Grafana DB'yi kendi tutmazken, Prometheus kendi DB'si mevcuttur (Bu DB time series DB'dir.). Fakat Prometheus'un visualizing modülü Grafana gibi başarılı değildir. 90 | 91 | Prometheus bağımsız bir servis olarak ayağa kalkar. önceden her servisin healt (örneğin Spring'deki Actuator endpoint'leri) URL'si Prometheus'a tanıtılır. Prometheus bu URL'lere giderek düzenli olarak data çeker ve kendi database'sine kaydeder. 92 | 93 | # exporter 94 | Prometheus dünyasında "exporter"; okuduğu data'yı Prometheus'un anlayacağı formata çeviren yazılımdır. Piyasada neredeyse her yazılım Prometheus'a metric'lerini atabilmek için kendi exporter'ını geliştirmiştir. örnekler: 95 | - https://github.com/danielqsj/kafka_exporter 96 | - https://github.com/infinityworks/docker-hub-exporter 97 | 98 | Bazı yazılımlar ise default'ta direk Prometheus'un anlayacağı formatta metric sunmaktadır. örnekler: 99 | - Kubernetes 100 | - RabbitMQ 101 | - Zipkin 102 | 103 | • • • • • • • • • • • • • • • • • • • • • • • • 104 | 105 | • • • • • • • • • • • • • • • • • • • • • • • • 106 | 107 | • • • • • • • • • • • • • • • • • • • • • • • • -------------------------------------------------------------------------------- /tutorials/algorithms_data_structures_comparison_table.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # ALGORITHM DATA STRUCTURES COMPARISON TABLE 5 | ############################ 6 | 7 | ############################ 8 | 9 | # Complexity values of operations for each data strcuture 10 | 11 | | Data Structure | (Average) Access | (Average) Search | (Average) Insertion | (Average) Deletion | (Worst) Access | (Worst) Search | (Worst) Insertion | (Worst) Deletion | (Worst) Space Complexity | 12 | |--------------------|------------------|------------------|---------------------|--------------------|----------------|----------------|-------------------|------------------|--------------------------| 13 | | Array | Θ(1) | Θ(n) | Θ(n) | Θ(n) | O(1) | O(n) | O(n) | O(n) | O(n) | 14 | | Stack | Θ(n) | Θ(n) | Θ(1) | Θ(1) | O(n) | O(n) | O(1) | O(1) | O(n) | 15 | | Queue | Θ(n) | Θ(n) | Θ(1) | Θ(1) | O(n) | O(n) | O(1) | O(1) | O(n) | 16 | | Singly-Linked List | Θ(n) | Θ(n) | Θ(1) | Θ(1) | O(n) | O(n) | O(1) | O(1) | O(n) | 17 | | Doubly-Linked List | Θ(n) | Θ(n) | Θ(1) | Θ(1) | O(n) | O(n) | O(1) | O(1) | O(n) | 18 | | Skip List | Θ(log(n)) | Θ(log(n)) | Θ(log(n)) | Θ(log(n)) | O(n) | O(n) | O(n) | O(n) | O(n log(n)) | 19 | | Hash Table | N/A | Θ(1) | Θ(1) | Θ(1) | N/A | O(n) | O(n) | O(n) | O(n) | 20 | | Binary Search Tree | Θ(log(n)) | Θ(log(n)) | Θ(log(n)) | Θ(log(n)) | O(n) | O(n) | O(n) | O(n) | O(n) | 21 | | Cartesian Tree | N/A | Θ(log(n)) | Θ(log(n)) | Θ(log(n)) | N/A | O(n) | O(n) | O(n) | O(n) | 22 | | B-Tree | Θ(log(n)) | Θ(log(n)) | Θ(log(n)) | Θ(log(n)) | O(log(n)) | O(log(n)) | O(log(n)) | O(log(n)) | O(n) | 23 | | Red-Black Tree | Θ(log(n)) | Θ(log(n)) | Θ(log(n)) | Θ(log(n)) | O(log(n)) | O(log(n)) | O(log(n)) | O(log(n)) | O(n) | 24 | | Splay Tree | N/A | Θ(log(n)) | Θ(log(n)) | Θ(log(n)) | N/A | O(log(n)) | O(log(n)) | O(log(n)) | O(n) | 25 | | AVL Tree | Θ(log(n)) | Θ(log(n)) | Θ(log(n)) | Θ(log(n)) | O(log(n)) | O(log(n)) | O(log(n)) | O(log(n)) | O(n) | 26 | | KD Tree | Θ(log(n)) | Θ(log(n)) | Θ(log(n)) | Θ(log(n)) | O(n) | O(n) | O(n) | O(n) | O(n) | 27 | -------------------------------------------------------------------------------- /tutorials/algorithms_data_structures_graph.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # ALGORITHMS DATA STRUCTURES GRAPH 5 | ############################ 6 | 7 | ############################ 8 | 9 | # çizge (or graph or tr:graf or çizit) 10 | - Any node may have a connection to any node (even circular). 11 | - For example: A node can be connected to 10 other nodes. In the same graph another node may connect only 1 node. 12 | 13 | Some terms: 14 | - __vertex (plural vertices) or node (or düğüm)__: vertex; "tepe noktası" anlamına gelir. 15 | - __edge__: Each connection of a specific node. 16 | - __Order__: The number of vertices in the graph. 17 | - __Size__: The number of edges in the graph. 18 | - __vertex degree (or düğümün derecesi)__: number of edges of a vertex. 19 | - __isolated vertex__: a vertex which does not have any connections(edges) to other vertices. 20 | - __self loop__: an edge from vertex to itself. 21 | - __undirected graph__: In this type of graph there is no direction information for edges. In another word; if X node have connection to Y node, Y node also must have connection to X. The opposite graph type is __directed graph__ which has direction information. 22 | - __komşuluk matrisi (or adjacency matrix)__: This takes more memory. But it is fast to find the connections. 23 | 24 | ``` 25 | A B C 26 | 27 | A 0 1 0 28 | 29 | B 1 1 1 30 | 31 | C 0 1 1 32 | ``` 33 | 34 | - __komşuluk listesi (or adjacency list)__: Requires low memory. But it takes long time to find the relations between nodes. Also it is more complex comparing "adjacency matrix". 35 | 36 | ``` 37 | A -> {B} 38 | 39 | B -> {C, D} 40 | ``` 41 | 42 | The above "adjacency list" means: 43 | - There is a connection from A to B. 44 | - There is a connection from B to C and D. 45 | 46 | # real use case examples of graph 47 | - storing the pyhsical border connections between countries and cities. 48 | - Storing the list of friend connections on social media web sites 49 | - connections of between atoms/molecules (for simulation) 50 | - connections between devices for electronic circuit (for simulation or on engineering design tools) 51 | - connections of each part on puzzle game 52 | - Google's PageRank algorithm. In this algorithm, Google stores which web page has linked by which web pages. If a web page has reference (link) inside other web pages, that means the web page reputation is high. 53 | - network topology. It seems like, the network is based on tree structure. But it's not. Because of 2 reasons: 54 | - the child nodes (the computers) can send directly message to each other. They use the router (parent) only to detect the IP address of each other. 55 | - A computer (node) can has multiple routers (parents) if the computer use multiple network devices. -------------------------------------------------------------------------------- /tutorials/algorithms_data_structures_map.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # ALGORITHMS DATA STRUCTURES MAP 5 | ############################ 6 | 7 | ############################ 8 | 9 | # Map 10 | Working mechanism of structures like HashSet, HashMap which are based on "hash" are explained to another topic (at the topic about "hashcode"). 11 | 12 | The Map interface of Java does not have any super class. It defined as: 13 | 14 | ```java 15 | Map 16 | ``` 17 | 18 | For each Class1 object, there should be Class2 object. It stores the data as key-value. Some implementations of "Map": 19 | 20 | - __HashMap__: It does not guarantees the order of a for loop which will be based on "keySet()" method. 21 | 22 | - __LinkedHashMap__: It guarantees the order of a for loop which will be based on "keySet()" method. It orders the data in sequence of data insertion method call. In order to do that It implements the HashMap and additionally it use doubly linked list to store the order under the hood. 23 | 24 | - __TreeMap__: It guarantees the order based on below techniques. 25 | 26 | - __java.lang.Comparable__ 27 | 28 | The data classes which implemented this interface, have to implemented "int compareTo(object1)" method. TreeMap uses that method to sort the classes. 29 | 30 | In Java articles we can see the "natural ordering" term. This term is using only for classes which implemented "Comparable". 31 | 32 | - __java.util.Comparator__ 33 | 34 | We create a class which implements this interface with "int compare(object1, object2)" method. 35 | 36 | This class is not implementing by any class which is storing on Map. "Comparator" implementation is a separated class from our data classes. It is an external class. 37 | 38 | - __IdentityHashMap__: It has 2 main differences with HashMap: 39 | - 1- HashMap uses "equals" method to compare the data which putted inside. But instead of that IdentityHashMap uses "==" (reference compare). 40 | - 2- HashMap use "hashCode" method, but IdentityHashMap uses "System.identityHashCode(object)" method which return the default "hashCode" which would be returning if the class hadn't override "hashCode". 41 | 42 | # SortedMap 43 | It's an interface which implements Map. It is using by order matter classes. 44 | 45 | # HashTable 46 | HashTable is a general data structure term. The corresponding class on Java is HashMap. 47 | 48 | But specifically for the Java world, there is a class named as HashTable. difference between HashMap vs HashTable: "java.util.Hashtable" class is thread-safe, while "java.util.HashMap" is not. 49 | 50 | It is slow to add elements because it calculates the hash code of each object but lookup is fast. 51 | 52 | # EnumMap 53 | It only accepts Java Enum for the key side. 54 | -------------------------------------------------------------------------------- /tutorials/algorithms_search.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # ALGORITHM SEARCH 5 | ############################ 6 | 7 | ############################ 8 | 9 | # arama algoritmaları 10 | 11 | ## İkili Arama Algoritması (or Binary Search Algorithm) 12 | - This algorithm design to work in a sorted array only. 13 | - It based on __parçala fethet (or divide and conquere)__. 14 | - Initially it starts to search from the center of array. 15 | - Lets say we search "S" and the middle element of the array is M. This algorithm does: 16 | - If S=M then return index of M (element founded) 17 | - If SM then return binarySearch(index-of-M, array-max-index, S) 19 | 20 | ## doğrusal arama Algoritması (or linear search Algorithm or sıralı arama or Sequential Search) 21 | - On this algorithm it does not matter if the array is sorted or not. 22 | - It compares each element one by one. 23 | 24 | # Comparison table 25 | 26 | | name | best | average | worst | worst space | 27 | |--------|------|---------|-------|-------------| 28 | | binary | 1 | log n | log n | 1 | 29 | | lineer | 1 | n | n | 1 | 30 | -------------------------------------------------------------------------------- /tutorials/algorithms_sort.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # ALGORITHM SORT 5 | ############################ 6 | 7 | ############################ 8 | 9 | # sort vs order 10 | They are both interchangeable. But "sorting" has 2 different meaning: 11 | - ordering 12 | - grouping. You can say "sort the books by size", but not "order the books by size.". This root of the verb "sorting" is "sort" which means: "a particular kind, species, class, or group, distinguished by a common character". 13 | 14 | # natural ordering vs lexicographic (or lexicographical order or lexical order or dictionary order) 15 | There is no any accepted standard about how they should work exactly: 16 | - what will happen if special (non-alpha-numeric) characters exist? 17 | - which will be first? 0 (any number) or A (any character)? 18 | - must be ignored capital/lower case? 19 | - which of them will be before: 0.1 and 0.10 (same valued numbers) 20 | 21 | National Information Standards Organization (NISO) (organisation which is accredited by the American National Standards Institute (ANSI)) has published a duideline about the __alphanumeric (or alphanumerical or alfabetik or abecesel)__ impelementations: https://www.niso.org/sites/default/files/2017-08/tr03.pdf 22 | 23 | natural sorting is more countable. But lexicographic is better(easier/faster) to see variants of any words (example: "photo", "photograph", "photographer"). 24 | 25 | # natural ordering 26 | It is human countable. 27 | 28 | ``` 29 | img1.png 30 | img2.png 31 | img10.png 32 | img12.png 33 | ``` 34 | 35 | The term "natural" comes from "natural numbers". As human, when we count natural numbers, we count as 1, 2, ... ,10, 11, 12... 36 | 37 | ## algorithm trick 38 | In some resources, the non-alphanumeric characters are ignoring directly. And each string is dividing in different parts, so it will be easier to sort and visualise it: 39 | 40 | ``` 41 | foo => "foo", -1, "" 42 | foobar => "foo", -1, "bar" 43 | foo13 => "foo", 13, "" 44 | foo13xyz => "foo", 13, "xyz" 45 | ``` 46 | 47 | On above block, there are multiple columns. -1 and "" mean null. 48 | 49 | ## GNU ls commands implementation 50 | "GNU ls" command has "version sort" feature. If that feature will be enabled (by sending a parameter to cammand) it sorts the result based on natural sorting. 51 | 52 | ## lexicographic 53 | As human when we want to search a word on a dictionary, we want to see in this order: 54 | 55 | ``` 56 | img1.png 57 | img10.png 58 | img12.png 59 | img2.png 60 | ``` 61 | 62 | So we can find the variants of a word near to root. Example: 63 | 64 | ``` 65 | phone 66 | photo 67 | photograph 68 | photographer 69 | ``` 70 | 71 | ## alphabetical vs alphanumerical 72 | Akademide ortak hiçbir tanımı yoktur. Alfabetik sıra kullanıldığını belirtir. Çoğu kaynakta, lexicographic'ın bir türevi olduğu yazar, fakat neye göre böyle yazıldığı belirsizdir. 73 | 74 | __alphanumerical__ ise sıralayacağımız String'in alpha numeric değerler içerdiğinde, "alfabetik" sıralama uygulayacağımızı belirtmek için kullanılan bir terimdir. 75 | 76 | # Features of the sorting algorithms 77 | 78 | - __Stability__ 79 | 80 | If it is not necessary the elements does not shift. 81 | 82 | Let assume that we sort a table by it's "Name" column (the table example is below). If we don't shift the rows which have the same names, it would be performance advantage for us. 83 | 84 | ``` 85 | Name ID 86 | Ahmet 101 87 | Ahmet 102 88 | Ahmet 103 89 | Mehmet 105 90 | ``` 91 | 92 | - __in-place algorithm__ 93 | 94 | The algorithms which does not require extra space (memory). Algortihms would require some small variables like: 95 | - counter 96 | - current index 97 | - max value of current array 98 | 99 | But those values are ignored. 100 | 101 | If an algorithm requires extra memory space to store a part of original array, they called __not-in-place (or out-of-place)__. 102 | 103 | # Sorting Algorithm (or Sıralama algoritması) 104 | 105 | - ## Kabarcık Sıralaması (or Baloncuk sıralaması or Bubble Sort) 106 | 107 | Diziyi eleman sayısı kadar dolaşır. Her dolaşmada her elemanı sağ taraftaki ile kontrol edip yer değiştirtir. 108 | 109 | - ## Seçerek Sıralama (or Selection Sort) 110 | 111 | Diziyi sürekli dolaşır. En ufak elemanı geçici bir dizinin başına atar. Daha sonraki dolaşımlarda tekrar en ufak elemanı bulur geçici dizideki 2inci elemana atar. 112 | 113 | - ## Hızlı Sıralama Algoritması (or Quick Sort Algorithm) 114 | 115 | bir eleman seçilir. bu eleman pivot (Türkçe ve İngilizce'de bu şekilde kullanılır) adı verilir. bu elemanın, hangi index'teki eleman seçileceği hakkında birçok farklı görüş mevcuttur. 116 | 117 | her pivotun sağ tarafında ondan büyük elemanlar yerleştirilir ve sol tarafında ise küçük elemanlar yerleştirilir. aynı işlem, sağ ve sol taraf içinde yapılacaktır. böyle olunca en ufak parçalara (3 elemana düşünceye kadar) bölündüğünde tekrar birleştirdiklerinde dizi sıralanmış olacaktır. 118 | 119 | pivotun sağ ve sol tarafına yerleştirme işlemi şu şekilde yapılır: dizinin ilk ve son elemanı pivot ile karşılaştırılır. eğer ilk-elemen>=pivot>=son-eleman ise ilk-eleman ve son-eleman swap (yer değiştirir) edilir. Daha sonra dizinin baştan ikinci ve sonradan ikinci elemanı için aynı işlem yapılır. sonra 3üncü... tabi dizinin ortasına gelene kadar. 120 | 121 | Buradan sonra dizinin sağ ve sol tarafı ayrı ayrı rekürsif olarak quick-sort algoritmasına sokulur. Burada ayrı ayrı quick-sort'a atılan dizilerin referanslarını quick-sort metotuna geçmemiz yeterli. yeni bir liste oluşturup klonlamaya gerek yok. 122 | 123 | - ## Birleştirme Sıralaması (or Merge Sort) 124 | 125 | Diziyi sürekli ikiye böler. her elemanı kendi içinde 2 şerli şekilde sıralar. Sonra bunları birleştirir. Birleştirirken de elemanların büyüklüklerini değerlendirir. 126 | 127 | - ## Yığınlama Sıralaması (or Heap Sort) 128 | 129 | öncelikle sıralanması istenen dizi heap ağacı kurallarına uygun şekilde ağaç haline getirilir. heap ağacı hale getirilmesi kısadır. büyük olan üstte ufak olan altında şeklinde dallandırılacaktır. fakat ağaç bir dizi yapısı olmadığından henüz elimizde sıralı bir dizi yoktur. bunu dizi hale getirmek gerekmektedir. heap ağacının en üstündeki en üst sayı olacağından, sonuç kümesine en büyük rakam olarak kaydedilir. daha sonra ağacın en üstteki node'u silerek ağaç tekrar heapfy işlemine sokulur. bu sefer ağacın en üstündeki değer sonuç kümemizin ikinci en büyük sayısı olmuş olur. bu şekilde tüm ağaç sıfırlandığında sonuç kümemizde sıralanmış bir dizi olacaktır. 130 | 131 | - ## Radix sort 132 | radix kelime anlamı: sayı tabanı (örnek: hexadecimal). 133 | 134 | bazı Türkçe kaynaklarda basamak olarak isimlendiriliyor. Fakat bu yanlış. "basamak" İngilizce'de "Positional (or place-value)" olarak çevrilir. 135 | 136 | Diğer çok bilinen sort algoritmalarına göre bu algoritmanın çözümü için çok fazla farklı implementasyonlar vardır. 137 | 138 | Radix sort temelde şunu söylüyor: önce en düşük seviyeli basamağa göre sayılar sıralanır. Sonra bir sonraki basamağa göre, sonra bir sonraki basamağa göre sıralanır... Zaten hepsini yapınca dizi sıralanmış olacaktır. 139 | 140 | örnek: 141 | - orjinal dizi: 55,45,35,33,38,48 142 | - 1inci basamağa göre sıralanmış hali: 33,55,45,35,38,48 143 | - 2inci basamağa göre sıralanmış hali: 33,35,38,45,48,55 144 | -------------------------------------------------------------------------------- /tutorials/array_native.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # ARRAY NATIVE 5 | ############################ 6 | 7 | ############################ 8 | 9 | # Multidimensional Array (or çokboyutlu dizi) 10 | C# Example of: two-dimensional (2d) array of 4 rows and 2 columns. 11 | 12 | ```c# 13 | string[,] array = new string[4, 2] { 14 | { "one", "two" }, 15 | { "three", "four" }, 16 | { "five", "six" } 17 | }; 18 | 19 | ``` 20 | 21 | C# Example of: three-dimensional (3d) array: 22 | 23 | ```c# 24 | int[,,] array = new int[2, 2, 3] { 25 | { { 1, 2, 3 }, { 4, 5, 6 } }, 26 | { { 7, 8, 9 }, { 10, 11, 12 } } 27 | }; 28 | 29 | ``` 30 | 31 | # jagged array (or ragged array or array of array) 32 | jagged kelime anlamı: sivri. 33 | 34 | ragged kelime anlamı: eski püskü. 35 | 36 | "__multidimensional array__" is something different. It should not be mixed. 37 | 38 | This feature is supported by Java and C#. 39 | 40 | The below __jagged array__ example is sytnax is valid for both Java and C#: 41 | 42 | ```c# 43 | int[][] c; 44 | c = new int[2][]; // creates 2 rows 45 | c[0] = new int[5]; // 5 columns for row 0 46 | c[1] = new int[3]; // create 3 columns for row 1 47 | ``` 48 | 49 | ## variable-length array (or VLA or variable-sized array or runtime-sized array) 50 | Java bu özelliği destekliyor. 51 | 52 | C'ye C99 ile bu özellik gelmiştir. C'de daha öncesinde array ancak şu 2 şekilde oluşturulabiliyordu: 53 | 54 | - array-size'ı ancak define'da tanımlanan bir değer ile oluşturulabiliyordu 55 | - malloc ile bellek alanı tahsis edilen bir array pointer'ı yaratılıyordu 56 | 57 | VLA sayesinde, C99 ile artık run-time'de oluşturulan bir integer değeri ile de dizi oluşturabiliyoruz. Örnek: 58 | 59 | ```c 60 | int i = 5; 61 | int array[i]; 62 | ``` 63 | 64 | C++'ta bu özellik yok (eski sürümlerinde yoktu. yeni sürümlerinde gelmiş olabilir). Fakat gcc derleyicisi bu özelliği destekleyecek şekilde bir yeteneği var. fakat resmi C++ spesifikasyonlarında bu özellik desteklenmiyor. 65 | 66 | __Flexible array member__ C99 ile gelen VLA'dan farklı bir özelliktir. VLA ile karıştırılmamalı. 67 | 68 | ## dynamic array (or growable array or resizable array) 69 | __dynamic size array__ veya __dynamic length array__ isimlendirilebilir. 70 | 71 | Bazı makalelerde "dynamic size array" veya "dynamic array", VLA yerine kullanılıyor. Çünkü array'i boyutu runtime'da belirlenip array init edilebiliyor. Oysa bu terimler farklıdır. 72 | 73 | dynamic array; size'ı belirlenmiş ve init edilmiş bir dizinin boyutunun değiştirilebilir olması özelliğidir. 74 | 75 | dynamic array'i bir programlama dilin desteklemesi mümkün değil. Genelde bunu 2 dolaylı yöntem ile çözmüş gibi gösteriyorlar: 76 | - arkaplanda yeni array oluşturan wrapper sınıflar bu altyapıyı destekler gibi gözükmektedir. Örnek: Java'da ArrayList. 77 | - Pointer destekleyen dillerde (örnek: C), pointer'lar ile bunu yapabiliriz. Fakat aslında pointer'lar, native array olarak sayılmazlar. -------------------------------------------------------------------------------- /tutorials/broker_platforms_activemq.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # BROKER PLATFORMS ACTIVEMQ 5 | ############################ 6 | 7 | ############################ 8 | 9 | # Topic vs address 10 | ActiveMQ'da, hem topic, hemde adres kavramı vardır. 11 | 12 | client, ActiveMQ'daki bir address'e mesajı yollar. ActiveMQ bu mesajı okur ve kendi içinde tuttuğu birden fazla queue'ya yönlendirir. yönlendirirken, eğer routing-type-config'i __anycast__ ise, 1 mesaj bu queue'lardan sadece 1'ine yollanır. Oysa routing-type-config __multicast__ ise, 1 mesaj, tüm queue'lara yollanır. 13 | 14 | ActiveMQ server'ındaki config dosyalarının örnekleri: 15 | 16 | active-mq'da address'e yazılıyor ve queue'dan okunuyor. bu sebeple active-mq'da şu ayar olmalıdır: 17 | 18 | ```xml 19 | 20 |
21 | 22 | 23 | 24 |
25 |
26 | ``` 27 | 28 | multicast örneği: 29 | 30 | ```xml 31 | 32 |
33 | 34 | 35 | 36 | 37 |
38 |
39 | ``` 40 | 41 | Yukarıdaki multicast örneği genelde bu şekilde implemente edilmez. Genelde aşağıdaki gibi implemente edilir. çünkü active-mq zaten her bağlanan consumer direk adresten okuma yapar. bu sebeple aşağıdaki tercih edilir: 42 | 43 | ```xml 44 | 45 |
46 | 47 |
48 |
49 | ``` 50 | 51 | Yukarıdaki son örnekte, her mesaj, her queue'ya clonlanır. bu tarz queue'lara piyasada __subscription queues__ denir. 52 | 53 | # Fully Qualified Queue Names 54 | JMS gibi sistemler "address" kavramını bilmeyebilir. Bu sebeple JSM'in destination'ı, active-mq'daki bir queye'ya bağlanırken şu şekilde olmalıdır: 55 | 56 | ``` 57 | address::queue 58 | ``` 59 | 60 | örnek JMS kodu: 61 | 62 | ```java 63 | Queue q1 session.createQueue("a1::q1"); 64 | MessageConsumer consumer = session.createConsumer(q1); 65 | ``` 66 | -------------------------------------------------------------------------------- /tutorials/broker_platforms_terminology.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # BROKER PLATFORMS TERMINOLOGY 5 | ############################ 6 | 7 | ############################ 8 | 9 | # Messaging system 10 | Messaging system'a aracılık eden tool'a __messaging broker (or message broker)__ denir. 11 | 12 | # JMS (or Java Message Service) 13 | - JMS is part of Oracle's JEE specification. It's a Java API that encapsulates both message queue and publish-subscribe messaging patterns. 14 | - JMS is a very popular API and is implemented by most messaging systems. JMS is only designed for Java clients. 15 | - JMS does not define a standard wire (data-transfer) format. it only defines a programmatic API. 16 | 17 | source for all above: https://activemq.apache.org/components/artemis/documentation/2.0.0/messaging-concepts.html title: "Java Message Service (JMS)". 18 | 19 | - JMS dünyasında broker'lara __JMS provider__ deniliyor. 20 | - "Apache ActiveMQ Artemis" provides a fully compliant JMS 1.1 & 2.0 + Jakarta Messaging 2.0 & 3.0 API. source: https://activemq.apache.org/ 21 | 22 | # AMQP (or Advanced Message Queuing Protocol) 23 | AMQP'nun farklı versiyonları var. 24 | 25 | __wire-level protocol__ network üzerinden atılan data'nın fromatının belirlendiği stadartlardır. Örneğin; JMS bir API'dir, fakat implementasyonun network'ten hangi data ile nasıl haberleşeceğine karışmaz. Fakat AMQP __wire-level protocol__'dür. Data'nın kendisine karışır. source: https://www.amqp.org/resources/developer-faqs 26 | 27 | __wire-level protocol__ (kelime kökeni bunu ifade etmese de) fiziksel network katmanındaki formatlarla ilgilenmez, onun yerine API-level'daki (daha üst katmanların) yollayacağı data formatını ifade etmek için kullanılır. TCP/UDP katmanının wired-level'a girip girmediği bir tartışma konusudur. 28 | 29 | # JMS Interface and Clasess 30 | - Yollanan mesaj bunlardan biri ile yollanır: Message, BytesMessage, MapMessage, ObjectMessage, StreamMessage and TextMessage. 31 | - Queue: sadece P2P için gerekli objedir. 32 | - Topic: sadece Pub/Sub için gerekli objedir. 33 | - Destination: the common supertype of Queue and Topic. 34 | 35 | # message queuing vs publish-subscribe (or P/S) & topic vs queue 36 | Kafka ve alternatifi sistemler 2 tipte mesaj yollama işlemini yapabiliyor. __publish-subscribe__'da tüm consumer'lara mesaj giderken, __queuing (or Point-to-Point Messaging Model or P2P Model or PTP)__ modunda sadece 1 adet consumer mesajı okuyabiliyor. kaynak: (source-id: 388) "Kafka as a Messaging System" başlığı ilk paragraf. 37 | 38 | JMS dünyasında terimler yukarıdaki gibidir ve JMS dünyasında P/S __topic__'ler aracılığı ile yapılırken, P2P'de queue aracılığı ile yapılır. 39 | 40 | Kafka yukarıda yazan "message queuing" ve "publish-subscribe" özelliklerini sadece "topic" üzerinden destekliyor. Bu bazen makalelerde terimlerin yanlış anlaşılmasına sebep olabiliyor. Kafka yukarıda yazan özelliklere ek olarak şu özelliği sunuyor: streaming. Yani offset'i bilen client'lar eski bilgileri istediği okuyabiliyor, yani stream edebiliyor. 41 | 42 | # Kafka vs RabbitMQ 43 | Kafka streaming platform olarak geçer, RabbitMQ ise messaging broker'dır. temelde fark şuradadır: Kafka-server kuyruğu silmez. Kafka-client kuyrukta nerede olduğunu (index'i) kendi tutmak zorundadır. bu onu "consumer-centric" yapar. bu sebeple streaming platform olarak kullanılır. çünkü her client istediği gibi geçmişe ileriye gidebilir, yani stream edebilir. RabbitMQ da ise push vardır. RabbitMQ mesajları karşıya push'lar. eski mesajları client göremez. RabbitMQ'daki bu çalışma modeline "__smart-broker/dumb-consumer (or smart broker/dumb consumer)__" denir. Oysa Kafka'nın çalışma modeline tersi olarak; "__smart-consumer/dumb-broker (or smart consumer/dumb broker)__" denir. 44 | 45 | not: Kafka-consumer(client) başarılı şekilde işlemin bittiğini ("acknowledgment") Kafka'ya bildirir. böylece Kafka bir cursor tutar. Dolayısı ile yeni ayağa kalkan bir client index'i bilmek zorunda değildir. Cursor'un olduğu yerden, pull etmeye başlayabilir. Fakat istenirse, index üzerinden de hareket edebilir. Eğer kesinlikle index üzerinden tekrar event okumayacak ise, Kafka kullanmamayı düşünmek gerekebilir. 46 | 47 | RabbitMQ mesajları persist edebilir fakat bunların çekilmiş client'lar tarafından tekrar çekilebilmesini sağlayamaz. 48 | 49 | RabbitMQ mesajların consumer'lara ulaşıp ulaşmadığını garanti edebilir (retry yapabilir). 50 | 51 | # message queue vs message broker 52 | __message broker__ yazılımı, __message queue__'ların management'ini sağlar. kaynak: (source-id: 389) title: "What is a message broker?", 4th paragraph. 53 | 54 | - __enqueue__ 55 | 56 | fiildir. sıraya almak. 57 | 58 | - __dequeue__ 59 | 60 | fiildir. kuyruktan çıkarmak. 61 | 62 | # queue vs bus 63 | "bus" genel bir terimdir. "queue" onun özel bir türevidir. queue'da first-in-first-out (FIFO) mutlaka olmalıdır. fakat bus'ta böyle bir zorunluluk söz konusu değildir. 64 | 65 | # event bus için yazılımlar (broker'lar) 66 | - __Apache Kafka__ 67 | 68 | - __Apache ActiveMQ__ 69 | 70 | "Artemis" kod adı ile ActiveMQ projesi paralelden geliştiriliyor. Artemis stabil olduğunda eski proje sonlandırılacak. Artemis'in başlaması ile artık eski proje "Classic" olarak adlandırılıyor. 71 | 72 | __Advanced Message Queue Protocol (or AMQP)__ protokolü ile çalışır. Fakat MQTT, OpenWire, Stomp protokolleri ile de çalışabilir. 73 | 74 | - __OpenWire__: __AMQP__'ye çok benzer bir protokoldür. 75 | - __OpenWire__ vs __STOMP__: STOMP text based haberleşme sağlar ve OpenWire'a göre yavaştır. OpenWire ise binary haberleşme sağlar ve STOMP'a göre hızlıdır. 76 | 77 | - __Open Message Queue (or OpenMQ or Open MQ)__ 78 | 79 | Oracle tarafından geliştirilen, GlassFish içerisinde default olarak geliyor. İstenirse standalone da kullanılabiliyor. 80 | 81 | - __OpenJMS__ 82 | 83 | - __Oracle Advanced Queuing (or AQ)__ 84 | 85 | - __IBM MQ (or old-name:MQSeries or old-name:WebSphere MQ)__ 86 | 87 | - __Rabbit mq__ 88 | 89 | Pivotal Software tarafından geliştiriliyor. __AMQP__ protokolü ile çalışır. 90 | 91 | # BROKER FEATURES 92 | Broker olan sistemlerde şu özelliklerden bahsedebiliriz: 93 | 94 | - ## CONSUMPTION MODE 95 | Push vs Pull. 96 | 97 | push: broker'ın push ettiği model. 98 | 99 | pull: consumer'ın pull aldığı model. 100 | 101 | Client'ın pull alması, client'ın kendine fazladan yük bindirmemesi konusunda avantaj sağlamaktadır. Çünkü broker sürekli push yaparsa sıkıntı olabilir. 102 | 103 | - ## MESSAGE QUEUING MODEL 104 | point-to-point (or P2P) vs __publish-subscribe (or pub/sub) 105 | 106 | point-to-point, 1 mesaj en fazla 1 consumer tarafından okunabilir. "queue" vardır. queue'ya 1 den fazla consumer listen edebili fakat yine de 1 mesajı sadece 1 consumer okuyabilir. 107 | 108 | P2P, Fire-and-forget (async) veya request/reply (synchronized) messaging olabilir. 109 | 110 | pub/sub modelinde ise 'topic'ler vardır. 111 | 112 | - ## DELIVERY SEMANTICS 113 | birçok çeşit olabilir. bazı örnekler: 114 | - __at-most-once__ (Kafka bunu destekliyor.) 115 | - __at-least-once__ (Kafka bunu destekliyor.) 116 | - __exactly-once__ (bunun %100 sağlanması çok maliyetli.) 117 | 118 | - ## ORDERING GUARANTEE 119 | - no-ordering: 120 | 121 | bazı broker'lar mesajların sırasını garanti edemeyebilir. performans açısından büyük avantaj sağlar. 122 | 123 | - partition or queue ordering 124 | 125 | bazı brokerlar mesaj sırası garanti edebilir ancak sadece belli kısımları için edebilir. örneğin Kafka sadece partition bazında garanti verebiliyor. 126 | 127 | - global ordering 128 | 129 | performans açısından önemli derecede yavaşlığa sebep olabilir. bu seviyede tüm partition'lar arası sürekli senkronizasyon gerekmektedir. -------------------------------------------------------------------------------- /tutorials/c_build_phases.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # C BUILD PHASES 5 | ############################ 6 | 7 | ############################ 8 | 9 | # fazlar (or phases) 10 | - preprocess 11 | 12 | derleme öncesi çalışır. başka başlıkta anlatılan keyword'lerin (ifdef gibi) çalıştığı aşamadır. bu fazın çıktısı yine source koddur. fakat bir kısmı ifdef gibi tanımlar sebebi ile silinmiştir. 13 | 14 | - compile 15 | 16 | kod, makinenin anlayacağı dile çevriliyor. bu faz sonucunda __object code (or object file)__ elde edilir. 17 | 18 | genelde __.o__ uzantılıdır. C'den türemiş bazı dillerde __.obj__ olarakta kullanılır. 19 | 20 | object code'da diğer kütüphaneler henüz linklenmediği için düzgün çalışamaz. 21 | 22 | - link 23 | 24 | kütüphanelerin birleştirildiği/linklendiği fazdır. artık object code'umuz executable olmuştur. 25 | 26 | # file formats 27 | arayüzler ".h" (__header file__ (Türkçe'de "__üst bilgi dosyası__" olarak çevrilir)) uzantılı, diğer tüm kodlar ".cpp" uzantılı text dosyalarında saklanması önerilir. bazı repo'larda C++ header'ları C header'ları ile karışmasın diye ".hpp" uzantılı kaydedilir. 28 | 29 | C'de de bu şekildedir. header dosyasında fonksiyon definition'larımız durur. fonksiyonların implementasyon kodları ".h" dosyasında olmamalıdır. fakat olursa yine çalışır. fakat best practice değildir. 30 | 31 | ".h" dosyalarının implementasyonları ".c" dosyalarında olmalıdır. ".c" dosyası ile ".h" dosyası aynı isimde olma gibi bir zorunluluk yoktur. 32 | 33 | # "iostream" vs "iostream.h" 34 | farklı dosyalardır. C++ ilk çıktığında "iostream.h" kullanılıyordu. fakat namespace verilmemişti. daha sonrada std namespace'i altına taşındıklarında eski kodlar etkilenmesin diye "iostream" isimli kütüphane (dosya) altında dağıtılmaya başlandı. 35 | 36 | # DLL 37 | DLL dosyaları sadece implementasyonları barındıran dosyalardır. Bu sebeple; DLL dosyasını C veya C++ 'tan kullanabilmek için, DLL'e tekabül eden (C veya C++ için uygun formatta olan) header dosyasına ihtiyacımız vardır. Bu header dosyalarını build sırasında bulundurmak zorundayız, yoksa kodumuz compile etmez. 38 | 39 | Eğer DLL dinamik ise (runtime sırasına belirlenebilir), OS tarafından bize verilmelidir. 40 | 41 | Fakat DLL dosyaları portable olduklarından, onları Exe içerisine gömüpte kullanabiliriz. 42 | -------------------------------------------------------------------------------- /tutorials/c_memory_structure.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # C MEMORY STRUCTURE 5 | ############################ 6 | 7 | ############################ 8 | 9 | # memory structure 10 | 11 | ``` 12 | High Addresses ---> .----------------------. 13 | | Environment | CommandLine Argument + Enviroment variables 14 | |----------------------| 15 | | | variable are declared on the stack 16 | | STACK | 17 | stack pointer -> | - - - - - - - - - - -| 18 | | | | 19 | | v | 20 | : : 21 | . . The stack grows down into unused space 22 | . Empty . while the heap grows up. 23 | . . 24 | . . (other memory maps do occur here, such 25 | . . as dynamic libraries, and different memory 26 | : : allocate) 27 | | ^ | 28 | | | | 29 | | - - - - - - - - - - -| Dynamic memory is declared on the heap 30 | | HEAP | 31 | | | 32 | |----------------------| 33 | | BSS | Uninitialized data (BSS) 34 | |----------------------| 35 | | Data | Initialized data (DS) 36 | |----------------------| 37 | | Text | Binary code 38 | Low Addresses ----> '----------------------' 39 | ``` 40 | 41 | C ile derlenmiş bir uygulama çalışırken, memory'deki görüntüsü yukarıdaki gibidir. bu parçaları incelersek: 42 | 43 | - stack 44 | 45 | static olmayan değerler burada tutulur. 46 | 47 | her fonksiyonun bir stack bloğu vardır. 48 | 49 | LIFO mantığında çalışır. bu sebeple __stack pointer__ listenin tepesinin adresini tutar. 50 | 51 | - heap 52 | 53 | memory allocation (alloc, realloc...) işlemleri ile buradan yer ayırtılır. buradaki değerler fonksiyonlardan bağımsızdır. 54 | 55 | - BSS (or Uninitialized data segment) 56 | 57 | static yada global olan fakat initialize olmamış değerler burada tutulur. (aslında initialize doğru değil. çünkü tanımlama yapılınca zaten örneğin integer'lara 0 değeri atanmış oluyor. onlarda burada tutuluyor.) 58 | 59 | - DS (or Initialized data segment) 60 | 61 | static veya global olan ve initialize olmuş değerler burada tutulur. 62 | 63 | - Text 64 | 65 | kodumuzun binary hali burada tutulur. bu kısım read-only'dir. böylece yanlışlıkla buraya yazma gibi bir durum söz konusu olamaz. 66 | 67 | # segmentation fault (or segfault) 68 | eğer memory'de erişmeye yetkimiz olmayan veya geçersiz bir adrese erişmek istediğimizde bu hatayı alırız. 69 | -------------------------------------------------------------------------------- /tutorials/c_plus_plus.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # C PLUS PLUS 5 | ############################ 6 | 7 | ############################ 8 | 9 | # C++ 10 | C++ ile bazı konular başka başlıkta (c (language)) anlatılıyor. 11 | 12 | ```c++ 13 | #include // includes all functions of this lib on this file. 14 | using namespace std; 15 | 16 | namespace myCustomNameSpace 17 | { 18 | int val = 30; 19 | } 20 | 21 | int val = 10; // Global variable. 22 | 23 | #define NAME_SIZE 50 // Defines a macro 24 | 25 | class Person { 26 | int id; // all members are private by default 27 | char name[NAME_SIZE]; 28 | bool active; // boolean 29 | 30 | public: 31 | void aboutMe(){ 32 | 33 | count << "I'm a person"; 34 | 35 | // eğer en yukarıda "using namespace std;" yazmasaydık, 36 | // o zaman bunu yazmak zorundaydık: 37 | // std::cout << "I'm a person"; 38 | 39 | // nameSpaceIdentifier::varInsideNameSpace 40 | } 41 | 42 | int anotherFunction(){ 43 | // this is also public function 44 | } 45 | }; 46 | 47 | class Student : public Person { 48 | public: void aboutMe(){ 49 | count << "I'm a student"; 50 | } 51 | }; 52 | 53 | int main(){ 54 | Student * p = new Student(); 55 | p -> aboutMe(); // prints "I'm a student" 56 | delete p; // allocated memory 57 | 58 | // comma operator example: 59 | int b = 0; 60 | int a = (b=3, b+2); 61 | // above code flow: 62 | // 1- b=3 (b is 3) 63 | // 2* b+2 (b is 5) 64 | // a = 5 (a is 5) 65 | 66 | int x = 5; 67 | int y = 6; 68 | duplicate(x, y); 69 | 70 | // arrays 71 | int arrX[5] = { 10, 20, 30 }; // other 2 variables are 0. 72 | // or different sytax: 73 | int arrY[5] { 10, 20, 30 }; 74 | 75 | // C++ standart lib --> include have custom array: 76 | // array myarray {10,20,30}; 77 | // for (int i=0; i 145 | T sum(T a, T b) 146 | { 147 | T result; 148 | result = (a + b) * X; 149 | return result; 150 | } 151 | 152 | // usage: 153 | int x = sum(1, 2); 154 | int y = sum(1.1, 2.2); 155 | ``` 156 | 157 | # scope 158 | 159 | ```c++ 160 | int main () { 161 | int x = 10; 162 | int y = 20; 163 | { 164 | int x; // ok, inner scope. 165 | x = 50; // sets value to inner x 166 | y = 50; // sets value to (outer) y 167 | } 168 | // x = 10 169 | // y = 50 170 | } 171 | ``` 172 | 173 | # using keyword 174 | 175 | ```c++ 176 | #include 177 | using namespace std; 178 | 179 | namespace first 180 | { 181 | int x = 5; 182 | int y = 10; 183 | } 184 | 185 | namespace second 186 | { 187 | double x = 3.1416; 188 | double y = 2.7183; 189 | } 190 | 191 | int main () { 192 | using first::x; 193 | using second::y; 194 | cout << x << '\n'; // prints the x of first 195 | cout << y << '\n'; // prints the y of second 196 | cout << first::y << '\n'; 197 | cout << second::x << '\n'; 198 | return 0; 199 | } 200 | ``` 201 | 202 | # Operator overloading 203 | function overloading'den farklıdır. function overloading aynı isimdeki fonksiyonun farklı parametreler alarak çalışabilmesidir. oysa operator overloading dildeki gömülü olan bir operatörün (+, - gibi...) kullanımını override edebilmemizi sağlayan özelliktir. 204 | 205 | C++ birçok operatörün override edilmesine izin veriyor. bazı override edilebilen operatörler: 206 | 207 | > +, -, *, /, %, ^, !, =, ==, new, delete, --, <<=, &&, || 208 | 209 | Fakat bazılarını overload edemiyoruz: 210 | 211 | > ., ::, ?:, sizeof 212 | 213 | Bazı operatörlerin unary ve binary versiyonları vardır. bunlar ayrı ayrı overloading edilirler. örnek: 214 | 215 | > &, *, +, -. 216 | 217 | örnek olarak + operatorünü bizim custom class'ımız için overload edelim: 218 | 219 | ```c++ 220 | class Point { 221 | int x; 222 | int y; 223 | 224 | // this should be define here! but It should not be implemented here! 225 | Point &operator+(const Point&); 226 | } 227 | 228 | //this should be implemented outside of class. 229 | Point Point::operator+ (const Point& param) { 230 | Point temp; 231 | temp.x = x + param.x; 232 | temp.y = y + param.y; 233 | return temp; 234 | } 235 | 236 | // if we don't declare the signature inside class we should use the following code here: 237 | Point operator+ (const Point& point1, const Point& point2) { 238 | Point temp; 239 | temp.x = point1.x + point2.x; 240 | temp.y = point1.y + point2.y; 241 | return temp; 242 | } 243 | 244 | int main () { 245 | Point point1 (3,1); 246 | Point point2 (1,2); 247 | Point result; 248 | result = point1 + point2; 249 | // above line is same as below: 250 | result = point1.operator+(point2); 251 | return 0; 252 | } 253 | ``` 254 | 255 | # insertion operator (<<) 256 | 257 | ```c++ 258 | // "cout" console output'un kısaltmasından gelir. 259 | // cout writes to console-output-stream. 260 | - 261 | cout << "hello1"; 262 | // same with: 263 | cout.operator<<("hello1"); 264 | 265 | // example 2: 266 | cout << "hello2" << "world"; 267 | 268 | // extraction operator (>>) 269 | // cin: console input'un kısaltmasından gelir. 270 | // cin reads from console-input-stream. 271 | char charArr[100]; 272 | cin >> charArr; 273 | ``` 274 | -------------------------------------------------------------------------------- /tutorials/c_standart_libraries.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # C STANDART LIBRARIES 5 | ############################ 6 | 7 | ############################ 8 | 9 | # standart kütüphaneler 10 | bu kısım özellikle bir implementasyona göre yazılmadı. 11 | 12 | - assert.h 13 | 14 | ```c 15 | scanf("%d", &a); 16 | 17 | // it runs depending on a configuration. 18 | // if it fails, itwill throw exception. 19 | assert(a >= 10); 20 | 21 | printf("Integer entered is %d\n", a); 22 | ``` 23 | 24 | - ctype.h 25 | - int isalnum(int c) - is alphanumeric 26 | - int isdigit(int c) 27 | - int toupper(int c) 28 | 29 | - errno.h 30 | 31 | Bazı fonksiyonlar hata döndüklerinde genelde -1 dönerler. ek olarak "errno" değerine de hata numarasını set ederler. bu integer değer errno.h içerisindedir. 32 | 33 | errno değeri thread-lokaldir. bu sebeple multi-thread uygulamalarda her thread için farklı bir instance tutulur. bu sebeple exception kontrollerimizi buradan sorunsuzca yapabiliriz. 34 | 35 | errno C standardında thread-lokal diildir. Fakat çoğu modern POSIX thread-local olarak şekilde ayarlamıştır. 36 | 37 | - limits.h 38 | 39 | aşağıdaki sabit değerleri barındırıyor 40 | - CHAR_BIT 41 | - LONG_MAX 42 | - LONG_MIN 43 | 44 | - stdio.h 45 | 46 | dosya veya diğer stream'ler üzerine okuma yazma işlemleri yapabilmemizi sağlayan fonksiyonlar içerir 47 | - int fclose(FILE *stream) 48 | - int printf(const char *format, ...) 49 | 50 | - stdlib.h 51 | 52 | Memory management, array sort, search gibi utility olarak gruplandırabileceğimiz fonksiyonlar içerir 53 | 54 | - void *calloc(size_t nitems, size_t size) - memory management fonksiyon 55 | - void exit(int status) - terminate the application 56 | - void *bsearch(const void *key, const void *base, size_t nitems, size_t size, int (*compar)(const void *, const void *)) - binary search 57 | - void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*)) - quick sort 58 | 59 | - math.h 60 | 61 | - double tanh(double x) 62 | - double log(double x) 63 | 64 | - complex.h 65 | 66 | matematikteki karmaşık sayılar üzerinde işlem yapmamızı sağlayan fonksiyonlar içerir 67 | 68 | - stdint.h 69 | 70 | fixed-size variable'lar barındırır. 71 | 72 | - inttypes.h 73 | 74 | stdint.h'i içinde zaten barındırıyor. bu kütüphane stdint içinde gelen fixed-size variable'ların printf, scanf gibi standart metotlarla çalışabilmeleri için formatter'ları barındırıyor. örnek: 75 | 76 | > PRId64 = "ld" 77 | 78 | sabiti inttypes.h içerisindedir. bu değer ile standart c kütüphane metotu olan printf ile şunu yapabiliriz: 79 | 80 | ```c 81 | printf("%+"PRId64"\n", myInt64Var); 82 | ``` 83 | 84 | C'de string birleştirmeyi derleyici bizim için yapıyor. dolayısı ile yukarıdaki printf metotu şuna tekabül ediyor: 85 | 86 | ```c 87 | printf("%+ld\n", myInt64Var); 88 | ``` 89 | 90 | - sysexits.h 91 | 92 | exit status tamsayılarını barındırıyor. konu başka başlıkta anlatılıyor. 93 | 94 | - signal.h 95 | 96 | Sinyal handler fonksiyonunu ve sinyallerin integer değerlerini barındırıyor. konu başka başlıkta anlatılıyor. 97 | 98 | - stdint.h 99 | 100 | sabit boyutlar tamsayılar barındıran kütüphanedir. boyutlar aşağıdaki tablodadır: 101 | 102 | | Değişken | İşareti | Bits | Bytes | Minimum Değer | Maksimum Değer | 103 | |----------|----------|------|-------|------------------------------------|---------------------------------------| 104 | | int8_t | Signed | 8 | 1 | −2^7 = −128 | 2^7 − 1 = 127 | 105 | | uint8_t | Unsigned | 8 | 1 | 0 | 2^8 − 1 = 255 | 106 | | int16_t | Signed | 16 | 2 | −2^15 = −32,768 | 2^15 − 1 = 32,767 | 107 | | uint16_t | Unsigned | 16 | 2 | 0 | 2^16 − 1 = 65,535 | 108 | | int32_t | Signed | 32 | 4 | −2^31 = −2,147,483,648 | 2^31 − 1 = 2,147,483,647 | 109 | | uint32_t | Unsigned | 32 | 4 | 0 | 2^32 − 1 = 4,294,967,295 | 110 | | int64_t | Signed | 64 | 8 | −2^63 = −9,223,372,036,854,775,808 | 2^63 − 1 = 9,223,372,036,854,775,807 | 111 | | uint64_t | Unsigned | 64 | 8 | 0 | 2^64 − 1 = 18,446,744,073,709,551,615 | 112 | -------------------------------------------------------------------------------- /tutorials/c_terminology.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # C TERMINOLOGY 5 | ############################ 6 | 7 | ############################ 8 | 9 | # C version history 10 | 11 | __ANSI C (or ISO C or Standard C)__ American National Standards Institute (ANSI) ve International Organization for Standardization tarafından geliştirilen C dili spesifikasyonudur. Birçok sürümü vardır. spesifikasyon sürümleri: 12 | 13 | | kısaltma | spesifikasyon resmi ID | resmi stabil yayım yılı | makro değeri __STDC_VERSION__ | 14 | |--------------|----------------------------------------------------------------------------------------------|-------------------------|-------------------------------| 15 | | | Brian Kernighan and Dennis Ritchie published the first edition of The C Programming Language | 1978 | not exist | 16 | | C89 | ANSI X3.159-1989 | 1989 | not exist | 17 | | C90 | ISO/IEC 9899:1990 | 1990 | not exist | 18 | | C95 | ISO/IEC 9899/AMD1:1995 | 1995 | not exist | 19 | | C99 | ISO/IEC 9899:1999 | 1999 | 199901L | 20 | | C11 | ISO/IEC 9899:2011 | 2011 | 201112L | 21 | | C18 yada C17 | ISO/IEC 9899:2018 | 2018 | 201710L | 22 | 23 | # C standard library (or libc or ISO C library) 24 | __Libc__, __American National Standards Institute (ANSI)__ ve __International Organization for Standardization__ tarafından geliştirilen, piyasada kabul görmüş temel birçok işlevleri bulunduran C kütüphaneleridir. 25 | 26 | Libc'ye alternatif birçok kütüphane vardır. bazıları: 27 | 28 | - __C POSIX library__ kütüphanesi Libc'nin bir türevidir. çok büyük oranla libc ile uyumludur, ek olarak birçok farklı fonksiyon da içerir. 29 | - __BSD Libc__, implementations distributed under BSD operating systems 30 | - __GNU C Library (Glibc)__, used in GNU Hurd, GNU/kFreeBSD and Linux 31 | - __Microsoft C run-time library__, part of Microsoft Visual C++ 32 | - __Dietlibc__, an alternative small implementation of the C standard library (MMU-less) 33 | - __μClibc__, a C standard library for embedded μCLinux systems (MMU-less) 34 | - __Newlib__, a C standard library for embedded systems (MMU-less) 35 | - __Klibc__, primarily for booting Linux systems 36 | - __musl__, another lightweight C standard library implementation for Linux systems 37 | - __Bionic__, originally developed by Google for the Android embedded system operating system, derived from BSD libc 38 | 39 | # C++ 40 | C is not a subset of C++. C programs will not compile as C++ code without modification. C++ was introduces as extension of C. But after a while C++ introduced many features that are not available in C. 41 | 42 | C ve C++'ın interoperability'si çok yüksek. birbirlerini direk olarak call edebiliyorlar. kaynak: (source-id: 227) title: "CPL.3: If you must use C for interfaces, use C++ in the calling code using such interfaces". 43 | 44 | # GCC (or GNU Derleyici Koleksiyonu or GNU Compiler Collection) 45 | Açık kaynaklıdır ve birçok programlama dilleri için (C, C++, Objective-C, Fortran, Java, Ada, Go) derleyici içerir. 46 | 47 | İlk versiyonu sadece C derleyicisi içeriyordu. Bu sebeple eski versiyonlarının ismi yine GCC idi, fakat açılımı __GNU C Compiler__ idi. 48 | 49 | # g++ 50 | GCC'nin içindeki bir komut satırı uygulamasıdır. Sadece C++ Compiler'ıdır. gcc komutu ile yapılabileceklerin aynısını sağlar. fakat sadece C++ derlediği için, komutların C++ için ayarlanmış olması büyük kolaylıklar sağlamaktadır. 51 | 52 | # Bloodshed Dev-C++ 53 | Bloodshed firması tarafından geliştirilen sadece Microsoft Windows üzerinde çalışan C ve C++ için IDE'dir. compiler olarak gcc veya onun türevlerini kullanmaktadır. 54 | 55 | # turbo c 56 | Borland firması tarafından geliştirilen IDE ve C/C++ derleyicisidir. İsmi daha sonra __Turbo C++__ olmuştur. fakat proje sonlanmıştır. 57 | 58 | # Objective-C 59 | bu şekilde de kullanılır: __ObjC__ yada __Objective C__ yada __Obj-C__. 60 | 61 | Apple ürünlerinde kullanılan fakat platform bağımsız bir dildir. Nesneye yönelimlidir. 62 | 63 | C dilinden türetilmiştir. C diline ek olarak nesne oluşturma syntax'ları eklenmiştir. kaynak: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html Fakat superset/subset olayından hiç bahsedilmemiş. Yani; nesneye yönelimli olması için yeni syntax eklenmiştir fakat var olanlar değiştirildi mi diye özel bir bilgi yok. Fakat buralarda C'nin superset'i olduğu belirtilmiş: 64 | - https://developer.apple.com/library/archive/referencelibrary/GettingStarted/RoadMapOSX/books/WriteObjective-CCode/WriteObjective-CCode/WriteObjective-CCode.html 65 | - https://www.informit.com/articles/article.aspx?p=1765122 66 | - https://www.drdobbs.com/examining-objective-c/184402055 67 | 68 | # C# 69 | C veya C++'ın superset'i veya subset'i değildir. 70 | -------------------------------------------------------------------------------- /tutorials/database_h2.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # DATABASE H2 5 | ############################ 6 | 7 | ############################ 8 | 9 | # H2 10 | Starting the server doesn't open a database. Databases are opened as soon as a client connects. 11 | 12 | # dialect and driver 13 | H2 server has its own JDBC driver. It will not work with others. 14 | 15 | But H2 server is compatible with different dialects. But the database connection should initialize with spesific mode. example JDBC URL compatible with MSSQLServer: 16 | 17 | ``` 18 | jdbc:h2:~/test;MODE=MSSQLServer 19 | ``` 20 | 21 | or it can be change anytime using simple SQL: 22 | 23 | ```sql 24 | SET MODE MSSQLServer 25 | ``` 26 | 27 | H2 itself has it's own SQL dialect. It is enabled as default. 28 | 29 | # modes 30 | 31 | This term should not be confused with the "mode" property which is using on JDBC-URL. 32 | 33 | - Embedded Mode 34 | 35 | does not opens a "H2 server". only 1 connection is available on the same database. Only the process itself can connect to DB. 36 | 37 | - Server Mode (or remote mode or client/server mode) 38 | 39 | A standalone process starts the "H2 server" app. It opens JDBC or ODBC API via TCP. 40 | 41 | - Mixed Mode 42 | 43 | "H2 server" starting inside from Java app itself. Other process can connect via TCP. 44 | 45 | # Start server 46 | 47 | - inside from Java app: 48 | 49 | ```java 50 | import org.h2.tools.Server; 51 | 52 | Server server = Server.createTcpServer(args).start(); 53 | server.stop(); 54 | ``` 55 | 56 | This method calling "__Embedded Mode__". 57 | 58 | - using standalone executable file: 59 | 60 | ```sh 61 | java -cp "/h2/bin/h2-1.4.199.jar" "org.h2.tools.Server" 62 | ``` 63 | 64 | This method calling "__Server Mode (or remote mode or client/server mode)__". 65 | 66 | # Connection URL & Mode 67 | - Local file path: 68 | 69 | > JDBC:h2:~/file_path/test3 70 | 71 | On above example "~" means home directory of course. 72 | 73 | > JDBC:h2:file_path/test3 74 | 75 | On above example, the file path does not start with file seperator. Therefore it use the home directory as base path. Which means: $HOME/file_path/test3 76 | 77 | - TCP 78 | 79 | > JDBC:h2:tcp://localhost/~/file_path/test2 80 | 81 | - In-Memory 82 | 83 | Does not persist DB to a file. H2 uses only RAM. 84 | 85 | > JDBC:h2:mem:test1 86 | 87 | # H2 Console 88 | embedded to "h2.jar". It can be optionally started together with "h2 server". It serves a simple web page to connect and manage (execute query, view tables...) different databases. When the end-user try to connect to a database, the web page sends HTTPrequests to the H2 Console backend and the backend connects to DB via TCP and returns the results to the front-end. 89 | -------------------------------------------------------------------------------- /tutorials/database_pivot_table.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # DATABASE PIVOT TABLE 5 | ############################ 6 | 7 | ############################ 8 | 9 | # pivot table 10 | 11 | pivot Türkçe anlamları: en önemli nokta, püf nokta, çark etmek, eksen üzerinde dönmek. 12 | 13 | pivot olarak belirlediğimiz sütuna ait satırları, sütun haline çevirip oluşturduğumuz tabloya pivot tablosu denir. 14 | 15 | en basit örnekle ilerleyelim: 16 | 17 | - bir sipariş tablomuz var. 18 | 19 | - Bir müşterinin verdiği her bir sipariş bir satırda gösteriliyor. 20 | 21 | - Her müşteri için son 6 aylık sipariş bilgilerini görmek istiyoruz. 22 | 23 | 24 | > ||| SiparisID ||| MusteriAdSoyad ||| UrunAdi ||| Tutar ||| Donem ||| 25 | 26 | tablomuz olsun. 27 | 28 | pivot tablomuzu oluşturursak; 29 | 30 | ```sql 31 | SELECT * 32 | 33 | FROM ( 34 | 35 | SELECT 36 | 37 | MusteriAdSoyad 38 | 39 | ,Donem 40 | 41 | ,sum(Tutar) as ToplamTutar 42 | 43 | FROM Siparis 44 | 45 | group by MusteriAdSoyad ,Donem 46 | 47 | ) as gTablo 48 | 49 | PIVOT 50 | 51 | ( 52 | 53 | SUM(ToplamTutar) 54 | 55 | FOR Donem IN ([200911],[200912],[201001]) 56 | 57 | ) 58 | 59 | AS p 60 | ``` 61 | 62 | Tablomuz şöyle olacaktır: 63 | 64 | > ||| MusteriAdSoyad ||| 200911 ||| 200912 ||| 65 | 66 | MS Excel gibi uygulamalarda da pivot tablosu yapabilmek için fonksiyonlar hazır sunulmaktadır. 67 | -------------------------------------------------------------------------------- /tutorials/database_sql_commands_quick_examples.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # DATABASE SQL COMMANDS QUICK EXAMPLES 5 | ############################ 6 | 7 | ############################ 8 | 9 | ```sql 10 | 11 | ------------------------------------------ 12 | ------------------------------------------ 13 | -- CREATE SCHEME AND DATA 14 | -- TESTES ONLY WITH: SQLite 3.46.1 15 | ------------------------------------------ 16 | ------------------------------------------ 17 | 18 | -- TABLE NAME: customers 19 | 20 | -- Name |Value | 21 | -- -------+--------+ 22 | -- id |1 | 23 | -- name |user1 | 24 | -- surname|surname1| 25 | 26 | 27 | -- TABLE NAME: orders 28 | 29 | -- id|customer_id|status|active| 30 | -- --+-----------+------+------+ 31 | -- 1| 1| 100| 1| 32 | -- 2| 1| 101| 1| 33 | -- 3| 1| 102| 0| 34 | -- 4| 2| 103| 1| 35 | 36 | drop table if exists customers; 37 | drop table if exists orders; 38 | 39 | CREATE TABLE customers ( 40 | id INTEGER PRIMARY KEY AUTOINCREMENT, 41 | name TEXT, 42 | surname TEXT 43 | ); 44 | 45 | INSERT INTO customers 46 | (name, surname) 47 | VALUES 48 | ('user1', 'surname1'), 49 | ('user2', 'surname2'); 50 | 51 | CREATE TABLE orders ( 52 | id INTEGER PRIMARY KEY AUTOINCREMENT, 53 | customer_id INTEGER, 54 | status INTEGER, 55 | active BOOLEAN 56 | ); 57 | 58 | INSERT INTO orders 59 | (customer_id, status, active) 60 | VALUES 61 | (1, 100, true), 62 | (1, 101, true), 63 | (1, 102, false), 64 | (2, 103, true); 65 | 66 | ------------------------------------------ 67 | ------------------------------------------ 68 | -- EXAMPLE 1 69 | ------------------------------------------ 70 | ------------------------------------------ 71 | 72 | -- show status list for each customer. 73 | -- output should be: 74 | 75 | -- name status list 76 | -- user1 100,101 77 | -- user2 103 78 | 79 | ------------------------------------------ 80 | ------------------------------------------ 81 | -- NOTES: 82 | -- For below 2 solutions SQLite group_concat built-in function has been used. 83 | -- For MS-SQL "STRING_AGG" built-in function can be used. It gets same parameters. 84 | ------------------------------------------ 85 | ------------------------------------------ 86 | 87 | -- SOLUTION 1 --------------------------- 88 | -- with LEFT JOIN and GROUP BY 89 | ------------------------------------------ 90 | select 91 | customers.name, 92 | group_concat(orders.status, ',') AS 'status list' 93 | from customers 94 | left join orders 95 | on 96 | ( 97 | customers.id = orders.customer_id 98 | AND 99 | orders.active = true 100 | ) 101 | GROUP by customers.name 102 | 103 | -- SOLUTION 2 --------------------------- 104 | -- execute independed SQL inside SELECT. 105 | ------------------------------------------ 106 | select 107 | customers.name, 108 | ( 109 | ( 110 | SELECT group_concat(orders.status , ',') 111 | FROM orders 112 | where 113 | customers.id = orders.customer_id 114 | AND 115 | orders.active = true 116 | ) 117 | ) as 'status list' 118 | from customers 119 | 120 | 121 | ------------------------------------------ 122 | ------------------------------------------ 123 | -- EXAMPLE 2 124 | ------------------------------------------ 125 | ------------------------------------------ 126 | 127 | -- show active and passive order-ids for each customer. 128 | -- output should be: 129 | 130 | -- name passive-order-id-list active-order-id-list 131 | -- user1 3 1,2 132 | -- user2 4 133 | 134 | -- SOLUTION --------------------------- 135 | -- execute independed SQL inside SELECT. 136 | ------------------------------------------ 137 | select 138 | customers.name, 139 | ( 140 | SELECT 141 | group_concat(orders.ID, ',') 142 | FROM orders 143 | WHERE 144 | orders.active = FALSE 145 | AND 146 | customers.id = orders.customer_id 147 | ) AS 'passive-order-id-list', 148 | 149 | ( 150 | SELECT 151 | group_concat(orders.ID, ',') 152 | FROM orders 153 | WHERE 154 | orders.active = TRUE 155 | AND 156 | customers.id = orders.customer_id 157 | ) AS 'active-order-id-list' 158 | 159 | from customers 160 | 161 | 162 | -- WRONG ANSWER -------------------------- 163 | -- Join "orders" multiple times 164 | ------------------------------------------ 165 | 166 | select 167 | 168 | customers.name, 169 | 170 | group_concat(passive_orders.ID, ',') AS 'passive-order-id-list', 171 | 172 | group_concat(active_orders.ID, ',') AS 'active-order-id-list' 173 | 174 | from customers 175 | 176 | left join orders AS passive_orders 177 | on 178 | ( 179 | customers.id = passive_orders.customer_id 180 | AND 181 | passive_orders.active = false 182 | ) 183 | 184 | left join orders AS active_orders 185 | on 186 | ( 187 | customers.id = active_orders.customer_id 188 | AND 189 | active_orders.active = true 190 | ) 191 | 192 | GROUP by customers.name 193 | 194 | -- Result of above SQL: 195 | -- name |passive-order-id-list|active-order-id-list| 196 | -- -----+---------------------+--------------------+ 197 | -- user1|3,3 |1,2 | 198 | -- user2| |4 | 199 | 200 | -- The above example will not show result corretly. because we join same table multiple times. 201 | -- To understand beter, execute the above SQL (it is same SQL above. I only remove SELECT and GROUP BY) 202 | 203 | select 204 | * 205 | from customers 206 | 207 | left join orders AS passive_orders 208 | on 209 | ( 210 | customers.id = passive_orders.customer_id 211 | AND 212 | passive_orders.active = false 213 | ) 214 | 215 | left join orders AS active_orders 216 | on 217 | ( 218 | customers.id = active_orders.customer_id 219 | AND 220 | active_orders.active = true 221 | ) 222 | 223 | -- Result of above SQL: 224 | 225 | -- id|name |surname |id|customer_id|status|active|id|customer_id|status|active| 226 | -- --+-----+--------+--+-----------+------+------+--+-----------+------+------+ 227 | -- 1|user1|surname1| 3| 1| 102| 0| 1| 1| 100| 1| 228 | -- 1|user1|surname1| 3| 1| 102| 0| 2| 1| 101| 1| 229 | -- 2|user2|surname2| | | | | 4| 2| 103| 1| 230 | 231 | 232 | ``` 233 | -------------------------------------------------------------------------------- /tutorials/gradle.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # GRADLE 5 | ############################ 6 | 7 | ############################ 8 | 9 | # Gradle 10 | 11 | Groovy syntax'ı ile build script yazmaya yarıyor (Groovy syntax'ı başka başlıkta anlatılmıştır). sadece JVM tabanlı projeler için değil, programlama dilinden bağımsızdır. şu anda çoğu eklentisi Java tabanlı projeler için yazılığı için öyle bir algı oluşturmuş. 12 | 13 | # Kotlin 14 | Gradle Groovy'nin yanında Kotlin syntax'ını da destekliyor. dosyanın Kotlin ile yazıldığını belirtmek için her Gradle dosyasının sonuna kts eklemek gerekiyor. örnek: 15 | 16 | > build.gradle.kts 17 | 18 | # files 19 | 20 | - # build.gradle 21 | 22 | tüm işleyişin belirlendiği dosya 23 | 24 | - # gradle.properties 25 | 26 | properties formatında dosyasıdır. key-value şeklinde build.Gradle tarafına parametre geçmek için kullanılır. 27 | 28 | - # settings.gradle 29 | 30 | tüm sub-modüller için geçerli olan key-value şeklindeki property'leri ve işleyişin de belirlenebileceği dosyadır. sub-modüller içeren projede sadece 1 tane (root projede) olması gerekir alt projelerde olmamalıdır. 31 | 32 | # lifecycle 33 | 34 | - initialization phase 35 | 36 | bu arada Gradle sadece sub-modüllerin var olup olmadıklarını kontrol ediyor. 37 | 38 | - configuration phase 39 | 40 | __Gradle builds a Directed Acyclic Graph (DAG)__ algoritması kullanarak task'larda döngü olup olmadığını temsil ediyor. 41 | 42 | - execution phase 43 | 44 | tüm build task'larının çalıştırıldığı fazdır. ilk 2 faz IDE eklentileri tarafından default çağrılırken, bu fazın çağrılması için bir komut gerekmektedir. 45 | 46 | # tasks 47 | 48 | Gradle'da fazlar aslında basit yapıdadır. Gradle task'lar üzerine kuruludur. task başka task'ları çağırır. hangi task'ların olacağına plugin'ler karar verir. Java-plugin'i, bazı istisnalar dışında Maven ile aynı isimlere sahip task'lar tanımlamıştır. bu şekilde Maven'a alışmış geliştiriciler, Gradle'daki task'ları da çağırabilir. 49 | 50 | build.Gradle içinde; 51 | 52 | ```groovy 53 | task hello { 54 | doLast { 55 | println 'hello world' 56 | } 57 | } 58 | ``` 59 | 60 | task'ımızı şu şekilde run ediyoruz: 61 | 62 | > gradle –q hello 63 | 64 | yada 65 | 66 | > gradlew hello 67 | 68 | Gradlewrapper otomatik olarak task çağırmaktadır. 69 | 70 | "gradlew --help" ile "gradlew help" ayrı komutlardır. 71 | 72 | Eclipse'te Gradle eklentisi varsa "Gradle tasks" view'ı tüm Gradle task'larını listelemektedir. Gradle task'ları önce proje bazlı gruplandırılmakta daha alt seviyede ise 'task grup'ları bazında listelenmektedir. task'larımızı gruplandırmak istersek; örnek hello task'ımızı bir grup altına alalım: 73 | 74 | build.Gradle dosyamızın içine bunu eklememiz yeterli: 75 | 76 | ```groovy 77 | hello.group = MY_GROUP_NAME 78 | ``` 79 | 80 | Gradle'da hiçbir eklenti yoksa "Help" ve grubu altında bir kaç task varsayılan olarak tanımlı gelir. bunlar Gradle executable'ın içine gömülmüş task'lardır: 81 | 82 | - build setup (task grup) 83 | 84 | - init (task) 85 | 86 | boş bir Gradle proje oluşturur. bulunduğumuz dizinde, Gradle.build dosyası vs oluşturur... 87 | 88 | - wrapper (task) 89 | 90 | Gradle wrapper dosyalarını bulunduğumuz dizinde oluşturur. 91 | 92 | - help (task group) 93 | 94 | - tasks (task) 95 | 96 | Displays the tasks runnable from root project 97 | 98 | - help 99 | 100 | displays help 101 | 102 | - (and others) 103 | 104 | # task dependsOn 105 | 106 | ```groovy 107 | task task4(dependsOn: [task1, task3]) << { 108 | 109 | println 'building task4' 110 | } 111 | ``` 112 | 113 | Artık task4 koştuğunda önce task1 sonra task3 koşacaktır. task1 ve task2 koşmuş ise (başka task tarafından) o zaman tekrar koşmaz. 114 | 115 | # :my-sub-project1:myTask 116 | 117 | bu şekilde altprojedeki bir task'ı çağırmış oluyoruz. örnek komut: 118 | 119 | > gradle :order-microservice:compile 120 | 121 | yada aşağıdaki aynı task'ı çalıştırmaktadır: 122 | 123 | > gradle order-microservice:compile 124 | 125 | # defaultTasks 126 | 127 | defaultTasks'lar eğer task ismi komut satırında hiç verilmemiş ise koşacak task'lardır. örnek: 128 | 129 | ```groovy 130 | defaultTasks 'clean', 'run' 131 | 132 | task clean { 133 | doLast { 134 | println 'Default Cleaning!' 135 | } 136 | } 137 | 138 | task run { 139 | doLast { 140 | println 'Default Running!' 141 | } 142 | } 143 | 144 | task other { 145 | doLast { 146 | println "I'm not a default task!" 147 | } 148 | } 149 | ``` 150 | 151 | > gradle -q 152 | 153 | komutu sadece clean ve run task'larını çağıracaktır. 154 | 155 | # Java plugin 156 | 157 | ```groovy 158 | apply plugin: 'java' 159 | 160 | repositories { 161 | 162 | mavenCentral() 163 | } 164 | 165 | dependencies { 166 | 167 | compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final' 168 | 169 | testCompile group: 'junit', name: 'junit', version: '4.+' 170 | 171 | } 172 | ``` 173 | 174 | # Java plugin dependency types 175 | 176 | - Compile 177 | - Runtime 178 | - Test Compile 179 | - Test Runtime 180 | 181 | # sourceSet 182 | 183 | Java plugin'inin sunduğu bir konsepttir. sourceSet; birlikte derlenecek resource ve Java kodlarının bulunduğu dizinlerdir. Örneğin default tanımlı main sourceSet'i: 184 | 185 | ```groovy 186 | sourceSets { 187 | 188 | main { 189 | 190 | Java { 191 | 192 | srcDirs = ['src/main/java'] 193 | 194 | } 195 | 196 | resources { 197 | 198 | srcDirs = ['src/main/resources'] 199 | 200 | } 201 | 202 | } 203 | 204 | } 205 | ``` 206 | 207 | gibi test source set'i de bulunur. isteğe bağlı ek source set'ler belirlenebilir. örnek: "integration-test" sourceSet gibi. 208 | -------------------------------------------------------------------------------- /tutorials/groovy.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # GROOVY 5 | ############################ 6 | 7 | ############################ 8 | 9 | # Groovy language syntax 10 | Groovy syntax başlığı, Gradle, Grovvy ile yazıldığı için önemli. sadece en temel seviyede syntax anlatılmıştır. 11 | 12 | Groovy her sınıfa otomatik olarak aşağıdaki paketleri import eder. Bu sebeple print gibi metotlar direk çağrılıyor. bu durumun Groovy'nin syntax'ı ile bir bağlantısı yoktur. 13 | 14 | ```groovy 15 | import java.lang.* 16 | import java.util.* 17 | import java.io.* 18 | import java.net.* 19 | import groovy.lang.* 20 | import groovy.util.* 21 | import java.math.BigInteger 22 | import java.math.BigDecimal 23 | ``` 24 | 25 | # special characters calls methods 26 | "technologies" instance'ı bir liste ise; 27 | 28 | ```groovy 29 | technologies = technologies - 'Grails' // removes an element form list 30 | technologies << "Groovy" // adds an element to list 31 | ``` 32 | 33 | her işaret spesific bir metotu çağırıyor. yani; technologies liste objesinde - işareti minus isimli metotu execute ediyor. biz de yaptığımız sınıfta minus metotunu - işareti ile çağırabiliriz. << gibi diğer karakterler: 34 | 35 | > + 36 | 37 | a.plus(b) 38 | 39 | > a[b] 40 | 41 | a.getAt(b) 42 | 43 | > - 44 | 45 | a.minus(b) 46 | 47 | > a[b] = c 48 | 49 | a.putAt(b, c) 50 | 51 | > * 52 | 53 | a.multiply(b) 54 | 55 | > a in b 56 | 57 | b.isCase(a) 58 | 59 | > / 60 | 61 | a.div(b) 62 | 63 | > << 64 | 65 | a.leftShift(b) 66 | 67 | > % 68 | 69 | a.mod(b) 70 | 71 | > \>> 72 | 73 | a.rightShift(b) 74 | 75 | > ** 76 | 77 | a.power(b) 78 | 79 | > \>>> 80 | 81 | a.rightShiftUnsigned(b) 82 | 83 | > | 84 | 85 | a.or(b) 86 | 87 | > ++ 88 | 89 | a.next() 90 | 91 | > & 92 | 93 | a.and(b) 94 | 95 | > -- 96 | 97 | a.previous() 98 | 99 | > ^ 100 | 101 | a.xor(b) 102 | 103 | > +a 104 | 105 | a.positive() 106 | 107 | > as 108 | 109 | a.asType(b) 110 | 111 | > -a 112 | 113 | a.negative() 114 | 115 | > a() 116 | 117 | a.call() 118 | 119 | > ~a 120 | 121 | a.bitwiseNegate() 122 | 123 | # closure 124 | 125 | ```groovy 126 | class MyClass { 127 | 128 | def str1 = 'Merhaba' 129 | 130 | } 131 | 132 | static void main(String[] args) { 133 | 134 | def str1 = "Hello"; 135 | 136 | def clos = { param -> println "${str1} ${param}" } //this is closure 137 | 138 | clos.call("World"); // prints "Hello World" 139 | 140 | // now we are changing the value of the String str1 which is referenced in the closure 141 | 142 | str1 = "Welcome"; 143 | 144 | clos.call("World"); // prints "Welcome World"; 145 | 146 | clos("World"); // yukarıdaki satır ile (call metotu ile) aynı görevi görüyor. 147 | 148 | clos.setDelegate(new MyClass() ); // we change the context of closure. 149 | 150 | clos("World"); //prints Merhaba World 151 | 152 | 153 | 154 | def myClosure2 = { println it }; // closure sadece 1 parametre alıyorsa, parametre tanımı yazılmak zorunda değildir. değişkenin ismi "it" olur. 155 | 156 | def myClosure3 = { String param -> println "${str1} ${param}" }; // closure'larda, istenirse parametre tipi verilebilir. 157 | 158 | } 159 | ``` 160 | 161 | # DSL support 162 | 163 | ```groovy 164 | a b c d 165 | ``` 166 | 167 | yukarıdaki kod satırı bunu yapıyor: 168 | 169 | ```groovy 170 | a(b).c(d) 171 | ``` 172 | 173 | # sadece Java ile farklılık gösteren kısımlarla bir örnek sınıf: 174 | 175 | ```groovy 176 | class Example { 177 | 178 | static void main(String[] args) { 179 | 180 | //def keyword 181 | 182 | def x = 5; //def keywordu Java'daki Object'e denk geliyor. def istenirse kullanılır. 183 | 184 | // range 185 | 186 | def range = 5..10; 187 | 188 | println(range); //prints 5 6 7 8 9 10 189 | 190 | println(range.get(2)) // prints 7 . noktalı virgül kullanılmayabilir. yeni satır yapmak yeterli. 191 | 192 | //for in statement 193 | 194 | for(int i in array) { 195 | 196 | println(i); 197 | 198 | } 199 | 200 | // for statement 201 | 202 | for(emp in employee) { 203 | 204 | println(emp); 205 | 206 | } 207 | 208 | } //end of main method 209 | 210 | //default parameter (if parameter will not pass than default value will be used) 211 | 212 | static void sum(int a,int b = 5) { 213 | 214 | //method code here 215 | 216 | } 217 | 218 | } //end of class 219 | ``` -------------------------------------------------------------------------------- /tutorials/java_aspect.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # JAVA ASPECT 5 | ############################ 6 | 7 | ############################ 8 | 9 | # Spring-aop 10 | Spring security web servise gelen istekleri kontrol ederken, loggining mekanizması debug log'ları atarken, hep AOP'den yararlanır. Spring-AOP, ona alternatif olan AspectJ'ye göre çok basit kalır. 11 | 12 | AOP dünyasında genel terminoloji şu şekildedir: 13 | 14 | - __Aspect__: tüm tanımlamaların (pointcuts, aspects...) olduğu kümedir (class'tır). Spring'deki @Aspect annotation'unu attığımız class'a denk gelir. 15 | 16 | - __Joinpoint__: aspect'in gireceği event'e denir. örneğin; "metot çağrılmadan önce", "exception fırlatıldıktan sonra" event'leri joinpoint'tir. yani; aspect'in join olacağı noktadır. 17 | 18 | - __Advice__: araya girecek yeni kod bloğumuza (fonksiyona) denir. 19 | 20 | - __Pointcut__: hangi aspect'in hangi joinpoint'te çalışacağını belirten tanımlamadır (expression'dır). 21 | 22 | - __Target Object__: advice'ın uygulandığı objeler/class'tır. örneğin; "Person" class'ının "die()" metotuna bir advice atamış olalım. bu durumda bu advice çalıştığında, target-objemiz "Person" class'ı olur. 23 | 24 | # AspectJ kullanımı 25 | 26 | ```java 27 | import org.aspectj.lang.*; 28 | 29 | @Aspect 30 | public class MyLoggingAspect 31 | { 32 | @Before("execution(# com.mycustompackage.MyService.myMethod(..))") 33 | 34 | public void beforeMyMethod(JoinPoint joinpoint) 35 | 36 | { 37 | System.out.println("Before "+joinpoint.getSignature().getName()); 38 | } 39 | 40 | @AfterThrowing( 41 | 42 | pointcut="execution(# com.mycustompackage.MyService.myMethod(..))", 43 | 44 | throwing="exception") 45 | 46 | public void afterMyMethodThrowException(JoinPoint joinPoint,Throwable exception) 47 | { 48 | System.out.println("After throw exception"); 49 | System.out.println("Exception: "+exception); 50 | } 51 | } 52 | ``` 53 | 54 | diğer bazı annotation'lar: 55 | 56 | - AfterReturning - it returns (does not throws an exception) 57 | 58 | - After -> return or throws an exception 59 | 60 | aspect işlemleri Java-core'da desteklenmediği için bazı trick'lerle gerçekleştirilir. bu trick'lere __weawing__ denir. 61 | 62 | weawing işlemi 3 farklı şekilde yapılabilir: 63 | 64 | - derleme esnasında. Java'da bir proxy sınıf yaratılır. öncesinde ve sonrasında çalışacak metotlar burada çağrılır. 65 | 66 | - özel bir classloader ile yüklenecek sınıfın Bytecode'u ile oynanır 67 | 68 | - runtime sırasında AOP modülü dinamik olarak bir proxy sınıfı üretir. Spring-aspect modülü bu şekilde çalışır. 69 | 70 | # Pointcut 71 | aspect metotlarını gruplandırmak için kullanılır. direk örnek üzerinden gidersek; 72 | 73 | ```java 74 | @Aspect 75 | public class Audience { 76 | 77 | @Pointcut("execution(public String com.mypackage.myaction(Long) )") 78 | public void performance() {} 79 | 80 | @Before("performance()") 81 | public void myMethod1() { 82 | //do something 83 | } 84 | 85 | @Before("performance()") 86 | public void myMethod2() { 87 | //do something 88 | } 89 | 90 | @AfterReturning("performance()") 91 | public void myMethod3() { 92 | //do something 93 | } 94 | } 95 | ``` 96 | 97 | YUkarıda before, AfterReturning gibi tüm metotlar aynı sınıfta olan Pointcut metotu performance'ı işaret ediyor. böylece Pointcut'ta bir değişiklik olduğunda tüm aspectlerin aksiyon alması gereken nokta tek bir yerden belirlenmiş oluyor. 98 | 99 | Yukarıda performance() metotu tanımlamasına (annotationu ile birlikte) __pointcut signature__ deniliyor. 100 | 101 | # pointcut designator (or PCD) 102 | 103 | @Pointcut içerisindeki tanımlaya verilen isimdir. Birçok PCD vardır. örnek: 104 | 105 | Aşağıdaki PCD, public/private ve protected olan tüm Class1 sınıfı içindeki metotları kapsamaktadır. 106 | 107 | > @Pointcut("execution(* com.package.Class1.*(..))") 108 | 109 | Aşağıdaki PCD, sadece Long alan findById metotunu kapsamaktadır. 110 | 111 | > @Pointcut("execution(public String com.package.Class1.findById(Long))") 112 | 113 | Aşağıdaki PCD, Class1 içindeki tüm metotları kapsamaktadır. 114 | 115 | > @Pointcut("within(com.package.Class1)") 116 | 117 | Aşağıdaki PCD, find ile başlayan ve sadece 1 adet long parametresi kabul eden tüm metotları kapsamaktadır: 118 | 119 | > @Pointcut("execution(* *..find*(Long))") 120 | 121 | Aşağıdaki PCD, find ile başlayan ve ilk parametresinde long kabul eden tüm metotları kapsamaktadır: 122 | 123 | > @Pointcut("execution(* *..find*(Long,..))") 124 | 125 | Aşağıdaki PCD, Repository annotation'u içeren sınıfın tüm metotlarını kapsamaktadır. 126 | 127 | > @Pointcut("@target(org.springframework.stereotype.Repository)") 128 | 129 | Aşağıdaki PCD, Entity annotation'unu içeren nesneleri parametre olarak kabul eden tüm metotları kapsamaktadır 130 | 131 | > @Pointcut("@args(org.myapp.aop.annotations.Entity)") 132 | 133 | Aşağıda iki adet PCD birleştirilmiştir: 134 | 135 | ```java 136 | @Pointcut("@target(org.springframework.stereotype.Repository)") 137 | public void repositoryMethods() {} 138 | 139 | @Pointcut("execution(* *..create*(Long,..))") 140 | public void firstLongParamMethods() {} 141 | 142 | @Pointcut("repositoryMethods() && firstLongParamMethods()") 143 | public void entityCreationMethods() {} 144 | ``` 145 | 146 | # @Around 147 | bir Pointcut'ı referans etmiş tüm aspect metotlarını harmanlayabiliriz. 148 | 149 | direk örnek üzerinden gidelim: 150 | 151 | ```java 152 | @Aspect 153 | public class Audience { 154 | 155 | @Pointcut("execution(*# concert.Performance.perform(..))") 156 | public void performance() {} 157 | 158 | @Around("performance()") 159 | public void watchPerformance(ProceedingJoinPoint jp) { 160 | 161 | System.out.println("before all aspects"); 162 | jp.proceed(); 163 | System.out.println("after all aspects"); 164 | } 165 | } 166 | ``` 167 | 168 | # handling parameters 169 | aspect ettiğimiz metota geçilen parametreleri de alabiliriz: 170 | 171 | ```java 172 | @Pointcut( 173 | "execution(# soundsystem.CompactDisc.playTrack(int)) " + 174 | "&& args(trackNumber)") 175 | public void trackPlayed(int trackNumber) {} 176 | 177 | @Before("trackPlayed(trackNumber)") 178 | public void countTrack(int trackNumber) { 179 | 180 | //do something with trackNumber 181 | } 182 | ``` -------------------------------------------------------------------------------- /tutorials/java_future.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # JAVA FUTURE 5 | ############################ 6 | 7 | ############################ 8 | 9 | # java.util.concurrent.Future 10 | 11 | ```java 12 | public class SquareCalculator { 13 | 14 | // ExecutorService Java içinde gelen, Birçok thread'i yönetebilmemizi sağlayan bir yapıdır. 15 | private ExecutorService executor = Executors.newSingleThreadExecutor(); 16 | 17 | public Future calculate(Integer input) { 18 | 19 | return executor.submit(() -> { 20 | 21 | Thread.sleep(1000); 22 | 23 | return input * input; 24 | }); 25 | } 26 | } 27 | 28 | Future future = new SquareCalculator().calculate(10); 29 | 30 | while(!future.isDone()) { 31 | System.out.println("Calculating..."); 32 | Thread.sleep(300); 33 | } 34 | 35 | Integer result = future.get(); //get metotu eğer yukarıdaki while'ı yazmamış olsaydık, işlem tamamlanana kadar bekleyecekti. şimdiki durumda beklemesine gerek yok, çünkü zaten yukarıda işlemin bittiğine dair kontrolümüzü while içerisinde yaptık. 36 | ``` 37 | 38 | Future sınıfı şu metotları sunar: 39 | 40 | - Boolean Cancel(boolean mayInterruptIfRunning) 41 | 42 | eğer task zaten kapanmışsa yada kapatılamadıysa false döner. 43 | 44 | - V get() 45 | 46 | V dönüş objemiz. metotun ne yaptığı kod yukarıdaki kod içinde açıklandı. 47 | 48 | - V get(long Timeout, TimeUnit unit) 49 | 50 | metot belli aralıkta dönmezse TimeoutException fırlatır. 51 | 52 | - Boolean isCancelled() 53 | 54 | - Boolean isDone() 55 | 56 | # java.util.concurrent.CompletableFuture 57 | java.util.concurrent.Future implementasyonudur. ek özellikler sunar. Future'nin eksiklerini kapatmak için daha sonradan geliştirilmiştir. kapattığı eksikler: 58 | 59 | - zincir oluşturabilme 60 | 61 | üstüste Future'leri sırası ile execute etme 62 | 63 | - exception handling 64 | 65 | - manually complete the future 66 | 67 | ```java 68 | completableFuture.complete("Future's Result"); 69 | ``` 70 | 71 | bu satır sonrası, completableFuture'ı kullanan tüm metotlar isDone=true olacaktır. 72 | 73 | - callback metotu verebilme 74 | 75 | ```java 76 | CompletableFuture future = CompletableFuture.runAsync(new Runnable() { 77 | @Override 78 | public void run() { 79 | // any code here 80 | } 81 | }); 82 | 83 | future.get() 84 | ``` 85 | 86 | Aynı işi lambda ile çok daha kısa yapabiliriz: 87 | 88 | ```java 89 | CompletableFuture future = CompletableFuture.runAsync(() -> { 90 | // any code here 91 | }); 92 | ``` 93 | 94 | Sadece future kullansaydık; get()'ten sonra metotumuzu elle çalıştırmak zorunda kalacaktık ve işlemin success mi olup olmadığını da kontrol etmemiz gerekecekti. 95 | 96 | Burada callback metotumuz istersek obje de dönecek şekilde ayarlayabilirdik. 97 | 98 | CompletableFuture'ın bazı metotları birbirlerine çok benziyor. Asıl farkları bir önceki callback metotundan dönen parametreyi alıp almadıkları ve kendilerinin ne döndürdükleridir. aşağıdaki tablo üzerinde özet bilgiye ulaşılabilir: 99 | 100 | tablo kaynağı: (source-id: 420) 101 | 102 | | Method | Async method | Arguments | Returns | 103 | |----------------|---------------------|-----------------------------------------|--------------------------------| 104 | | thenRun() | thenRunAsync() | – | – | 105 | | thenAccept() | thenAcceptAsync() | Result of previous stage | – | 106 | | thenApply() | thenApplyAsync() | Result of previous stage | Result of current stage | 107 | | thenCompose() | thenComposeAsync() | Result of previous stage | Future result of current stage | 108 | | thenCombine() | thenCombineAsync() | Result of two previous stages | Result of current stage | 109 | | whenComplete() | whenCompleteAsync() | Result or exception from previous stage | – | 110 | 111 | # Promise 112 | standart Java içerisinde Promise objesi yoktur. CompletableFuture, diğer dillerde kullanılan promise kavramına en yakın objedir. 113 | -------------------------------------------------------------------------------- /tutorials/java_jsp_and_jsf.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # JAVA JSP AND JSF 5 | ############################ 6 | 7 | ############################ 8 | 9 | # JSP (or JavaServer Pages) 10 | 11 | JSP'de sayfalar, sunucu tarafta derlenip client'a gönderilir. her JSP sayfası, bir servlet'e çevrilir. servlet Java sınıfıdır. 12 | 13 | JSP dosyaları, Java servlet sınıfına çevrilirken: 14 | 15 | JSP dosyası: 16 | 17 | ```xml 18 | 19 | <% 20 | double num = Math.random(); 21 | if (num > 0.95) { 22 | %> 23 |

You will have a luck day!

(<%= num %>)

24 | ``` 25 | 26 | Java servlet sınıfı: 27 | 28 | ```java 29 | import java.io.*; 30 | import javax.servlet.*; 31 | import javax.servlet.http.*; 32 | public class MyServlet extends HttpServlet { 33 | 34 | // Runs when the servlet is loaded onto the server. 35 | public void init() { 36 | // servlet init codes here... 37 | } 38 | 39 | // Runs on a thread whenever there is HTTP GET request 40 | 41 | // Take 2 arguments, corresponding to HTTP request and response 42 | 43 | public void doGet(HttpServletRequest request, HttpServletResponse response) 44 | 45 | throws IOException, ServletException { 46 | 47 | // Set the MIME type for the response message 48 | 49 | response.setContentType("text/html"); 50 | 51 | // Write to network 52 | 53 | PrintWriter out = response.getWriter(); 54 | 55 | // Your servlet's logic here 56 | 57 | out.write("\r\n "); 58 | 59 | double num = Math.random(); 60 | 61 | if (num > 0.95) { 62 | 63 | out.write("

You will have a luck day!"); 64 | 65 | .... 66 | 67 | } 68 | ``` 69 | 70 | # JSP ile single page application 71 | Bu konu başlığı da okunması faydalı olacaktır: [file:"web.md" - title:"submit request vs Ajax"](./web.md#submit-request-vs-ajax) 72 | 73 | JSP ile single page application yapısına uygun değildir. fakat eğer yapılmak isteniyor ise bir çok farklı yöntem uygulanabilir. 74 | 75 | normalde JSP tüm sayfayı döner ve HTML'e o output yazılır. fakat biz eğer servlet'e isteği, JS'te oluşturduğumuz manuel bir Ajax işlemi ile yapar ve dönüş değerini manuel sayfanın bir kısmını güncelleyecek şekilde ayarlarsak o zaman single page application yapmış oluruz. aynı şey Spring MVC içinde geçerlidir. 76 | 77 | # JSP debug 78 | Eclipse debug perspektifindeyken, variables view'ı JSP dosyasında debug point koymamıza izin veriyor. runtime'da hangi değerlerin olduğunu da gösteriyor. bunun için Eclipse'te WTP (or web tools platform) plugin'i yüklü olmalıdır. 79 | 80 | # JavaServer Pages Standard Tag Library (or JSTL) 81 | JSTL JavaEE'nin bir modülüdür. 82 | 83 | jst JSP için core seviyede JSP tag'leri içerir. Gruplanmışlardır. 84 | 85 | sadece ihtiyacımız olan grubu JSP dosyamıza import ederiz: 86 | 87 | ```jsp 88 | <%@ taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %> 89 | ``` 90 | 91 | - ## Core Tags 92 | ```jsp 93 | 94 | 95 | 96 | ``` 97 | 98 | - ## Formatting tags 99 | ```jsp 100 | 101 | 102 | ``` 103 | 104 | - ## SQL tags 105 | SQL sorgusu çalıştırmayı ve bunu bir değere atayabilmemizi sağlar. 106 | ```jsp 107 | 108 | 109 | ``` 110 | 111 | - ## XML tags 112 | XML parse işlemleri yapmamızı sağlayan metotlar içerir. 113 | 114 | - ## JSTL Functions 115 | Hazır temel fonksiyonlar içerir. Çoğu string işlemleridir. 116 | 117 | # JSF (or Java Server Faces) 118 | 119 | JSF; JSP üzerine kurulu bir yapıdır. JSF'te, JSP gibi derleme ve servlet'in cevabı dönme işlemine ek olarak; altyapısı lifecycle'lar üzerinden hareket etmesini sağlamaktadır. 120 | 121 | JSP'de her JSP dosyası bir class'a denk gelirken, JSF'te her JSF dosyası tek bir servlet üzerinden (faces servlet) dağıtılır. 122 | 123 | JSF; MVC mimarisinde şu şekilde ayrılır: 124 | 125 | - M: modellerimiz (veritabanı modelleri gibi) 126 | 127 | - V: XHTML dosyalarımız 128 | 129 | - C: FacesServlet ---> çünkü view'lardaki değerleri güncelleyecek olan kodlar, aynı zamanda modelleri güncelleyecek olan kodlar buradadır. 130 | 131 | # Primefaces vs Icefaces vs Richfaces vs Myfaces 132 | 133 | Primefaces ve Icefaces ve Richfaces; JSF üzerine kuruludur. JSF tag'lerine ek kendi tag'lerini sunar. 134 | 135 | Myfaces; bir JSF implementasyonudur. 136 | -------------------------------------------------------------------------------- /tutorials/java_query_and_criteria_and_predicate.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # JAVA QUERY AND CRITERIA AND PREDICATE 5 | ############################ 6 | 7 | ############################ 8 | 9 | # javax.persistence.Query 10 | 11 | ```java 12 | Query query = getEntityManager().createQuery("SELECT u FROM UserEntity u WHERE u.id=:param1"); 13 | query.setParameter("param1", 99); 14 | UserEntity userEntity = (UserEntity) query.getSingleResult(); 15 | ``` 16 | 17 | __TypedQuery__ is the implementation of the Query. TypedQuery only stores the result class as a result, so we don't need to cast the executed result. 18 | 19 | ```java 20 | TypedQuery query = getEntityManager().createQuery("SELECT u FROM UserEntity u WHERE u.id=:param1"); 21 | query.setParameter("param1", 99); 22 | UserEntity userEntity = query.getSingleResult(); 23 | ``` 24 | 25 | __org.hibernate.query.NativeQuery__ ise javax.persistence.Query implementasyonudur. Kullanımı: 26 | 27 | ```java 28 | Query nativeQuery = getEntityManager().createNativeQuery("SELECT * FROM users WHERE id=:param1", UserEntity.class); 29 | query.setParameter("param1", 99); 30 | UserEntity userEntity = (UserEntity) query.getSingleResult(); 31 | ``` 32 | 33 | __NamedQuery__, Query implementasyonu değildir. Bir annotation'dur. Direk entity'de tanımlanmak üzere tasarlanmışlardır: 34 | 35 | ```java 36 | @org.hibernate.annotations.NamedQueries({ 37 | 38 | @org.hibernate.annotations.NamedQuery(name = "query1", 39 | query = "from DeptEmployee where employeeNumber = :employeeNo"), 40 | 41 | @org.hibernate.annotations.NamedQuery(name = "quer2", 42 | query = "from DeptEmployee where designation = :designation"), 43 | 44 | @org.hibernate.annotations.NamedQuery(name = "quer3", 45 | query = "Update DeptEmployee set department = :newDepartment where employeeNumber = :employeeNo") 46 | }) 47 | public class UserEntity { 48 | 49 | @Id 50 | private Long id; 51 | private String name; 52 | } 53 | ``` 54 | 55 | "Named" prefix'i kullanıldığında ismi ile çağrıldığıdan dolayı verilmiştir. Örnek kullanım: 56 | 57 | ```java 58 | Query namedQuery = getEntityManager().createNamedQuery("query1"); 59 | namedQuery.setParameter("employeeNo", id); 60 | UserEntity userEntity = (UserEntity) namedQuery.getSingleResult(); 61 | ``` 62 | 63 | # Criteria and Predicate classes of JPA 64 | 65 | "Spring Data" da bu sınıfları kullanır. Çünkü Spring-Data, JPA'yı wrap ediyor. 66 | 67 | Burada her satırı detaylı açıklanmış 3 önemli örnek var: https://github.com/yusuf-daglioglu/orm-examples-with-spring/ 68 | 69 | Burada birçok Criteria API örnekleri mevcut: https://en.wikibooks.org/wiki/Java_Persistence/Criteria 70 | 71 | # fetch join 72 | SQL'de böyle bir keyword yok ve zaten ihtiyaç yoktur. JPQL'e ait bir terimdir. Fakat "fetch" keyword'ü SQL'de tamamen farklı bir amaç için kullanılıyor. 73 | 74 | ```java 75 | @Table 76 | class Customer { 77 | String id; 78 | String name; 79 | 80 | @ManyToMany(fetch = FetchType.LAZY) 81 | String List orders; 82 | } 83 | ``` 84 | 85 | Yukarıdaki entity üzerinden veritabanında data çekmeye kalktığımızda "order" bilgisi gelmeyecektir. Ancak "getOrders()" metotunu çağırdığımızda JPA otomatik olarak yeni bir SQL isteği atacaktır. Çünkü "LAZY" annotation'u vardır. 86 | 87 | Eğer biz tek bir SQL sorgusunda tüm verinin dönmesini istiyorsak JPA'nın sunduğu "fetch join" özelliğini kullanabiliriz. 88 | 89 | ```java 90 | Query query = em.createQuery("SELECT DISTINCT c FROM Customer c INNER JOIN FETCH c.oders o"); 91 | ``` 92 | 93 | Ek not: Eğer alan LAZY olmasaydı ve biz sadece Customer tablosunu çekseydik, JPA arkaplanda "join" yapacaktı. Yani aşağıdaki 2 query aynı anlama gelmektedir: 94 | 95 | ```java 96 | Query query1 = em.createQuery("SELECT DISTINCT c FROM Customer c"); 97 | Query query2 = em.createQuery("SELECT DISTINCT c FROM Customer c INNER JOIN c.orders o"); 98 | ``` 99 | 100 | # JPA Metamodel 101 | 102 | ```xml 103 | 104 | org.hibernate 105 | hibernate-jpamodelgen 106 | 5.3.7.Final 107 | 108 | ``` 109 | 110 | Yukarıdaki bağımlılık build fazında tüm entity class'larımızı tarayıp, target dizini altına aşağıdaki kodları oluşturuyor: 111 | 112 | ```java 113 | @Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor") 114 | @StaticMetamodel(Student.class) 115 | public abstract class Student_ { 116 | 117 | public static volatile SingularAttribute firstName; 118 | public static volatile SingularAttribute lastName; 119 | public static volatile SingularAttribute id; 120 | 121 | public static final String FIRST_NAME = "firstName"; 122 | public static final String LAST_NAME = "lastName"; 123 | public static final String ID = "id"; 124 | } 125 | ``` 126 | 127 | Biz bu sınıflar sayesinde aşağıdaki gibi kod hazabiliyoruz: 128 | 129 | ```java 130 | Predicate p = builder.equal(Student_.LAST_NAME, authorName); 131 | 132 | // Eğer bu sınıflar oluşturulmasaydı field ismini hardcode yazmak zorunda kalacaktık: 133 | Predicate p = builder.equal(from.get("lastName"), authorName); 134 | ``` -------------------------------------------------------------------------------- /tutorials/java_querydsl.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # JAVA QUERY DSL 5 | ############################ 6 | 7 | ############################ 8 | 9 | # QueryDSL 10 | build sırasında code generation'ı yaparak, birçok Java kütüphanesi için ek query sağlayan kütüphanedir. desteklediği kütüphaneler: 11 | 12 | - JPA 13 | - SQL 14 | - MongoDB 15 | - Collections 16 | 17 | JPA için örnek olarak kullanımına bakalım: 18 | 19 | ```xml 20 | 21 | 22 | 23 | 24 | com.querydsl 25 | querydsl-apt 26 | ${querydsl.version} 27 | provided 28 | 29 | 30 | 31 | 32 | com.querydsl 33 | querydsl-jpa 34 | ${querydsl.version} 35 | 36 | 37 | 38 | 39 | 40 | 41 | com.mysema.maven 42 | apt-maven-plugin 43 | 1.1.3 44 | 45 | 46 | 47 | process 48 | 49 | 50 | target/generated-sources/java 51 | com.querydsl.apt.jpa.JPAAnnotationProcessor 52 | 53 | 54 | 55 | 56 | ``` 57 | 58 | Java kodumuzda User isimli bir entity varsa; "mvn compile" komutunu çalıştırdığımızda QUser isimli bir sınıf generate edilecektir. QUser içerisinde birçok query yapabilmemizi sağlayan metot mevcuttur. örnek kullanım: 59 | 60 | ```java 61 | EntityManagerFactory emf = Persistence.createEntityManagerFactory(); // default JPA class 62 | EntityManager em = emf.createEntityManager(); // default JPA class 63 | 64 | JPAQueryFactory queryFactory = new JPAQueryFactory(em); // com.querydsl.jpa.impl.JPAQueryFactory 65 | 66 | QUser user = QUser.user; // QUser is auto-generated by QueryDSL library. QUser includes a default instance of QUser as static. 67 | 68 | // simple get example 69 | User c = queryFactory.selectFrom(user) 70 | .where(user.login.eq("David")) 71 | .fetchOne(); 72 | 73 | // order example 74 | List c = queryFactory.selectFrom(user) 75 | .orderBy(user.login.asc()) 76 | .fetch(); 77 | 78 | // update example 79 | queryFactory.update(user) 80 | .where(user.login.eq("Ash")) 81 | .set(user.login, "Ash2") 82 | .set(user.disabled, true) 83 | .execute(); 84 | 85 | // delete example 86 | queryFactory.delete(user) 87 | .where(user.login.eq("David")) 88 | .execute(); 89 | ``` 90 | 91 | # Predicate 92 | Predicate kelime anlamı: yüklem, doğrulamak, belirtmek. 93 | 94 | kelime kökü predict'ten (öngörmek) gelmiyor. tamamen farklı kelimelerdir. 95 | 96 | Bilgisayar ve matematik bilimlerinde Predicate filtre yapıldığında uygulanacak kriterin tutulduğu instance/obje'ye verilen isimdir. Predicate, en basit örnek olarak aşağıdaki Java kodu ile örneklenmiştir. aşağıdaki filter metotu java.util.function.Predicate (Functional Interface) 'i argüman olarak kabul eder. 97 | 98 | ```java 99 | List list = Arrays.asList(1, 2, 3, 4, 5); 100 | 101 | List collect = list.stream().filter(x -> x > 3).collect(Collectors.toList()); 102 | ``` 103 | 104 | java.util.function.Predicate'in kodu bu şekildedir: 105 | 106 | Not: aşağıdaki koddaki yorumlara bakıldığında şu yorum çok önemli: 107 | 108 | ``` 109 | "predicate (boolean-valued function) of one argument." 110 | ``` 111 | 112 | ```java 113 | import java.util.Objects; 114 | 115 | /** 116 | * Represents a predicate (boolean-valued function) of one argument. 117 | */ 118 | @FunctionalInterface 119 | public interface Predicate { 120 | 121 | /** 122 | * Evaluates this predicate on the given argument. 123 | * 124 | * @param t the input argument 125 | * @return {@code true} if the input argument matches the predicate, 126 | * otherwise {@code false} 127 | */ 128 | boolean test(T t); 129 | 130 | /** 131 | Other code here! 132 | http://hg.openjdk.java.net/jdk8/jdk8/JDK/file/687fd7c7986d/src/share/classes/java/util/function/Predicate.java 133 | */ 134 | } 135 | ``` 136 | 137 | # QueryDSL Predicate 138 | 139 | örnek: 140 | 141 | ```java 142 | import org.springframework.data.querydsl.binding.QuerydslPredicate; 143 | import com.querydsl.core.types.Predicate; 144 | 145 | @GetMapping(value = "/users") 146 | public Page fetchUsers( 147 | @QuerydslPredicate(root = UserDBEntity.class) Predicate predicate, 148 | 149 | // "pageable" başka başlıkta anlatılıyor. bu konudan bağımsız. burada sadece birlikte kullanılabileceğini göstermeye çalıştım. pageable'ın konulması zorunlu değil. 150 | Pageable pageable 151 | ) { 152 | 153 | // repository should extends org.springframework.data.querydsl.QuerydslPredicateExecutor 154 | Page userListPageable = userRepository.findAll(predicate, pageable); 155 | 156 | // mpToDto QueryDSL'den bağımsız bir konu. database entity'sini dönmemek için burada basit bir mapping yapıldı. 157 | return userListPageable.map(UserDBEntity -> mapperUtil.mapToDto(UserDBEntity)); 158 | } 159 | ``` 160 | 161 | @QuerydslPredicate direk query'nin parametre olarak inject edilmesini sağlıyor. Aynı Pageable 'in yaptığı gibi. 162 | 163 | ```java 164 | // com.querydsl.core.types.dsl.BooleanExpression 165 | BooleanExpression b = QUser.user.email.eq("ahmet@gmail.com"); 166 | ``` 167 | 168 | BooleanExpression implements com.querydsl.core.types.Predicate interface. 169 | -------------------------------------------------------------------------------- /tutorials/java_servlet_stream.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # JAVA SERVLET STREAM 5 | ############################ 6 | 7 | ############################ 8 | 9 | # javax.servlet.http.HttpServletRequestWrapper 10 | Servlet veya onun implementasyonlarını wrap etmemizi sağlayan bir wrapper sınıfıdır. Bu sınıf Servlet'lerin davranışlarını değiştirmek istediğimizde kullanmamız için yaratılmıştır. 11 | 12 | örnek bir kullanım case'i: ServletFilter'ımızda request'in body'sine ihtiyacımız var. Normal koşullarda, ServletFilter içerisindeyken 'body' henüz inputstream'den okunmamış durumdadır. biz okuruz: 13 | 14 | ```java 15 | // Aşağıdaki satırda Apache-commons-io kullandım. stream'den string okumak için. o kullanılmadan da yapılabilirdi. basit okunabilir olsun diye böyle yazdım. 16 | String body = IOUtils.toString(request.getReader()); // 'request' yerine httpServletRequest'te olabilirdi. fark etmez. 17 | 18 | // do anything with 'body' 19 | 20 | chain.doFilter(request, response); // burada kod fail eder. çünkü biz @Controller metotumuza geldiğimizde gelen request objesi tümüyle okunum DTO'ya map edilir. Fakat okunmak istediğinde request objemizin stream'i zaten okunmuş olacağından hata alınacaktır. 21 | ``` 22 | 23 | Bu davranışı ezebilmek için HttpServletRequestWrapper kullanılır. önce HttpServletRequestWrapper implemetasyonumuzu yazalım. Bu implementasyon bize kalmış. Biz sadece input stream'in davranışını ezeceğiz: 24 | 25 | ```java 26 | import java.io.BufferedReader; 27 | import java.io.ByteArrayInputStream; 28 | import java.io.IOException; 29 | import java.io.InputStream; 30 | import java.io.InputStreamReader; 31 | 32 | import javax.servlet.ServletInputStream; 33 | import javax.servlet.http.HttpServletRequest; 34 | import javax.servlet.http.HttpServletRequestWrapper; 35 | 36 | public class RequestWrapper extends HttpServletRequestWrapper { 37 | private final String body; 38 | 39 | public RequestWrapper(HttpServletRequest request) throws IOException 40 | { 41 | super(request); //So that other request method behave just like before 42 | 43 | StringBuilder stringBuilder = new StringBuilder(); 44 | BufferedReader bufferedReader = null; 45 | try { 46 | InputStream inputStream = request.getInputStream(); 47 | if (inputStream != null) { 48 | bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); 49 | char[] charBuffer = new char[128]; 50 | int bytesRead = -1; 51 | while ((bytesRead = bufferedReader.read(charBuffer)) > 0) { 52 | stringBuilder.append(charBuffer, 0, bytesRead); 53 | } 54 | } else { 55 | stringBuilder.append(""); 56 | } 57 | } catch (IOException ex) { 58 | throw ex; 59 | } finally { 60 | if (bufferedReader != null) { 61 | try { 62 | bufferedReader.close(); 63 | } catch (IOException ex) { 64 | throw ex; 65 | } 66 | } 67 | } 68 | 69 | body = stringBuilder.toString(); 70 | } 71 | 72 | @Override 73 | public ServletInputStream getInputStream() throws IOException { 74 | final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes()); 75 | ServletInputStream servletInputStream = new ServletInputStream() { 76 | public int read() throws IOException { 77 | return byteArrayInputStream.read(); 78 | } 79 | }; 80 | return servletInputStream; 81 | } 82 | 83 | @Override 84 | public BufferedReader getReader() throws IOException { 85 | return new BufferedReader(new InputStreamReader(this.getInputStream())); 86 | } 87 | 88 | //Use this method to read the request body N times 89 | public String getBody() { 90 | return this.body; 91 | } 92 | } 93 | ``` 94 | 95 | Artık servlet-filter'ımızda bu satırı kullanabiliriz: 96 | 97 | ```java 98 | request = new RequestWrapper((HttpServletRequest) request); 99 | String body = request.getBody(); 100 | chain.doFilter(request, response); // this will work properly 101 | ``` 102 | 103 | Wrapper'ımızın getInputStream() metotunu override ettik. getInputStream metotunun implementasyona dikkat edilirse, sürekli yeni bir inputStream dönüyor. Bu şekilde Spring framework bunu çağırdığında ona da yeni bir input stream dönülecektir. 104 | 105 | HTTP'de "Body" stream'dir. Onun dışındaki alanlar önceden gelir (ilk okunur) ve onlar okunmadan hiçbir şekilde servlet metotu initialize edilmez. Bu sadece Spring'de değil, tüm framework'lerde bu şekildedir (örnek Javascript fetch API - bu konu başka başlıkta anlatılıyor). HTTP mantığı bu şekilde çalışacak şekilde tasarlanmıştır. 106 | 107 | # sadece body'nin stream olması 108 | 109 | aşağıdaki tüm bilgiler buradan alınmıştır: kaynak: (source-id: 223) 110 | 111 | ServletRequest.getParameter metotu özel bir metottur. web tarayıcısı, form submit yapıldığında GET veya POST olmasına göre form bilgilerini ya URL'ye yada body'ye basar. getParameter metotu her 2 durumu göz önüne bulundurarak çalışır ve tek bir metot üzerinden parametrelerin okunmasını sağlar. 112 | 113 | API dökümantasyonunda şu yazar: 114 | 115 | ``` 116 | If the parameter data was sent in the request body, such as occurs with an HTTP POST request, then reading the body directly via getInputStream() or getReader() can interfere with the execution of this method. 117 | ``` 118 | 119 | Yani (sadece "post" case için) biz inputStream okursak, getParameter metotunun işleyişi bozulacaktır. çünkü post case'leri için getParameter fonksiyonu da stream aracılığı ile bizim için data'yı okuyor. 120 | -------------------------------------------------------------------------------- /tutorials/java_spring_page.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # JAVA SPRING PAGE 5 | ############################ 6 | 7 | ############################ 8 | 9 | # Spring Page 10 | 11 | Spring pageable yapabilmek için JPA tarafında destek sunmaktadır. birkaç basit örnek ile ele alalım: 12 | 13 | - örnek 14 | 15 | ```java 16 | import org.springframework.data.repository.PagingAndSortingRepository; 17 | 18 | public interface UserRepository extends PagingAndSortingRepository { 19 | List findAllByName(String name, Pageable pageable); 20 | 21 | @Query("select c from Users c where c.age = :age") 22 | List findUsersCustom(@Param("age") String user, Pageable pageable); 23 | } 24 | ``` 25 | 26 | - farklı bir örnek 27 | 28 | ```java 29 | import org.springframework.data.domain.Page; 30 | import org.springframework.data.domain.Pageable; 31 | import org.springframework.data.jpa.repository.JpaRepository; 32 | import org.springframework.stereotype.Repository; 33 | 34 | @Repository 35 | public interface UserRepository extends JpaRepository{ 36 | Page findAll(Pageable pageable); 37 | } 38 | ``` 39 | 40 | ```java 41 | @Service 42 | public class UserService{ 43 | 44 | @Autowired 45 | UserRepository userRepository; 46 | 47 | public List findAll(PageRequest pageRequest){ 48 | Page usersPage = userRepository.findAll(pageRequest); 49 | return usersPage.getContent(); 50 | } 51 | } 52 | ``` 53 | 54 | ```java 55 | int page = 0; // index/number of page which we want to fetch from DB 56 | int pageSize = 5; // how much elements have the each page 57 | PageRequest pageRequest = new PageRequest(page, pageSize, new Sort(Sort.Direction.DESC, "userId")); 58 | List userList = userService.findAll(pageRequest); 59 | ``` 60 | 61 | - farklı bir örnek 62 | 63 | ```java 64 | private List findAll() { 65 | List allEmployees = new ArrayList<>(); 66 | 67 | // First page of employees -- 5000 results per page 68 | PageRequest pageRequest = PageRequest.of(0, 5000); 69 | Page employeePage = employeeRepository.findAll(pageRequest); 70 | allEmployees.addAll(employeePage.getContent()); 71 | 72 | // All the remaining employees 73 | // hasNext() is an offline method. it does not ask to DB runtime if another record(Employee) exist. it a simple fixed boolean inside employeePage instance. 74 | while (employeePage.hasNext()) { 75 | Page nextPageOfEmployees = employeeRepository.findAll(employeePage.nextPageable()); 76 | allEmployees.addAll(nextPageOfEmployees.getContent()); 77 | 78 | // update the page reference to the current page 79 | employeePage = nextPageOfEmployees; 80 | } 81 | 82 | return allEmployees; 83 | } 84 | ``` 85 | 86 | __org.springframework.data.domain.PageRequest__, __org.springframework.data.domain.Pageable__ arayüzünden türemiştir. 87 | 88 | ```java 89 | public interface Pageable { 90 | 91 | // index/number of page which we want to fetch from DB 92 | int getPageNumber(); 93 | 94 | // how much elements have the each page 95 | int getPageSize(); 96 | 97 | // sorting parameters 98 | Sort getSort(); 99 | 100 | // others 101 | } 102 | ``` 103 | 104 | __Pageable__ DB'ye yapılacak istek için gerekli meta bilgileri barındırır. 105 | 106 | __Page__ and __Slice__ arayüzleri ise DB'den dönen objeleri wrap eder. ikisinin içindeki temel metotlara bakalım: 107 | 108 | slice kelime anlamı: dilim 109 | 110 | ```java 111 | public interface Page extends Slice{ 112 | 113 | // total number of pages 114 | int getTotalPages(); 115 | 116 | // total number of items 117 | long getTotalElements(); 118 | 119 | // others 120 | } 121 | ``` 122 | 123 | ```java 124 | public interface Slice { 125 | 126 | // current page number 127 | int getNumber(); 128 | 129 | // page size 130 | int getSize(); 131 | 132 | // number of items on the current page 133 | int getNumberOfElements(); 134 | 135 | // list of items on this page (real data objects. example: List) 136 | List getContent(); 137 | 138 | // others 139 | } 140 | ``` 141 | 142 | Eğer bu bilgileri client'a döndürecek isek; o zaman Java main app metotumuzun tepesine __@EnableSpringDataWebSupport__ koymak zorundayız. Fakat Spring boot uygulamalarında SpringDataWebAutoConfiguration olduğu için bu annotation'a ihtiyacımız yok. Eğer bu annotation olmazsa şu tarz hata ile karşılaşabiliriz: 143 | 144 | > java.lang.NoSuchMethodException: org.springframework.data.domain.Pageable.\() 145 | 146 | Web örneği: 147 | 148 | ```java 149 | @GetMapping(path = "/users/page") 150 | Page loadUsersPage(Pageable pageable) { 151 | return userRepository.findAllPage(pageable); 152 | } 153 | ``` 154 | 155 | Spring otomatik olarak get query param'lara size, page, sort gibi parametreleri ekliyor. Sadece sort özelliğini parametre olarak kabul etmek isteyebilirdik: 156 | 157 | ```java 158 | @GetMapping(path = "/users/sorted") 159 | List loadUsersSorted(Sort sort) { 160 | return userRepository.findAllSorted(sort); 161 | } 162 | ``` 163 | 164 | Aşağıdaki örnekte Qualifier, query parametrelerimize prefix atabilmemizi sağlar: custom_size, custom_sort... 165 | 166 | ```java 167 | @GetMapping(path = "/users/qualifier") 168 | Page loadUsersPageWithQualifier( 169 | @Qualifier("custom") Pageable pageable) { 170 | ... 171 | } 172 | ``` 173 | -------------------------------------------------------------------------------- /tutorials/java_spring_spel.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # JAVA SPRING SPEL 5 | ############################ 6 | 7 | ############################ 8 | 9 | 10 | # spEL (or Spring Expression Language) 11 | 12 | 2 temel işlevi vardır: 13 | - regex işlemleri 14 | - Bean'e property atamalarında kullanılan özel bir syntax dilidir 15 | 16 | Bean property atamalarına örnekler verelim: 17 | 18 | örnek: 19 | 20 | ```xml 21 | 22 | ``` 23 | 24 | yada 25 | 26 | ```java 27 | @Value("#{100+1}") 28 | private String message; 29 | ``` 30 | 31 | Her property set edildiğinde (her yeni instance oluşturulduğunda), set edilecek 1 artacaktır. ilk değer 100 olacaktır. 32 | 33 | Diğer örnekler: 34 | 35 | Diğer örnekler: 36 | 37 | ```java 38 | @Value("#{1 == 1}") // true 39 | private boolean equal; 40 | 41 | @Value("#{1 eq 1}") // true 42 | private boolean equalAlphabetic; 43 | 44 | @Value("#{1 != 1}") // false 45 | private boolean notEqual; 46 | 47 | @Value("#{1 ne 1}") // false 48 | private boolean notEqualAlphabetic; 49 | 50 | @Value("#{1 < 1}") // false 51 | private boolean lessThan; 52 | 53 | @Value("#{1 lt 1}") // false 54 | private boolean lessThanAlphabetic; 55 | 56 | @Value("#{1 <= 1}") // true 57 | private boolean lessThanOrEqual; 58 | 59 | @Value("#{1 le 1}") // true 60 | private boolean lessThanOrEqualAlphabetic; 61 | 62 | @Value("#{1 > 1}") // false 63 | private boolean greaterThan; 64 | 65 | @Value("#{1 gt 1}") // false 66 | private boolean greaterThanAlphabetic; 67 | 68 | @Value("#{1 >= 1}") // true 69 | private boolean greaterThanOrEqual; 70 | 71 | @Value("#{1 ge 1}") // true 72 | private boolean greaterThanOrEqualAlphabetic; 73 | 74 | @Value("#{250 > 200 && 200 < 4000}") // true 75 | private boolean and; 76 | 77 | @Value("#{250 > 200 and 200 < 4000}") // true 78 | private boolean andAlphabetic; 79 | 80 | @Value("#{400 > 300 || 150 < 100}") // true 81 | private boolean or; 82 | 83 | @Value("#{400 > 300 or 150 < 100}") // true 84 | private boolean orAlphabetic; 85 | 86 | @Value("#{!true}") // false 87 | private boolean not; 88 | 89 | @Value("#{not true}") // false 90 | private boolean notAlphabetic; 91 | 92 | @Value("#{'100' matches '\\d+' }") // true 93 | private boolean validNumericStringResult; 94 | 95 | @Value("#{'100xyzabc' matches '\\d+' }") // false 96 | private boolean invalidNumericStringResult; 97 | 98 | @Value("#{'valid alphabetic string' matches '[a-zA-Z\\s]+' }") // true 99 | private boolean validAlphabeticStringResult; 100 | 101 | @Value("#{'invalid alphabetic string #$1' matches '[a-zA-Z\\s]+' }") // false 102 | private boolean invalidAlphabeticStringResult; 103 | 104 | @Value("#{someBean.someValue matches '\d+'}") // true if someValue contains only digits 105 | private boolean validNumericValue; 106 | ``` 107 | 108 | spEL aynı zamanda regex işlemlerini de yapıyor: 109 | 110 | ```java 111 | Expression expression = expressionParser.parseExpression("'Any string'.bytes"); 112 | Expression expression = expressionParser.parseExpression("'Any string'.replace(\" \", \"\").length()"); 113 | Integer result = (Integer) expression.getValue(); 114 | ``` 115 | -------------------------------------------------------------------------------- /tutorials/java_test.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # JAVA TEST 5 | ############################ 6 | 7 | ############################ 8 | 9 | # RestTemplate 10 | Aşağıdaki gibi kullanımı olan REST client'tır. Spring-web modülü içinde gelir. 11 | 12 | ```java 13 | RestTemplate restTemplate = new RestTemplate(); 14 | 15 | People people = restTemplate.getForObject("http://Google.com/people", People.class); 16 | 17 | log.info(people.toString()); 18 | ``` 19 | 20 | # TestRestTemplate 21 | Bu sınıf RestTemplate'ten extend etmez fakat RestTemplate'i private olarak kendi içinde bulundurur. neredeyse tüm metotları RestTemplate'teki metotları direk çağırır. yani RestTemplate'i wrap eder. fakat ekstradan testleri kolaylaştırmak amaçlı bazı metotlar içerir. örnek: 22 | 23 | - basic auth için password ve username'i veririz, artık her istekte bunları header'da yollar. 24 | 25 | - Constructor with HttpClientOption sunuyor. böylece options'ları constructor'da geçebiliyoruz. 26 | 27 | Aynı zamanda TestRestTemplate exception fırlatmaz. kodumuz çalışmaya devam eder. böylece testlerimizde try-catch bloklarımızın sayısı azalır. bunun yerine dönen response'u elle kontrolünü bize bırakır. bu durum testlerde try-catch'den dah açok terchi ediliyor çünkü. 28 | 29 | TestRestTemplate kesinlikle sadece testler için kullanılmalıdır. 30 | 31 | • • • • • • • • • • • • • • • • • • • • • • • • 32 | 33 | • • • • • • • • • • • • • • • • • • • • • • • • 34 | 35 | • • • • • • • • • • • • • • • • • • • • • • • • 36 | 37 | # Java'da assert kavramı 38 | Türkçe kelime anlamı: öne sürmek, iddia etmek. 39 | 40 | assert programlama dünyasında kullanılan genel bir mantıktır. assert, Java'da anahtar bir kelimedir. bu yüzden bir metot gibi kullanışı (syntax'ı) yoktur. Java 1.4 ile gelmiştir. örnek kullanımı şu şekildedir: 41 | 42 | ```java 43 | assert( 3 == myNumber ); 44 | ``` 45 | 46 | eğer kod runtime sırasında bu satıra geldiyse ve condition false ise; satır AssertionError fırlatacaktır. Eğer condition true ise; kod hiçbir sey yokmuş gibi devam edecektir. 47 | 48 | assert syntax'ı şu şekilde de kullanılabilir: 49 | 50 | ```java 51 | assert ( 3 == myNumber) : "error: number is not 3"; 52 | ``` 53 | 54 | condition sağlanmaz ise sağ taraftaki blok toString'e çevrilir ve AssertionError içerisine yazılır. 55 | 56 | Java da bir uygulama başlatırken assert keyword'lu satırlar devre dışıdır. yani hiç çalıştırılmaz. bunu enable etmek için Java uygulamasına en başta parametre geçmek gerekli. İsteğe bağlı olarak assert'leri sadece belirli paketlerde enable edebiliriz. 57 | 58 | # assert kütüphaneleri 59 | bazı kütüphaneler (JUnit gibi) assert metotları sunmaktadır. bu metotlar bildiğimiz Java sınıflarıdır. özel bir syntax olma durumu söz konusu değildir. 60 | 61 | Bazı assert kütüphaneleri, kendi içinde Java'daki 'assert'ü kullanıyor veya AssertionError fırlatıyor olabilir. 62 | 63 | • • • • • • • • • • • • • • • • • • • • • • • • 64 | 65 | • • • • • • • • • • • • • • • • • • • • • • • • 66 | 67 | • • • • • • • • • • • • • • • • • • • • • • • • 68 | 69 | # JBehave 70 | Java için BDD test sürecini işletmek için gerekli kütüphane. Temel olarak öncelikle; test için yapılacak işlemler story dosyalarına belirli formatlarda yazılıyor. Daha sonra Java içerisinde bu dosyalardaki her satıra (işleme) tekabül eden Java metotları yazılıyor. Örneğin; 71 | 72 | story dosyasının bir satırında: 73 | 74 | "When the page is www.google.com it will print type to search on the screen" 75 | 76 | Java sınıfında: 77 | 78 | ```java 79 | @When("When the page is " $URL ' it will print ' $PRINTED_TEXT " on the screen") 80 | public void checkWhatSiteHasPrinted(String URL, String PRINTED_TEXT){ 81 | 82 | //do the test here 83 | } 84 | ``` 85 | 86 | Daha sonra JBehave konfigürasyonları (çıktı rapor türü formatı gibi) yapılır. JBehave daha sonra story'leri run eder ve rapor çıktılarını istenilen dizine oluşturur. 87 | 88 | JBehave kendi içinde JUnit'e depend eder. JBehave kendi içinde JUnit testlerini çağırır. Bu çağrılan JUnit-test story dosyalarını okur ve bunları işletir. 89 | 90 | • • • • • • • • • • • • • • • • • • • • • • • • 91 | 92 | • • • • • • • • • • • • • • • • • • • • • • • • 93 | 94 | • • • • • • • • • • • • • • • • • • • • • • • • 95 | 96 | # Testcontainers 97 | birçok programlama dili için açık kaynaklı test kütüphanesidir. container'ları programatik ayağa kaldırmamızı sağlar. bu şekilde temel amaç testlerden önce ilgili testin, container içinde koşmasını sağlamaktır. 98 | 99 | isteğe bağlı; JUnit ile entegreli çalışabilir. bunun için ekstra lib eklemek gerekli: group-id:org.testcontainers package-id:JUnit-jupiter. 100 | 101 | ```java 102 | @Testcontainers 103 | class MyTestcontainersTests { 104 | 105 | // will be shared between test methods 106 | @Container 107 | private static final MySQLContainer MY_SQL_CONTAINER = new MySQLContainer(); 108 | 109 | // will be started before and stopped after each test method 110 | @Container 111 | private PostgreSQLContainer postgresqlContainer = new PostgreSQLContainer() 112 | .withDatabaseName("foo") 113 | .withUsername("foo") 114 | .withPassword("secret"); 115 | 116 | @Test 117 | void test() { 118 | 119 | String mySqlUrl = MySQLContainer.getJdbcUrl(); 120 | 121 | assertTrue(MY_SQL_CONTAINER.isRunning()); 122 | assertTrue(postgresqlContainer.isRunning()); 123 | } 124 | } 125 | ``` 126 | 127 | • • • • • • • • • • • • • • • • • • • • • • • • 128 | 129 | • • • • • • • • • • • • • • • • • • • • • • • • 130 | 131 | • • • • • • • • • • • • • • • • • • • • • • • • 132 | -------------------------------------------------------------------------------- /tutorials/java_test_junit.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # JAVA TEST JUNIT 5 | ############################ 6 | 7 | ############################ 8 | 9 | # JUnit 10 | test sınıfları verilecek aşağıdaki şekilde çağrılabilir: 11 | 12 | ```java 13 | JUnitCore junit = new JUnitCore(); 14 | Result result = junit.run(testClasses); 15 | ``` 16 | 17 | Fakat IDE'lerdeki JUnit eklentisi @test annotation'ları içeren metotların sınıflarını otomatik olarak çağırmaktadır. 18 | 19 | # JUnit 4 vs 5 20 | 5 inci sürüm ile büyük değişiklikler oldu. 21 | 22 | # modülerlik 23 | JUnit 5, 3 temel parçadan oluşuyor: 24 | - JUnit Platform: API (programatik çağrılabilmesi için arayüzler(API'ler) burada) 25 | - JUnit Jupiter: API implementasyonu. sadece junit5 annotation'larını çağırıyor. 26 | - JUnit Vintage: JUnit 3 and JUnit 4 kodlarını çalıştırabilmek için gerekli API implementasyonu. 27 | 28 | Her implementasyon (Jupiter, Vintage...), "Platform" modülündeki "TestEngine" class'ını implemente eder. kaynak: (source-id: 181) 29 | 30 | # Launcher 31 | JUnit 5 ile; Launcher kavramı geldi. "Launcher" programatik olarak testleri class'larda arayabiliyor, filtreleyebiliyor ve yürütebiliyor. Launcher'ın programatik olarak çağrılıyor dedik, işte bu API; "JUnit Platform Launcher API" olarak isimlendiriliyor ve artifact-ID'si: "junit-platform-launcher". 32 | 33 | # JUnit 4 integration to 5 34 | eğer runtime'da JUnit-vintage-engine varsa; JUnit-4 annotation'ları otomatik olarak launcher tarafından bulunur ve execute edilir. hiçbir ek ayara gerek yoktur. kaynak: (source-id: 182) "3.1. Running JUnit 4 Tests on the JUnit Platform" başlığı. 35 | 36 | Eğer junit4'ten tamamen geçilmek isteniyor ise buradakiler yapılmalıdır: kaynak: (source-id: 182) "3.2. Migration Tips" başlığı. 37 | 38 | # TestEngine 39 | JUnit 5 ile gelen bir kavramdır. Şu anda iki farklı TestEngine var: 40 | - junit-jupiter-engine 41 | - junit-vintage-engine 42 | 43 | Her test engine implementasyonu "JUnit-platform-engine" paketindeki arayüzleri implemente etmelidir. 44 | 45 | ## annotations 46 | | purpose of annotation | JUnit 4 | JUnit 5 | 47 | |------------------------------------------------------|--------------|--------------| 48 | | Declare a test method | @Test | @Test | 49 | | Execute before all test methods in the current class | @BeforeClass | @BeforeAll | 50 | | Execute after all test methods in the current class | @AfterClass | @AfterAll | 51 | | Execute before each test method | @Before | @BeforeEach | 52 | | Execute after each test method | @After | @AfterEach | 53 | | Disable a test method / class | @Ignore | @Disabled | 54 | | Test factory for dynamic tests | NA | @TestFactory | 55 | | Nested tests | NA | @Nested | 56 | | Tagging and filtering | @Category | @Tag | 57 | | Register custom extensions | NA | @ExtendWith | 58 | 59 | ## min java 60 | Junit 4 min Java 5 isterken, JUnit 5, min Java 8 istemektedir. 61 | 62 | ## test suite'ler 63 | 64 | JUnit 4: 65 | 66 | ```java 67 | import org.junit.runner.RunWith; 68 | import org.junit.runners.Suite; 69 | 70 | @RunWith(Suite.class) 71 | @Suite.SuiteClasses({ 72 | ExceptionTest.class, 73 | TimeoutTest.class 74 | }) 75 | public class JUnit4Example 76 | { 77 | } 78 | ``` 79 | 80 | JUnit 5: 81 | 82 | ```java 83 | import org.junit.platform.runner.JUnitPlatform; 84 | import org.junit.platform.suite.API.SelectPackages; 85 | import org.junit.runner.RunWith; 86 | 87 | @RunWith(JUnitPlatform.class) 88 | @SelectPackages("ExceptionTest.class", "TimeoutTest.class") 89 | public class JUnit5Example 90 | { 91 | } 92 | ``` 93 | 94 | # JUnit 5 örnek kod 95 | 96 | ```java 97 | JUnit 5 örnek test: 98 | 99 | import org.junit.jupiter.API.AfterAll; 100 | import org.junit.jupiter.API.AfterEach; 101 | import org.junit.jupiter.API.Assertions; 102 | import org.junit.jupiter.API.BeforeAll; 103 | import org.junit.jupiter.API.BeforeEach; 104 | import org.junit.jupiter.API.Disabled; 105 | import org.junit.jupiter.API.Tag; 106 | import org.junit.jupiter.API.Test; 107 | 108 | import com.myproject.junit5.examples.Calculator; 109 | 110 | public class AppTest { 111 | 112 | @BeforeAll 113 | static void setup(){ 114 | System.out.println("@BeforeAll executed"); 115 | } 116 | 117 | @BeforeEach 118 | void setupThis(){ 119 | System.out.println("@BeforeEach executed"); 120 | } 121 | 122 | @Tag("DEV") 123 | @Test 124 | void testCalcOne() 125 | { 126 | System.out.println("======TEST ONE EXECUTED======="); 127 | Assertions.assertEquals( 4 , Calculator.add(2, 2)); 128 | } 129 | 130 | @Tag("PROD") 131 | @Disabled 132 | @Test 133 | void testCalcTwo() 134 | { 135 | System.out.println("======TEST TWO EXECUTED======="); 136 | Assertions.assertEquals( 6 , Calculator.add(2, 4)); 137 | } 138 | 139 | @AfterEach 140 | void tearThis(){ 141 | System.out.println("@AfterEach executed"); 142 | } 143 | 144 | @AfterAll 145 | static void tear(){ 146 | System.out.println("@AfterAll executed"); 147 | } 148 | } 149 | ``` 150 | 151 | ```java 152 | @RunWith(JUnitPlatform.class) 153 | @SelectPackages("com.test.examples") //yada @SelectClasses( com.test.examples.ClassA.class ) 154 | @IncludePackages("com.test.example.packageB") 155 | @ExcludeTags("PROD") 156 | public class JUnit5TestSuiteExample 157 | { 158 | } 159 | ``` 160 | 161 | • • • • • • • • • • • • • • • • • • • • • • • • 162 | 163 | • • • • • • • • • • • • • • • • • • • • • • • • 164 | 165 | • • • • • • • • • • • • • • • • • • • • • • • • 166 | -------------------------------------------------------------------------------- /tutorials/java_test_spring.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # JAVA TEST SPRING 5 | ############################ 6 | 7 | ############################ 8 | 9 | # Spring-test 10 | spring'in bir modülünün özel ismidir. 11 | 12 | # @RunWith(SpringJUnit4ClassRunner.class) 13 | JUnit Spring'in özellikleri ile açılmalıdır. aksi durumda Spring özellikleri çalışmaz (yani injection'lar, Bean'ler özelliklerini kaybeder. normal sınıf olarak kullanımda kalırlar.). __SpringRunner__.class parametresi de __SpringJUnit4ClassRunner__'a referans ettiği için tamamiyle aynı işi görüyor. 14 | 15 | Bunun yerine JUnit 5 ile artık "__@ExtendWith__" kullanıyoruz. Fakat geriye uyumluluk için __@RunWith__ hala kullanılabiliyor. 16 | 17 | # @ContextConfiguration(locations = {...}) 18 | ApplicationContext'in belirlenmesi için yapılıyor. parametre olarak XML dosyasının path'i verilebilir, yada @Configuration sınıfı/sınıfları verilebilir. Her @Configuration içerisinde @ComponentScan yapıp, sadece ayağa kaldıracağımız Bean'lerin paket isimlerini verebiliriz. Böylece tüm Spring uygulaması ayağa kalkmaz. 19 | 20 | # @SpringBootTest 21 | Eğer Junt testi içinde @Configuration kullanılmamışsa, "/src/main/* (test olmayan paketler)" arasında @SpringBootConfiguration arar ve Spring context'i ayağa kaldırır. böylece Bean'ler test süresince kullanılabilir olur. 22 | 23 | __SpringJUnit4ClassRunner__ (veya __SpringRunner__) sadece testlerin Bean'ler kullanılarak çalışılacağını aktif eder. fakat application context'te Bean taraması yapmaz. Bean taraması olmadığından pek bir işe yarayamaz. bu sebeple __SpringRunner__ ve __SpringBootTest__ genelde birlikte kullanılır. 24 | 25 | __@SpringBootApplication__ içerisinde zaten __@EnableAutoConfiguration__ vardır. 26 | 27 | __@SpringBootTest__ default olarak tek başına Spring server'ı (web ortamı kısmını) ayağa kaldırmaz. kaynak: (source-id: 184) "25.3. Testing Spring Boot Applications" başlığı. 28 | 29 | Web ortamı oluşturmak için @SpringBootTest'e parametre geçmek gerekli: 30 | 31 | ```java 32 | @SpringBootTest(webEnvironment.MOCK) 33 | ``` 34 | 35 | webEnvironment aşağıdaki değerleri sunmaktadır: 36 | 37 | - # MOCK (Default) 38 | ApplicationContext'i kaldırır fakat mock bir web environment'i oluşturur. yani gerçek bir server ayağa kalkmaz. Mock controller'lar olacağı için: 39 | - @AutoConfigureMockMvc (reactive olamayan server'lara bağlanmak için) 40 | - yada @AutoConfigureWebTestClient (reactive olan server'lara bağlanmak için) 41 | 42 | gibi annotation'larla kullanılması önerilir. 43 | 44 | eğer classpath'te web dependency'leri yok ise; normal ApplicationContext'i init eder. 45 | 46 | - # RANDOM_PORT 47 | Gerçek server'ı uygulamayı ayağa kaldırır. Rastgele bir port ile dışarıya açar. 48 | 49 | - # DEFINED_PORT 50 | Gerçek server'ı uygulamayı ayağa kaldırır. port default port yada application.yml'de verilen porttur. 51 | 52 | - # NONE 53 | ApplicationContext'i, web ortamlarını tamemen ignore ederek ayağa kaldırır. 54 | 55 | If your test is @Transactional, it rolls back the transaction at the end of each test method by default. However, if you are using RANDOM_PORT or DEFINED_PORT which provides a real servlet environment, the HTTP client and server run in separate threads and, for that reason, they are separate transactions. Any transaction initiated on the server does not roll back in this case. 56 | 57 | # @WebMvcTest 58 | @WebMvcTest aşağıdaki iki annotation'u devreye sokar: 59 | 60 | - __@AutoConfigureWebMvc__ 61 | 62 | sadece SpingMVC modülünde bazı component'leri (@Controller, Filter'ları ...) ayağa kaldıracak şekilde Spring context'i ayağa kaldırır. bu şekilde testlerin başlama hızı daha yüksektir. çünkü sistemin sadece bir kısmı ayağa kalkar. Fakat bu durumda HTTP client ile sunucuya gerçek istek atılamaz. 63 | 64 | - __@AutoConfigureMockMvc__ 65 | 66 | MockMvc Bean'ini inject edebilmemiz sağlar. web slicing testing'de, server, full ayağa kalkmaz. dolayısı ile Controller'lar normal-standart yöntemlerle çağrılamaz. ancak bu işi "MockMvc" objesi yapabilir. MockMvc artık client API'mizdir. 67 | 68 | Yukarıdaki iki annotation bilgilerinden yola çıkarak şunu söyleyebiliriz: eğer testlerimize @AutoConfigureWebMvc ve @SpringBootTest yazarsak (@AutoConfigureWebMvc yazılmamışsa) server full ayağa kalkar ve yine testlerimiz mockMVC ile yapabiliriz. 69 | 70 | sadece 1 adet controller'ı ayağa kaldırmak için: 71 | 72 | ```java 73 | @WebMvcTest(HomeController.class) 74 | ``` 75 | 76 | @WebMvcTest test örneği: 77 | 78 | ```java 79 | @RunWith(SpringRunner.class) 80 | @WebMvcTest(UserVehicleController.class) 81 | public class UserVehicleControllerTests { 82 | 83 | @Autowired 84 | private MockMvc MVC; 85 | 86 | @MockBean // package: org.springframework.boot.test.mock.Mockito 87 | private UserVehicleService userVehicleService; 88 | 89 | @Test 90 | public void testExample() throws Exception { 91 | given(this.userVehicleService.getVehicleDetails("sboot")) 92 | .willReturn(new VehicleDetails("Honda", "Civic")); 93 | this.MVC.perform(get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN)) 94 | .andExpect(status().isOk()).andExpect(content().string("Honda Civic")); 95 | } 96 | } 97 | ``` 98 | 99 | bu tarz testlere "__slicing test__ (slice kelime anlamı: dilimlemek)" denir. çünkü sadece sistemin bir kısmı kaldırılır ve o kısımlar test edilir. bu test tipi, unit test'in bir türevidir. 100 | 101 | slicing test için Spring boot'ta bu annotation'lar sunulmaktadır: 102 | 103 | __@WebMvcTest__ - for testing the controller layer 104 | __@JsonTest__ - for testing the JSON marshalling and unmarshalling 105 | __@DataJpaTest__ - for testing the repository layer 106 | __@RestClientTests__ - for testing REST clients 107 | 108 | # @DataJpaTest 109 | full auto-configuration yapmayıp, sadece JPA ortamını ayağa kaldırıyor. 110 | 111 | her test metotu sonrası işlemler geri alınır. 112 | 113 | repo testleri entity ilişkilerinin doğru kurulup kurulmadığının ve özel yazılan query'lerin düzgün çalışıp çalışmadığını görebilmek için yapılır. 114 | 115 | ```java 116 | @RunWith(SpringRunner.class) 117 | @DataJpaTest 118 | public class CityRepositoryTest { 119 | 120 | @Autowired 121 | private CityRepository repository; 122 | 123 | @Test 124 | public void should_find_all_customers() { 125 | 126 | Iterable cities = repository.findAll(); 127 | 128 | assertThat(cities).hasSize(10); 129 | } 130 | } 131 | ``` 132 | 133 | @DataJpaTest, __TestEntityManager__ autowired edilebilmesini sağlar. TestEntityManager, EntityManager'i wrap etmez. ona alternatiftir. test için uygun olan metotları barındırır ve bazı EntityManager metotlarını barındırmaz. 134 | 135 | • • • • • • • • • • • • • • • • • • • • • • • • 136 | 137 | • • • • • • • • • • • • • • • • • • • • • • • • 138 | 139 | • • • • • • • • • • • • • • • • • • • • • • • • 140 | -------------------------------------------------------------------------------- /tutorials/java_validators.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # JAVA VALIDATORS 5 | ############################ 6 | 7 | ############################ 8 | 9 | # Validators 10 | 11 | # "Bean Validation" version history 12 | 13 | | version | RFC | 14 | |---------|---------| 15 | | 1.0 | JSR-303 | 16 | | 1.1 | JSR-349 | 17 | | 2.0 | JSR 380 | 18 | 19 | # Hibernate Validator 6.x 20 | Is the reference implementation of "JSR 380 (or Bean Validation 2.0)". 21 | 22 | Hibernate Validator offers additional value on top of the features required by Bean Validation. For example, a programmatic constraint configuration API as well as an annotation processor. 23 | 24 | # Apache BVal 25 | implementation of "JSR 380 (or Bean Validation 2.0)". 26 | 27 | # Compability matrix 28 | 29 | | Hibernate Validator | 7.0 | 6.2 | 6.0 | 30 | |-------------------------|---------|---------|---------| 31 | | Java | 8 or 11 | 8 or 11 | 8 or 11 | 32 | | Bean Validation | N/A | N/A | 2.0 | 33 | | Jakarta Bean Validation | 3.0 | 2.0 | N/A | 34 | 35 | # Spring Validation 36 | Spring support validation with "org.springframework.validation.Validator" interface. 37 | 38 | Spring has also optionally integration/support for "Bean Validation". "Bean Validation" is supporting also by adopting itself to "org.springframework.validation.Validator" interface. 39 | 40 | example implementation for org.springframework.validation.Validator: 41 | 42 | ```java 43 | public class PersonValidator implements org.springframework.validation.Validator { 44 | 45 | /** 46 | * This Validator validates *just* Person instances 47 | */ 48 | public boolean supports(Class clazz) { 49 | return Person.class.equals(clazz); 50 | } 51 | 52 | public void validate(Object obj, org.springframework.validation.Errors e) { 53 | ValidationUtils.rejectIfEmpty(e, "name", "name.empty"); 54 | Person p = (Person) obj; 55 | if (p.getAge() < 0) { 56 | e.rejectValue("age", "negativeValue"); 57 | } else if (p.getAge() > 110) { 58 | e.rejectValue("age", "too.darn.old"); 59 | } 60 | } 61 | } 62 | ``` 63 | 64 | Validate programatically (manually): 65 | 66 | ```java 67 | Person person = new Person(); 68 | person.setName("Jack"); 69 | BeanPropertyBindingResult result = new BeanPropertyBindingResult(person, "person"); 70 | ValidationUtils.invokeValidator(new PersonValidator(), person, result); 71 | result.getAllErrors().stream().forEach(e -> 72 | System.out.println(messageSource.getMessage(e, Locale.US))); 73 | ``` 74 | 75 | Spring MVC integration (only using "Bean validation" annotations): 76 | 77 | ```java 78 | @RequestMapping(value="/user", method=RequestMethod.POST) 79 | public createUser(Model model, @Valid @ModelAttribute("user") User user, BindingResult result){ 80 | if (result.hasErrors()){ 81 | // do something 82 | } 83 | else { 84 | // do something else 85 | } 86 | } 87 | ``` 88 | 89 | Spring MVC integration (only using "Bean validation" annotations): 90 | 91 | ```java 92 | @RequestMapping(value="/user", method=RequestMethod.POST) 93 | public createUser(Model model, @ModelAttribute("user") User user, BindingResult result){ 94 | 95 | // exception will not throw until here! Because we did not use @Valid annotation. 96 | 97 | UserValidator userValidator = new UserValidator(); 98 | userValidator.validate(user, result); 99 | 100 | if (result.hasErrors()){ 101 | // do something 102 | } 103 | else { 104 | // do something else 105 | } 106 | } 107 | ``` 108 | 109 | # JSR 380 (or Bean Validation 2.0) 110 | requires min Java 8. supports types like Optional and LocalDate. 111 | 112 | Dependencies: 113 | 114 | Only API (javax.validation.* packages): 115 | 116 | ```xml 117 | 118 | javax.validation 119 | validation-API 120 | 2.0.1.Final 121 | 122 | ``` 123 | 124 | Reference Implementation: 125 | 126 | ```xml 127 | 128 | org.hibernate.validator 129 | hibernate-validator 130 | 6.0.13.Final 131 | 132 | ``` 133 | 134 | Example: 135 | 136 | ```java 137 | import javax.validation.constraints.AssertTrue; 138 | import javax.validation.constraints.Max; 139 | import javax.validation.constraints.Min; 140 | import javax.validation.constraints.NotNull; 141 | import javax.validation.constraints.Size; 142 | import javax.validation.constraints.Email; 143 | 144 | public class User { 145 | 146 | @NotNull(message = "Name cannot be null") 147 | private String name; 148 | 149 | @AssertTrue 150 | private boolean working; 151 | 152 | @Size(min = 10, max = 200, message 153 | = "About Me must be between 10 and 200 characters") 154 | private String aboutMe; 155 | 156 | @Min(value = 18, message = "Age should not be less than 18") 157 | @Max(value = 150, message = "Age should not be greater than 150") 158 | private int age; 159 | 160 | @Email(message = "Email should be valid") 161 | private String email; 162 | 163 | // standard setters and getters 164 | } 165 | ``` 166 | 167 | Some other features: 168 | 169 | ```java 170 | List<@NotBlank String> preferences; 171 | ``` 172 | 173 | ```java 174 | public Optional<@Past LocalDate> getDateOfBirth() { 175 | return Optional.of(dateOfBirth); 176 | } 177 | ``` 178 | 179 | Spring integration (programatically validation): 180 | 181 | ```java 182 | ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 183 | Validator validator = factory.getValidator(); 184 | 185 | User user = new User(); 186 | user.setWorking(true); 187 | user.setAboutMe("Its all about me!"); 188 | user.setAge(50); 189 | 190 | Set> violations = validator.validate(user); 191 | 192 | for (ConstraintViolation violation : violations) { 193 | log.error(violation.getMessage() + violation.getPropertyPath()); 194 | } 195 | ``` -------------------------------------------------------------------------------- /tutorials/javascript_babel.md: -------------------------------------------------------------------------------- 1 | 2 | ############################ 3 | 4 | ############################ 5 | # JAVA BABEL 6 | ############################ 7 | 8 | ############################ 9 | 10 | # Babel 11 | bir node modülü. bu modül JS sürümleri arası compile sağlıyor. bu şekilde güncel yazılan kodların eski tarayıcılarda çalışabilmesini sağlıyor. 12 | 13 | Babel Ecmascript'te kullanılan tipleri ve flow'da kullanılan tipleri kaldırmaktadır. çünkü convert işlemi sonunda olan JS kodudur ve JS'te tip yoktur. 14 | 15 | Babel config dosyaları: 16 | - .babelrc 17 | - package.json içindeki "babel" anahtarı altındaki ayarlar 18 | - babel.config.js 19 | 20 | # .babelrc JSON vs babel.config.js 21 | .babelrc JSON iken, babel.config.js JS dosyasıdır ve programatik olarak configure edilebilir. örnek: 22 | 23 | .babelrc file: 24 | ```json 25 | { 26 | "presets": [...], 27 | "plugins": [...] 28 | } 29 | ``` 30 | 31 | babel.config.js file: 32 | ```js 33 | module.exports = function (API) { 34 | API.cache(true); 35 | 36 | const presets = [ ... ]; 37 | const plugins = [ ... ]; 38 | 39 | return { 40 | presets, 41 | plugins 42 | }; 43 | } 44 | ``` 45 | 46 | Babel için birçok node modülü vardır: 47 | 48 | - __@babel/core__ 49 | 50 | JS API'si sunar. aşağıdaki gibi import edilip, JS içerisinde code'u string olarak alıp kodu çevirebilir. 51 | 52 | ```js 53 | var babel = require("@babel/core"); 54 | //yada 55 | import { transform } from "@babel/core"; 56 | //yada 57 | import * as babel from "@babel/core"; 58 | 59 | //convert code 60 | babel.transform(code, options, function(err, result) { 61 | result; // => { code, map, ast } 62 | }); 63 | ``` 64 | 65 | - __@babel/cli__ 66 | 67 | Babel'in komut satırından kullanılabilmesi için gerekli node modülüdür. 68 | 69 | # Babel plugins 70 | 71 | Babel'de tonlarca eklenti var. örneğin Ecmascript'in her özelliği bir eklenti. bu şekilde convert işlemlerinde özellik özellik enable işlemi yapabiliriz. 72 | 73 | eklentiler 2 gruba ayrılıyor: 74 | 75 | - Transform Plugins 76 | 77 | Belli kod syntax'larını transform ediyor. örnekler: 78 | 79 | - @babel/plugin-transform-exponentiation-operator 80 | - @babel/plugin-transform-arrow-functions 81 | 82 | - Syntax Plugins 83 | 84 | Sadece parse işlemi yapıyorlar. transform yapamazlar. 85 | 86 | Genelde birçok plugin birarada kullanılır. bunlar gruplanmış şekilde hazır olarak dağıtılırlar. bunu bu şekilde Babel config dosyamızda belirtebiliriz: 87 | 88 | ```json 89 | { 90 | "presets": ["es2015", "react", "stage-2"] 91 | } 92 | ``` 93 | 94 | preset değilde, sadece plugin kullanmak istersek yine benzer config'i vardır: 95 | 96 | ```json 97 | { 98 | "plugins": ["transform-decorators-legacy", "transform-class-properties"] 99 | } 100 | ``` 101 | 102 | Pluginler ve preset'ler aynı config'de olabilir. çalışma sırası için kurallar vardır: 103 | 104 | - Plugins run before Presets. 105 | - Plugin ordering is first to last. 106 | - Preset ordering is reversed (last to first). 107 | 108 | # @babel/preset-env 109 | bir Babel preset'idir. desteklenen tarayıcı bilgisini config'e gireriz ve bu tarayıcı grubuna uyumlu kod üretir. 110 | 111 | örnek kullanım: 112 | 113 | ```json 114 | { 115 | "presets": [ 116 | [ 117 | "@babel/preset-env", 118 | { 119 | "targets": { 120 | "chrome": "58", 121 | "ie": "11" 122 | } 123 | } 124 | ] 125 | ] 126 | } 127 | 128 | ``` 129 | 130 | # Babel 6 "loose" mode 131 | 132 | - sadece ES5'e çevirirken kullanılan bir mode'dur. 133 | 134 | - Babel uygulaması, ES6 kodunu ES5 koduna çevirirken, daha çok ES6'ya uygun bir şemantik kullanmaya gayret ederek bunu yapıyor. 135 | 136 | - this mode normally is not recommended. 137 | -------------------------------------------------------------------------------- /tutorials/javascript_npm.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # JAVASCRIPT NPM 5 | ############################ 6 | 7 | ############################ 8 | 9 | # npm package versions 10 | 11 | - version 12 | 13 | Must match version exactly 14 | 15 | - \>version 16 | 17 | Must be greater than version 18 | 19 | - \>=version 20 | 21 | version'dan küçük sürümler 22 | 23 | - ~version 24 | 25 | "Approximately equivalent to version". See: "semver". example: ~1.2.3, will accept 1.2.5 but will miss 1.3.0. 26 | 27 | - ^version 28 | 29 | "Compatible with version". See semver. example: ^1.2.3, will accept 1.3.1 but will miss 2.0.0. 30 | 31 | - 1.2.x 32 | 33 | 1.2.0, 1.2.1, etc., but not 1.3.0 34 | 35 | - http://... 36 | 37 | will use the remote folder as dependency 38 | 39 | - # 40 | 41 | Matches any version 42 | 43 | - "" 44 | 45 | (just an empty string) Same as * 46 | 47 | - version1 - version2 48 | 49 | \>=version1 <=version2. 50 | 51 | - range1 || range2 52 | 53 | Passes if either range1 or range2 are satisfied. 54 | 55 | - git 56 | 57 | Git URLs as Dependencies 58 | 59 | - user/repo 60 | 61 | GitHub URLs 62 | 63 | - tag 64 | 65 | A specific version tagged and published as tag. See "npm-dist-tag". 66 | 67 | - path/path/path 68 | 69 | use local folder for dependency. 70 | 71 | 72 | 73 | # npm update 74 | 75 | npm sürümleri bazen # gibi dinamik sürümler kullanabiliyor. bu sebeple bunların update kontrolü için bu komut çalıştırılmaktadır. 76 | 77 | 78 | 79 | # "main" inside package.json 80 | the file which is exported when the library is importing anywhere. 81 | 82 | example: "main":"app.js" 83 | 84 | # npm install 85 | çalıştırıldığı dizindeki package.json dosyasını okur ve dependencies ve devDependencies içindeki tüm projeleri internetten çalıştırıldığı dizinin /node_modules dizininin altına yükler. devDependencies paketleri build sırasında output/target paketi içerisinde bulundurulmayan paketleri içermektedir. 86 | 87 | # npm install -g module1 88 | -g parametresi module1'i global paket olarak sisteme ekliyor. yani artık sadece projenin bulunduğu dizinden değil tüm dizinlerden çağrılabilir durumda oluyor. 89 | 90 | # npm list 91 | çalıştığı dizinde node_modules altındaki modüllerin listesini ağaç şeklinde listeler. -g parametresi ile çalıştırılırsa bulunduğu dizine bakmaz ve global kurulan node paketlerinin listesini ağaç şeklinde gösterir. 92 | 93 | # directory structure 94 | - NODE_INSTALLATION_PATH/bin -> path'e eklenmiş olması gereklidir. burada global kullanılan node paketlerinin executable dosyalarının kısayolları mevcut. "npm" node ile çalışan bir modül olduğundan burada (path'te) her zaman npm kısayolu bulunur. 95 | 96 | - NODE_INSTALLATION_PATH/lib/node_modules/module1 --> global kurulan npm paketleri buradadır. module'in kendi dependency'leri "NODE_INSTALLATION_PATH/lib/node_modules/module1/node_modules" altındadır. npm projesi de buranın içindedir. 97 | 98 | - NODE_INSTALLATION_PATH/include/node --> node'un kendi sistem dosyaları buradadır. node'un executable dosyasının kısayolu "bin" dizinindedir. 99 | 100 | - NODE_INSTALLATION_PATH/share --> manual/help gibi dosyaları barındırır. 101 | 102 | - $HOME/.npm --> internetten indirilen tüm repository yedekleri buradadır. Maven'ın ".m2" dosyası ile aynı mantıkta çalışmaktadır. 103 | 104 | # npm link module1 105 | bir uygulamamız ve bir de ondan bağımsız module1 isminde paket geliştiriliyor olalım. uygulamamız module1'e depend olsun. module1'de değişiklik olduğunda bu paketi repoya atıp, daha sonra uygulamamızdan npm install çalıştırmamız gerekecek. bunu sürekli yapmamak için link komutu kullanılabilir. module1 dizini içerisinde "npm link" komutunu çalıştırırız. daha sonra uygulamamızın root dizinine gidip "npm link module1" komutunu çalıştırırız. artık bizim proje module1 dizinini direk görüyor olur. her değişiklik anında görülmüş olur. npm link çok basit bir taktikte kısayol atarak bu işi çözüyor. 106 | 107 | npm link işleminin geri alınması için, modüle olan paketin dizine gidip "npm unlink" ve daha sonra uygulamamızın dizinine gidip "npm unlink module" komutunu çalıştırmamı gerekmektedir. 108 | 109 | # scripts 110 | komut listesi barındırıyor. isteğe bağlı komutlar ve default komutlar mevcut. örneğin: 111 | 112 | ```json 113 | "scripts": { 114 | 115 | "start": "node node_modules/react-native/local-cli/cli.js start", 116 | 117 | "xxx": "node node_modules/react-native/local-cli/cli.js start" 118 | 119 | }, 120 | ``` 121 | 122 | yazarsak; 123 | 124 | - xxx isimli komut için, şu komutu "npm run-script xxx" çalıştırabiliriz. 125 | 126 | - start'a yazdığımız komutu "npm start" ile çağırabiliriz. "start" script'i, npm'in birçok standart komutlarından sadece bir tanesidir. standart olduğu için "run-script" ile çağrılmamaktadır. custom script ismi (standart olmayan isim) kullandığımızda run-script ile çağırmamız şart. 127 | 128 | "start" komutu; "prestart", "start" ve "poststart" komutlarını (eğer package.json'da yazılmış ise) sırası ile çalıştırmaktadır. 129 | 130 | # package-lock.json 131 | 132 | bu dosya package.json ile aynı dizinde otomatik npm tarafından oluşturulur. burada node_modules altındaki dizinlerin bir ağaç yapısı şeklinde metadata'ları ile bulundurur. bunun birkaç sebebi var: 133 | 134 | - npm tekrar install yaptığı zaman daha hızlı şekilde kontrol yapması sağlanır (tekrar tüm dizinler okunup metadata'larına bakmaya gerek kalmaz.). 135 | 136 | - bu dosya source code repository'de history'si durur ve eski paketler history'den kontrol edilebilir. 137 | 138 | - bir geliştirici yanlış paketleri kurmuş ve commit etmiş ise buradan farklı olan kısımlar incelenip neden farklı paket kurduğu incelenmeye başlanabilir. 139 | 140 | # npm-shrinkwrap.json 141 | 142 | manuel oluşturulan bir dosyadır. package-json ile aynı yerde olmalıdır. package.json içindeki dependency'lerin bazıları dinamik (1.0.* gibi) sürümlere sahiptir. dolayısı ile herkesin makinesinde npm paketleri olabilir. işte bunun için npm-shrinkwrap.json dosyası çözüm olarak sunulmuştur. bu dosyada yazan paketler spesifik sürümlerde tutulmaktadır. böylece birileri bu dosyayı update etmediği sürece npm install komutu herkeste aynı sürümü kuracaktır. bu dosya yerine direk package.json içerisindeki sürümlerle de oynanabilir fakat bu sadece bir alternatiftir. örneğin MomentJS paketini sürekli yükselmesinde sakınca görülmez fakat geliştirme yapılan süreçte bunu fix tutmak isteyebilirsiniz. bunu yorum satırı olarak yazacağımıza npm-shrinkwrap.json dosyasından yararlanırız ve package.json'da MomentJS "latest" tag'i ile kalmaya devam edecektir. 143 | 144 | "npm shrinkwrap" komutu ile hızlıca package-lock.json dosyasından npm-shrinkwrap.json dosyası oluşturmaktadır. 145 | 146 | # --no-shrinkwrap 147 | 148 | npm install işleminin yanına bu parametre eklendiğinde install işlemini npm-shrinkwrap.json ve package-lock.json dosyalarını ignore ederek yapıyor. 149 | 150 | # --save (or -S) 151 | 152 | npm install --save jquery 153 | 154 | bu parametre npm 5 öncesi versiyonlarda package.json'a dependency'yi eklemek için yapılıyordu. npm 5 ile birlikte sadece install komutu zaten package.json'a ekleme yapıyor. 155 | 156 | # npx 157 | npm'in güncel sürümlerinde beraber yüklü gelen, npm'i wrap eden yeni bir komut satırı uygulaması, aynı zamanda node modülüdür. npx, npm'e göre daha az komut yazarak işlem yapabilmemizi sağlar. örneğin: 158 | 159 | > npx install packageX 160 | 161 | packageX'i kurduğu gibi packageX'i execute eder. genelde kurulan paket, kurulduktan sonra kullanıcı tarafından çağrıldığı için böyle hazır bir yola gidilmiş. 162 | 163 | bunun gibi birçok özelliği vardır. 164 | 165 | # scoped packages 166 | "@sample-scope/sample-package" şeklinde dağıtılan paketler scope'u açan kullanıcılar tarafından yönetiliyor. tamamen gruplama amaçlı yapılmış bir şeydir. herkes dilediği gibi istediği scope'a paket atamıyor. yetkilendirmeler söz konusu. 167 | -------------------------------------------------------------------------------- /tutorials/javascript_webpack.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # JAVASCRIPT WEBPACK 5 | ############################ 6 | 7 | ############################ 8 | 9 | # Webpack 10 | Birçok JS, CSS, SASS, HTML gibi birçok web teknolojisi dosyasını birleştirmek için kullanılan komut satırı uygulaması, node module uygulamasıdır. 11 | 12 | projenin root'undaki webpack.config.js dosyası örneği: 13 | 14 | ```js 15 | const path = require('path'); 16 | const HtmlWebpackPlugin = require('html-webpack-plugin'); // installed via npm 17 | const webpack = require('webpack'); // to access built-in plugins 18 | 19 | module.exports = { 20 | // entry point 21 | // bu dosyadaki tüm import'lar birleştirilip tek bir dosya haline getirilecek. 22 | // default değeri: ./src/index.js 23 | entry: './path/to/my/entry/file.js' 24 | 25 | output: { 26 | path: path.resolve(__dirname, 'dist'), // bu sadece current dizini almak için kullanılan bir fonksiyon. "current-dizin/dist" dizinin altında file bundle file oluşturulacak. 27 | filename: 'my-first-webpack.bundle.js' 28 | } 29 | 30 | // loaders 31 | // Webpack JSON ve JS haricinde hiçbir formattan anlamaz. 32 | // diğer tipteki tüm dosyaları ancak loader'lar aracılığı ile import edebiliriz. 33 | // aşağıdaki örnek: txt dosyası require() yada import edilecek ise "raw-loader" ID'li loader ile import edilmeli anlamına gelmektedir. 34 | module: { 35 | rules: [ 36 | { test: /\.txt$/, use: 'raw-loader' } 37 | ] 38 | } 39 | 40 | // plugins 41 | // plugin'lerin loader'lardan daha fazla yetenekleri vardır. 42 | // aşağıdaki örnek plugin, oluşturulan bundle JS dosyasına link eden bir HTML dosyası oluşturuyor. 43 | plugins: [ 44 | new HtmlWebpackPlugin({template: './src/index.html'}) 45 | ] 46 | }; 47 | ``` 48 | # webpack-dev-server 49 | Webpack projesi altında olan fakat farklı bir node modülüdür ve ayrı repo'da geliştirilmektedir. 50 | 51 | package.json dosyamıza nasıl run edeceğimizi girelim: 52 | 53 | ```json 54 | "scripts": { 55 | "start-dev-server": "webpack-dev-server" 56 | } 57 | ``` 58 | 59 | webpack.config.js dosyamıza ayarlarımızı ekleyelim: 60 | 61 | ```js 62 | var path = require('path'); 63 | 64 | module.exports = { 65 | devServer: { 66 | contentBase: path.join(__dirname, 'dist'), // hangi dizinin sunucu tarafında dışarıya açılacağı. burada genelde target/dist/output isimlerini görebiliriz. 67 | compress: true, // kodun minify edilip edilmeyeceği 68 | port: 9000, // sunucunun dışarı açılacağı port 69 | after: function(app, server, compiler) { 70 | // do anything here... 71 | // this is event of server started. 72 | } 73 | } 74 | }; 75 | ``` 76 | 77 | Yukarıdakileri configleri dosyalara girmeseydik, sadece komut satırından da bu ayarları parametre geçip sunucuyu başlatabilirdik: 78 | 79 | ```sh 80 | node "./node_modules/webpack-dev-server/bin/webpack-dev-server.js" --entry "/entry/file" --output-path "/output/path" 81 | ## yada 82 | ./node_modules/.bin/webpack-dev-server.cmd --entry "/entry/file" --output-path "/output/path" 83 | ``` 84 | 85 | # Babel-loader 86 | Babel kodu convert ediyor. Webpack, Babel'in çevirdiği kodlardan bundle yaratması lazım. bu sebeple Babel-loader paketinin node modüllerde olması ve config'lerden aktif edilmesi şarttır. 87 | 88 | # hot module replacement (or HMR) 89 | Webpack runtime'da "module" isminde bir static objeyi variable olarak inject ediyor. import etmeden bu objeyi kullanabiliyoruz. hot reload olduğunda, instance'larımızı yeniden yaratabileceğimiz callback metotlarımızı tanımlayabiliyoruz. örnek: 90 | 91 | ```js 92 | var requestHandler = require("./handler.js"); 93 | var server = require("http").createServer(); 94 | server.on("request", requestHandler); 95 | server.listen(8080); 96 | 97 | // check if HMR is enabled 98 | if(module.hot) { 99 | // handler.js dosyası (dependency) update olursa aşağıdaki fonksiyon çalışacak. 100 | module.hot.accept("./handler.js", function() { 101 | 102 | // requestHandler instance'ımızı tekrardan yaratıyoruz. 103 | server.removeListener("request", requestHandler); 104 | requestHandler = require("./handler.js"); 105 | server.on("request", requestHandler); 106 | }); 107 | } 108 | ``` 109 | 110 | # sourcemap 111 | Web standartlarında olan teknolojidir. sourcemap; minify edilmiş yada JS sürümleri değiştirilmiş Javascript kodlarını ilk haline referans edebilmemizi sağlayan dosyalardır. örnek: 112 | 113 | optimize edilmiş dosyamız: 114 | 115 | ```js 116 | //# sourceMappingURL=/path/to/script.js.map 117 | Person p = new Person();var a=9;var b=1; 118 | ``` 119 | 120 | Tepesinde sourcemap'e referans var. yada dosyayı yapan "Ajax get" isteğine dönen response'un header'ında şunu koymamız gereklidir: 121 | 122 | ``` 123 | X-SourceMap: /path/to/script.js.map 124 | ``` 125 | 126 | örnek sourcemap dosyası: 127 | 128 | ```js 129 | { 130 | version: 3, // version of sourcemap format 131 | file: "script.js.map", // name of this file 132 | sources: [ // orijinal source files 133 | "app.js", 134 | "content.js", 135 | "widget.js" 136 | ], 137 | sourceRoot: "/", // optional. root path of "sources" 138 | names: ["slideUp", "slideDown", "save"], // minify edilen JS dosyasındaki symboller(symbol konusu başka başlıkta anlatılıyor). kaynak: (source-id: 238) "Proposed Format" başlığında "Line 7" ile başlayan satır. 139 | mappings: "AAA0B,kBAAhBA,QAAOC,SACjBD,OAAOC,OAAO..." // base64 of orijinal code 140 | } 141 | ``` 142 | 143 | UglifyJS sourcemap yaratmak için geliştirilen bir programdır. 144 | 145 | Webpack'deki mode:"development" seçeneği sourcemap dosyalarının oluşturulmasına yarıyor. 146 | 147 | gerçek bir örnek: 148 | 149 | bu dosya: 150 | 151 | ```js 152 | import { createBrowserHistory } from 'history'; 153 | 154 | const history = createBrowserHistory(); 155 | 156 | export default history; 157 | ``` 158 | 159 | bu halde minified olarak sunuluyor: 160 | 161 | ```js 162 | __webpack_require__.r(__webpack_exports__); 163 | /* harmony import */ var history__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! history */ "./node_modules/history/index.js"); 164 | /* harmony import */ var history__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(history__WEBPACK_IMPORTED_MODULE_0__); 165 | var history = Object(history__WEBPACK_IMPORTED_MODULE_0__["createBrowserHistory"])(); 166 | /* harmony default export */ __webpack_exports__["default"] = (history);//# sourceURL=[module] 167 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9hcHAvdXRpbHMvaGlzdG9yeS5qcz8wZGE4Il0sIm5hbWVzIjpbImhpc3RvcnkiLCJjcmVhdGVCcm93c2VySGlzdG9yeSJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQSxJQUFNQSxPQUFPLEdBQUdDLG9FQUFvQixFQUFwQztBQUNlRCxzRUFBZiIsImZpbGUiOiIuL2FwcC91dGlscy9oaXN0b3J5LmpzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY3JlYXRlQnJvd3Nlckhpc3RvcnkgfSBmcm9tICdoaXN0b3J5JztcbmNvbnN0IGhpc3RvcnkgPSBjcmVhdGVCcm93c2VySGlzdG9yeSgpO1xuZXhwb3J0IGRlZmF1bHQgaGlzdG9yeTtcbiJdLCJzb3VyY2VSb290IjoiIn0= 168 | //# sourceURL=webpack-internal:///./app/utils/history.js 169 | ``` 170 | 171 | en alttan ikinci satırda bir self-contained sourcemap dosyası var. o satırı, base64'ten encode edersek elimize şu geçer: 172 | 173 | ```json 174 | { 175 | "version": 3, 176 | "sources": [ 177 | "webpack:///./app/utils/history.js?0da8" 178 | ], 179 | "names": [ 180 | "history", 181 | "createBrowserHistory" 182 | ], 183 | "mappings": "AAAA;AAAA;AAAA;AAAA;AACA,IAAMA,OAAO,GAAGC,oEAAoB,EAApC;AACeD,sEAAf", 184 | "file": "./app/utils/history.js.js", 185 | "sourcesContent": [ 186 | "import { createBrowserHistory } from 'history';\nconst history = createBrowserHistory();\nexport default history;\n" 187 | ], 188 | "sourceRoot": "" 189 | } 190 | ``` 191 | 192 | dikkat edersek; "sourcesContent", ilk dosyamızın her satırını tek tek içeriyor. 193 | 194 | # debugger source list 195 | Firefox -> developer tools --> debugger -> sources --> sol taraftaki liste şu şekildedir: 196 | 197 | - main thread 198 | - localhost:8080 199 | - main.js 200 | - utils.js 201 | - libs 202 | - JQuery.js 203 | - backbone.js 204 | - www.Google.com 205 | - Google-adds.js 206 | - Google-utils.js 207 | - adblockerFirefoxAddOn 208 | - page.js 209 | - WebWorker 210 | - worker.js 211 | 212 | Her eklenti, her thread ve her "origin" için dosyalar ayrı ayrı gruplandırılmıştır. 213 | 214 | Benzer bir liste Chromium tabanlı tarayıcılarda da vardır. 215 | -------------------------------------------------------------------------------- /tutorials/jenkins.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # JENKINS 5 | ############################ 6 | 7 | ############################ 8 | 9 | # Jenkins 10 | 11 | en üst seviyede "item"'lar tanımlarız. item'ların çeşitleri: 12 | 13 | - project (or old-name:job): tanımlamalarımızı yürütecek olan süreçtir. 14 | 15 | - pipeline: build sürecinin her defasında dinamik olarak build edildiğinde tanımlanabilen bir süreçtir. build'a başlamadan "Jenkinsfile" isimli dosyayı okur ve içindekilere göre build yapar. 16 | 17 | - folder: diğer item'ları bir dizinde toplayabilmemizi sağlar. 18 | 19 | - external job: Jenkins'den bağımsız process'lerin takibi için yapılmış özel bir durum 20 | 21 | - multibranch pipeline: bu bir plug-in'in getirdiği item'dır. default gelmez. çekilen kod'un her branch'i için ayrı ayrı Jenkinsfile'ı çalıştırır. 22 | 23 | Jenkins içinde bazı eklentiler varsayılan olarak yüklü gelir. 24 | 25 | Her item "build" edilir. 26 | 27 | Yeni bir item oluşturduğumuzda; bizden item'ın çeşidini seçmemiz istenir. buradaki çeşitler default mevcuttur bazıları ise Jenkins'e eklediğimiz plugin'ler tarafından sağlanır. Bazı item çeşitlerinin isminde Project keyword'ü yer alır. bu tamamen ismin bir parçasıdır. terminolojide project denilen bir kelime yoktur. 28 | 29 | Bir item'ı seçtiğimizde ise yeni bir sayfada birçok ayar istenir. bu ayarlar gruplandırılmıştır. komple bir grup bir Jenkins eklentisi tarafından sağlanıyor olabilir. fakat default sunulan gruplara da eklentiler müdahale edebilir. eklentiler default grupların içine yeni form alanları ekleyebilir. bir form alanının sağ tarafında "?" simgesi vardır. ona tıkladığımızda o alan için kısa bilgi çıkar ve hangi eklentinin bu alanı buraya koyduğunu yazar. Eğer ? simgesi yoksa o alan default Jenkins ile geliyordur. 30 | 31 | Hangi grupların ve hangi form alanlarının gösterileceği, item'ın çeşidine göre değişir. item oluşturulduktan sonra item'ın çeşidini değiştiremeyiz. 32 | 33 | # Agent 34 | 35 | Jenkins master'a, agent'lar bağlanır ve bu agent'larda task'ları koşabiliriz. 36 | 37 | # node 38 | 39 | master ve agent'ların her birine verilen genel isimdir. bir node, agent yada master olabilir. 40 | 41 | # Stage 42 | 43 | pipeline (Türkçe kelime anlamı: boru hattı) içindeki her iş grubuna verilen isimdir. örnek pipeline dosyamız ve içindeki stage'ler: 44 | 45 | ```js 46 | pipeline { 47 | 48 | agent any 49 | 50 | stages { 51 | 52 | stage('Build') { 53 | 54 | steps { 55 | 56 | echo "build started" 57 | 58 | sh 'cd build_dir' 59 | 60 | } 61 | 62 | } 63 | 64 | stage('Test') { 65 | 66 | steps { 67 | 68 | sh 'javac source_dir' 69 | 70 | } 71 | 72 | } 73 | 74 | stage('Deploy') { 75 | 76 | steps { 77 | 78 | sh 'docker push *file.jar' 79 | 80 | } 81 | 82 | } 83 | 84 | } 85 | 86 | } 87 | ``` 88 | 89 | # step 90 | 91 | pipeline stage'sinin içindeki adımların her biri. 92 | 93 | # Upstream 94 | Upstream: akış yönünün tersine. 95 | 96 | bir item diğer bir item'ı tetikleyebilir. tetikleyen item'a, tetiklenen item'ın upstream'i denir. tabi tetiklenen projede downstream oluyor. 97 | 98 | # view 99 | 100 | tüm item'ların listelendiği ana sayfada item'lar gruplandırılabiliyor. her gruba "view" adı veriliyor. 101 | 102 | # workspace directory 103 | 104 | her item için bir dizin vardır. her build aynı dizin üzerinde işlem yapar. eğer "workspace temizleme" aktif edilmezse eski build'deki dosyalar sürekli orada kalır. 105 | 106 | # build directory 107 | 108 | her build bittiğinde metadata'larını (log, başlangıç ve bitiş saat bilgisi, istatistik bilgisi ve artifact'ları) build dizini içine kopyalar. 109 | 110 | # JENKINS_HOME 111 | 112 | - config.xml 113 | 114 | - plugins/ 115 | 116 | - workspace/ 117 | 118 | - [itemName] 119 | 120 | - jobs/ 121 | 122 | - [itemName] 123 | 124 | - config.xml (job configuration file) 125 | 126 | - latest (symbolic link to the last successful build) 127 | 128 | - builds/ 129 | 130 | - [buildId]/ 131 | 132 | Bazı Jenkins sürümlerinde workspace dizini her JENKINS_HOME/jobs/[itemName]/'in altındadır. 133 | 134 | # Pipeline types 135 | 136 | iki çeşit Pipeline var: 137 | 138 | - Scripted: Groovy dili ile yazılmış dosyadan okuyan pipeline'lardır. 139 | 140 | - declarative: özel üst seviyeli bir dil (arkaplanda Groovy kullanıyor). Scripted'a göre daha üst seviyeli olduğundan, Scripted'a göre daha kolay fakat daha az özellik sunuyor. 141 | 142 | # Jenkins'i Docker ile kurup job içinde Docker kullanma 143 | Docker içerisinde Docker kullanma konusuna girmekteyiz. bunun için 3 yöntem var: 144 | 145 | - container'ımız dışındaki Dockerd'ye bağlanmamız gerekli. bunun için container'ımızı açarken bağlama işleminin bu şekilde yapabiliriz: 146 | 147 | > docker container run -d -p 8080:8080 -v /var/run/docker.sock:/var/run/docker.sock jenkins-docker 148 | 149 | Jenkins-Docker içerisinde Docker client'ın kurulu olması gerekli. artık Jenkins job'larımızda, Dockerd'ye komut yollayabiliriz. 150 | 151 | "/var/run/docker.sock" bir UNIX socket dosyasıdır. Dockerd sürekli buradan dinleme yapar ve buradan gelen komutları kabul eder. 152 | 153 | Bu madde tavsiye edilmiyor, çünkü sıkıntı yaratıyor. kaynak: (source-id: 48) "The solution" başlığı. 154 | 155 | - Docker içerisinde Docker'ı kurarız. 156 | 157 | buna genelde __DIND (or Docker in Docker)__ deniliyor. 158 | 159 | bunu yapan hazır bir Docker image'si mevcut: (source-id: 49) 160 | 161 | Bu madde tavsiye edilmiyor, çünkü sıkıntı yaratıyor. kaynak: (source-id: 48) 162 | 163 | - Docker client ile container dışında olan bir Dockerd'ye istek atarız. bu madde en çok tavsiye edilen çözümdür. kaynak: (source-id: 48) Tüm makaledeki en son satır. -------------------------------------------------------------------------------- /tutorials/network_dns.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # NETWORK DNS 5 | ############################ 6 | 7 | ############################ 8 | 9 | 10 | # DNS (or Domain Name System) 11 | internet adres resolving sistemini temsil eden genel bir terimdir. 12 | 13 | __DNS Server (or Name Server)__ ise IP'leri resolving yapmakla yükümlü yazılımdır. Bazen __Domain Name Server__ denir fakat yanlış bir kullanımdır. 14 | 15 | # International Corporation for Assigned Names and Numbers (or ICANN) 16 | 2019 yılı itibariyle hala en yetkili kuruluştur. Amerika'ya bağlıdır. __registrar (or kaydedici)__ firmalar (örnek: Godaddy), ICANN'dan lisans almak zorundalar. 17 | 18 | # IANA (or Internet Assigned Numbers Authority) 19 | ICANN için gerekli bazı teknik konuları tamamlayan kuruluştur. 20 | 21 | # RIR (yad Regional Internet Registry) 22 | ICANN ve IANA'nın altında dünyanın 5 farklı bölgesinde yetkilendirilmiş kuruluşlar vardır. Bu kuruluşlar kendi bölgelerinden sorumludur ve devlete bağlı kuruluş değillerdir. 23 | 24 | - AfriNIC 25 | 26 | African Region Internet Registry: Afrika 27 | 28 | - APNIC 29 | 30 | Asia Pacific Network Information Centre: Asya ve Pasifik 31 | 32 | - ARIN 33 | 34 | American Registry for Internet Numbers: Kuzey Amerika 35 | 36 | - LACNIC 37 | 38 | Latin America and Caribbean Internet Addresses Registry: Latin Amerika ve Karayipler bölgesi 39 | 40 | - RIPE NCC 41 | 42 | Reseaux IP Europeens Network Coordination Centre: Avrupa bölgesi. 43 | 44 | RIR alanları yukarıda yazıldığı kadar keskin çizgilerle ayrılmaz. Örneğin, ARIN bölgesi esas olarak Kuzey Amerika olmakla beraber Güney Amerika ve Afrika'ya da servis verir. RIPE bölgesi esas olarak avrupa olmakla beraber Orta Doğu ve Orta Asya içlerine kadar servis vermektedir. Türkiye, RIPE NCC bölgesindedir. RIPE NCC'nin merkezi Hollanda'dadır. 45 | 46 | # LIR (or Local Internet Registry) 47 | kullanıcıya IP veren kuruluşlardır. ISP (or Internet Sevice Provider) (Türktelekom, Superonline...)'lere denk gelir. Yasal anlamda şirketi olan herkes bu görevi alabilir. Türkiye'de u servisi sağlayan 100'den fazla kuruluş vardır. 48 | 49 | # Web tarayıcının DNS sorgusu 50 | sırası ile: 51 | - web browser DNS cache 52 | - OS DNS cache 53 | - "hosts" file 54 | - __public DNS (or non-authoritative DNS server or recursive DNS server or recursive DNS resolver)__ 55 | 56 | örnek Google DNS 8.8.8.8, 8.8.4.4(Google ikinci yedek IP), Cloudflare 1.1.1.1 gibi... Eğer public DNS tanımlamazsak ISP bizim yerimize default değeri atar. 57 | 58 | public DNS kendi içinde bilgiyi bulamaz ise, kendi gidip root DNS server'a sorar. 59 | 60 | # hierarchy of DNS system 61 | 62 | # 1- root DNS servers 63 | en üstte olan ve en yetkili sunuculardır. 64 | 65 | DNS sunucuları tüm domain bilgilerini saklayamaz. local cache'inde yok ise, ilk önce root server'lara sorar. root server bu bilgiyi lokalinde bulundurmuyorsa 2inci seviye root server'ın adresini sorgulayan client'a döndürür. 66 | 67 | root server'lar dünyada 12 adettir (yıl 2019). bunlar ICANN tarafından belirlenmiştir. fakat sadece 1 tanesi ICANN kuruluşa direk bağlı bir sunucudur. bu sunucuya __ICANN Managed Root Server (or IMRS)__ deniyor. diğerlerinin ICANN'a bağlı olmamasının sebebi, merkezi yönetimden kaçınmaktır. 68 | 69 | ICANN'ın resmi sayfası olan www.dns.icann.org sitesinde root-servers.org'a referans verilmiştir. buradan 12 server'ı görebiliriz. 70 | 71 | 12 adet Root DNS server var, fakat bunlarda farklı instance'larla kendilerini çoğaltmışlardır. Yine bu instance'larda root-servers.org sayfasında görülebilir. 72 | 73 | 2inci seviye DNS sunucu bilgileri tutar. 74 | 75 | # 2- top-level DNS server 76 | 2inci seviye DNS server'lardır. her "top-level DNS server" ".com", ".org" gibi sorumluluk alanları vardır. 77 | 78 | # 3- authoritative DNS server 79 | 3üncü seviye DNS server'lardır. 80 | 81 | # 4- 82 | DNS sisteminde 4üncü seviye yoktur. Bu seviyeye istersek public DNS'lerimizi koyabiliriz. 83 | 84 | # whois server 85 | registrar'a yeni bir domain eklendiğinde, registrar bu bilgiyi o domain'in uzantısının sorumlusu olan "whois server"'a yollar. örneğin .com ve .Net alan isimleri için verisign şirketinin whois sunucusu merkezi sunucudur. daha sonra bu bilgi diğer üçüncü parti whois server'lar tarafından klonlanır. 86 | 87 | Dolayısı ile; root server'lar dahi .com ve .Net için gerekli tüm domain'leri lokallerinde tutmazlar. 88 | 89 | Verisign firması ICANN'a bağlıdır ve ICANN tarafından yetkilendirilmiştir. 90 | 91 | ICANN'dan her firma Godaddy gibi kolayca yetki alamaz. fakat Godaddy'ye kolayca aracılık edebilir, yani Godaddy'nin bayisi olabilir. 92 | 93 | # hostname vs domain name 94 | domain name bir bilgisayara DNS sunucusu tarafından atanmış string'dir. oysa hostname local bir network'te her makinanın kendisini dışarıya tanıttığı isimdir. network içinde hostname kullanılırken, dışarıya gidişlerde domain kullanılır. dışarıdaki bir yere giderken, oradaki network'teki bir alt makineye erişmek istediğimizde hostname.domainname.com gibi bir adresten yararlanılır. hostname ve domain name aynı görevi görür. www internet tarayıcıları için gerekli varsayılan makinanın hostname'idir. 95 | 96 | # subdomain 97 | mail.Google.com, map.Google.com'deki mail ve map birer subdomain'dir. ayrı IP'leri vardır. fakat istenirse aynı IP'ye de yönlendirilebilir. 98 | 99 | # domain'i hosting'e bağlama 100 | wix.com bizim sayfamızı barındırıyor (sunucu hosting firmamız) olsun. godaddy.com'dan da domain'imizi almış olalım. 101 | 102 | - wix.com'a domain-name'imizi bildiriyoruz. 103 | - wix.com bize wix'in kendi DNS'lerini veriyor. bunlar genelde ns1.wix-dns.com tarzında URL'ler oluyor. 104 | - Godaddy'de o domain'e ait nameserver'larımızı tanımlıyoruz. bunun için Godaddy'ye login oluyor, ilgili domain'imizi seçiyor, ayarlarına giriyor ve nameserver alanlarımızı dolduruyoruz. burada birden fazla nameserver olabilir. çünkü yedek nameserver olabiliyor. 105 | 106 | Artık domain'imize istek yapıldığında, Godaddy DNS sorgusunu yapanı ns1.wix-dns.com'a yönlendiriyor. ns1.wix-dns.com gelen sorguyu görüyor ve onu sunucu bilgisayarın IP'sini dönüyor. 107 | 108 | Bu örnekte Godaddy'ye verdiğimiz DNS sunucuları bizim kendi kişisel sunucularımız olabilir. Genelde büyük firmalar kendi DNS sunucularını kullanıyor. 109 | 110 | # fully qualified domain name (or FQDN) 111 | hostname + domain name birarada olduğunda verilen isimdir. örnek: tr.wikipedia.com, www.wikipedia.com... 112 | 113 | # top-level domain (or TLD) 114 | .com, .org, tr gibi terimlere verilen isimdir. TLD'nin çeşitleri vardır: 115 | 116 | - # country code top-level domain (ccTLD) 117 | .tr, .fr, .de, .us gibi ülke bazlı gruplama için gerekli domain bilgisini ifade eder. 118 | 119 | - # generic top-level domains (or gTLD) 120 | .com, .org gibi kurumların tipini belli eden domain ifadeleridir. 121 | 122 | # domain levels 123 | example: mail.Google.com 124 | 125 | - 1st level domain (or first-level domain) 126 | 127 | com 128 | 129 | - 2nd level domain (or second-Level domain) 130 | 131 | Google 132 | 133 | - 3rd level domain (or third-level domain) 134 | 135 | mail 136 | 137 | # Ters DNS Çözümlemesi (or Reverse DNS lookup or reverse DNS resolution or rDNS) 138 | IP'den DNS bulma işlemidir. 139 | 140 | • • • • • • • • • • • • • • • • • • • • • • • • 141 | 142 | • • • • • • • • • • • • • • • • • • • • • • • • 143 | 144 | • • • • • • • • • • • • • • • • • • • • • • • • 145 | 146 | # DNS over TLS (DoT) vs DNS over HTTPS (DoH) 147 | Standart DNS client'lar, DoT ve DoH sunucularına istek yapamazlar. çünkü farklı protokollerdir. 148 | 149 | standart DNS'te isteğin çoğu açık gider/gelir. oysa DoT ve DoH 'ta istek tamamen şifrelenmiştir. 150 | 151 | DoT, TCP soket bağlantısı açıp, o soketi üzerinden TLS ile DNS sorgusu atar. DoH ise HTTP protokolünden yararlanarak DNS isteği atar. 152 | 153 | Bu iki ptotokolün amacı ISP'lerden gizlenmek değildir. çünkü ISP, DNS sorgusundan sonra, gideceğimiz IP adresini zaten görecektir. buradaki amaç; 154 | 155 | - man-in-the-middle (or MITM) attack'ı önlemek 156 | - DNS sorgusu yapılıp, cevabı şifreli bir bağlantıda kullanılacak ise güvenliği sağlamış oluruz 157 | - ISP'lerin DNS sunucularındaki yaptığı engellemeleri ortadan kaldırmak 158 | 159 | • • • • • • • • • • • • • • • • • • • • • • • • 160 | 161 | • • • • • • • • • • • • • • • • • • • • • • • • 162 | 163 | • • • • • • • • • • • • • • • • • • • • • • • • -------------------------------------------------------------------------------- /tutorials/pattern_types.md: -------------------------------------------------------------------------------- 1 | 2 | ############################ 3 | 4 | ############################ 5 | # PATTERN TYPES 6 | ############################ 7 | 8 | ############################ 9 | 10 | # pattern types 11 | - Creational Pattern 12 | 13 | bir veya birden fazla objenin init edilmesi ile ilgili konuları ele alır. 14 | 15 | - structural pattern 16 | 17 | Sınıfların birbirleri arasındaki ilişki yapılarını ve birbirlerini nasıl kullandıkları ile ilgili konuları ele alır. 18 | 19 | - Behavioral pattern 20 | 21 | Objelerin birbiri ile olan ilişkilerinden ziyade, birbirleri arasında haberleşmelerini veya birbirlerini ne zaman kullanmaları gerektiği (rolleri/görevleri) konuları ele alır. 22 | 23 | - Concurrency pattern 24 | 25 | Multi-thread uygulamalar için geliştirilen pattern'lerdir. 26 | 27 | - Architectural pattern 28 | 29 | Daha çok üst seviyeli (yani; sınıf değil, yazılımlar veya modüller seviyesinde) olan pattern'lerdir. 30 | 31 | - Database pattern 32 | 33 | - Anti-Pattern 34 | 35 | • • • • • • • • • • • • • • • • • • • • • • • • 36 | 37 | • • • • • • • • • • • • • • • • • • • • • • • • 38 | 39 | • • • • • • • • • • • • • • • • • • • • • • • • 40 | -------------------------------------------------------------------------------- /tutorials/security_random_numbers.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # SECURITY RANDOM NUMBERS 5 | ############################ 6 | 7 | ############################ 8 | 9 | # Rassal değişken (or Random variable) 10 | rastgele oluşturulan değişkendir. 11 | 12 | # sözde rastsal (or pseudo random number) 13 | bilgisayar ortamında rastgele değişken oluşturulamayacağından, sözde rastsal sayılar oluşturulabilmektedir. 14 | 15 | # pseudorandom number generator (or eng-kısaltma:PRNG or deterministic random bit generator or eng-kısaltma:DRBG) 16 | sözde rastsal sayı üretebilmek için kullanılan yazılımlardır. 17 | 18 | PRNG, initial value'ya bakar. Initial value aynı olursa sürekli aynı çıktıları üretir. 19 | 20 | bahsi geçen bu initial value'ya __seed (or tohum)__ denir. 21 | 22 | # tr:entropi (or eng:entropy) 23 | kelime anlamı: 24 | 25 | - Termodinami bilimindeki tanımı: termal enerjinin faydalı işe çevrilemeyen kısmı olarak tanımlar (yani verimli kullanılamayan kısmına/oranına denir). 26 | 27 | - İstatistik biliminde: measurement of how unpredictable something is (unpredictable olması birşeyin düzensizliği oluyor) 28 | 29 | # Hardware random number generator (or eng-kısaltma:HRNG or true random number generators) 30 | donanımlar aracılığı ile rastgele sayı üretilememektedir (yazılımda olduğu gibi). fakat donanımlar bazı sensörler ile çevreden bilgi alıp rastgele sayı üretmeye çalışabilirler. örneğin; ısı sensörü gibi. aslında burada da %100 rastgele sayı üretilmiş olmuyor. fakat önceden kestirilemeyen (unpredictability) sayı üretiliyor. 31 | 32 | bilgisayarlar rastgele sayı üretebilmek için, her cihazda olan aşağıdaki 2 referanstan yararlanır. Her donanımda olduklarından portable algoritmalar için tercih edilirler. 33 | - saat-tarih 34 | - CPU çalışmaya başladığından itibaren kaç cycle geçmiş gösteren __Clock Sequence__ 35 | 36 | # cryptographically secure pseudorandom number generator (or CSPRNG or cryptographic pseudorandom number generator or CPRNG) 37 | %100 olmasa da belli standartları destekleyen güçlü seviyede random sayı üreten kütüphaneler mevcut. bunlara verilen özel isimdir. örnekler: 38 | 39 | | Platform | CSPRNG | 40 | |----------------------------------------|-------------------------------------------------------| 41 | | PHP | mcrypt_create_iv, openssl_random_pseudo_bytes | 42 | | Java | java.security.SecureRandom | 43 | | Dot NET (C#, VB) | System.Security.Cryptography.RNGCryptoServiceProvider | 44 | | Ruby | SecureRandom | 45 | | Python | os.urandom | 46 | | Perl | Math::Random::Secure | 47 | | C/C++ (Microsoft Windows API) | CryptGenRandom | 48 | | Any language on GNU/Linux or Unix Read | from /dev/random or /dev/urandom | 49 | 50 | Not: java.security.SecureRandom sınıfının constructor'ı parametre olarak Provider alıyor. Her provider farklı kaynaklardan data çekmeye yarıyor. kaynak: (source-id: 466) title: "SecureRandom Number Generation Algorithms". 51 | 52 | Bu tablodaki listede bulunan algoritmalar ek olarak donanımlardan da yararlanmaktadır. CPRNG'ın donanımdan yararlanması zorunlu değildir. Donanımdan yararlanmayan CPRNG'lar da mevcut. Yukarıdaki listedeki kütüphaneler, donanımdan aldıkları rastgele verileri CPRNG'a initial değer olarak verirler ve çıktı üretirler. Yukarıdaki API'ler genelde OS'un sunduğu API'lerden yararlanır. OS'ların sunduğu API'ler, kaynaklardan (donanımlarda oluşan event'lerden) bilgi toplarlar. Fakat bu bilgilerin zamana oranla üretimi kısıtlıdır (entropi düşüktür). Dolayısı ile belli zaman diliminde belli sayıda rastgele data üretilebilir. Daha sık üretilmesi için özel cihazlara (HSM gibi) başvurulmalıdır. 53 | 54 | Her OS'ta aşağıdakilerin davranışları farklı olabilir. 55 | - "/dev/random" entropi düşükken, isteği bloklar (bekletir). ne zaman yeni data depolanır o zaman cevabı döndürür. 56 | - "/dev/urandom" ise, eğer entropi düşükse, eski data'ları kullanarak cevap döndürür. 57 | 58 | /dev/random, TCP'de TLS/SSL tarafından da kullanılmaktadır. kaynak: (source-id: 298) 1inci paragraf. 59 | 60 | # software based random number generators 61 | bazı yazılımlar entropi üretmektedirler. OS'ların default entropi üreten modüller (yazılımları) çok basittir. Özellikle GUI'siz bir ortamda kullanılması pek önerilmez. kaynak: (source-id: 298) "Entropy Shortages" başlığı. 1inci paragraf. 62 | 63 | Bu sebeple daha gelişmiş bazı yazılımlar kullanılır. Örnekler: 64 | - Haveged (özel isimdir. içerisinde "HAVAGE" isimli algoritmayı kullandığından "havaged" olarak isimlendirilmiştir. HAVAGE algoritması bunun kısaltmasından üretilmiştir: HArdware Volatile Entropy Gathering and Expansion). 65 | - EGD (or Entropy Gathering Daemon) 66 | 67 | # HAVAGE 68 | HAVAGE algoritmasında, OS'un event'leri ve external event'ler HAVAGE generator'u sürekli reseed etmektedir. kaynak: (source-id: 300) "HArdware Volatile Entropy Gathering and Expansion:generating unpredictable random number at user level", yazarlar:André Seznec, Nicolas Sendrier, başlık: "6 havage: combining entropy/uncertainty gathering and pseudo-random number generation". 2inci paragraf, son cümle. 69 | 70 | HAVAGE algoritması CPU'da kod işletiyor ve bu kodun CPU'daki state'ini sürekli inceleyip, bu state'lerden entropi üretiyor. kaynak: kaynak: (source-id: 298) "HAVEGE" başlığı, 1inci paragraf. 71 | 72 | # rastgele sayı üretimi hakkında 73 | 74 | - Teorik olarak; sadece, hiç input almadan rastgele sayı üretebilen bir platform ancak bize gerçekten rastgele sayı üretebilir. 75 | 76 | - işletim sistemleri klavye ve mouse gibi bazı kaynaklardan yararlanarak rastgele sayı veren API sunarlar. örneğin POSIX'lerde: /dev/random'dan yararlanılır. 77 | 78 | - random.org sitesi bir web servis üzerinden rastgele sayı servisi sağlıyor. bu servis hava durumundan yararlanıyor. 79 | -------------------------------------------------------------------------------- /tutorials/security_saml.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # SECURITY SAML 5 | ############################ 6 | 7 | ############################ 8 | 9 | # saml version history 10 | 11 | OASIS Standards: 12 | 13 | - SAML 1.0 - year 2002 14 | - SAML 1.1 - year 2003 - minor changes. 15 | - SAML 2.0 - year 2005 - incompatible with older versions. 16 | 17 | The Liberty Alliance contributed its Identity Federation Framework (ID-FF), a fork of OASIS: 18 | 19 | - ID-FF 1.1 - year 2003 20 | - ID-FF 1.2 - year 2003 (based on SAML 2.0. but they have critical changes and they are incompatible.) 21 | 22 | 23 | Although ID-FF 1.2 was contributed to OASIS as the basis of SAML 2.0, there are some important differences between SAML 2.0 and ID-FF 1.2. In particular, the two specifications, despite their common roots, are incompatible. 24 | 25 | # oath vs saml 26 | saml oauth'a alternatiftir. oauth gibi sadece mesaj formatı diil, akışlarında standartı belirlenmiştir. 27 | -------------------------------------------------------------------------------- /tutorials/security_uuid.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # SECURITY UUID 5 | ############################ 6 | 7 | ############################ 8 | 9 | # UUID (or Universally unique identifier or GUID Globally Unique IDentifier) 10 | 11 | - (source-id: 302)'da belirtilen standartlardır. her versiyon hakkında bilgi yine bu standart altında belirtilmiştir. bu standartta 5 adet version belirtilmiştir. versiyonlama, olgunluk olarak belirlenmemiştir, sadece 5 çeşit UUID vardır. bunlar aşağıdaki gibidir: 12 | 13 | - version 1 (Time Based) 14 | 15 | cihazdaki MAC adresi ve data-time (en ufak birimi nanosecond olacak şekilde) bilgisi ile UUID üretir. aynı bilgilerle aynı UUID tekrar üretilebileceğinden bazı durumlarda takip edilebilirliği sağlamak amaçlı bu kullanılmaktadır. 16 | 17 | mac adresi olmayan durumlarda (cihazlarda/platformlarda) rastgele sayı kullanılabileceği RFC standartlarında belirtilmiştir. 18 | 19 | - version 2 (DCE Security) 20 | 21 | - version 3 (Name Based) 22 | 23 | UUID oluşturmak için namespace(URL gibi) ve name'in MD5'i kullanılır. örnek kod: 24 | 25 | ```java 26 | String source = namespace + name; 27 | byte[] bytes = source.getBytes("UTF-8"); 28 | UUID uuid = UUID.nameUUIDFromBytes(bytes);// bizim için MD5 hash alıyor 29 | ``` 30 | 31 | - version 4 (Random) 32 | 33 | sistem random number generate ederken, önceden belirli data'lardan yararlanmaz. bu sebeple genelde bu tercih edilir. 34 | 35 | - version 5 (Name Based) 36 | 37 | Version 3 ile aynı. tek fark: MD5 değil, SHA-1 istiyor. 38 | 39 | - version 40 | 41 | most significant 4 bits of "time" block. 42 | 43 | - variant 44 | 45 | UUID'nin ilk 3 bitidir. 46 | 47 | UUID'nin layout'udur. hangi bitlerde, hangi bilginin yer aldığı standartıdır. 48 | 49 | RFC4122'de sadece bir varyant anlatılıyor. 50 | 51 | ("x" önemi olmayan bit anlamına geliyor) 52 | 53 | | bit-0 | bit-1 | bit-2 | explanation | 54 | |-------|-------|-------|--------------------------------------------------------| 55 | | 0 | x | x | Reserved, NCS backward compatibility | 56 | | 1 | 0 | x | RFC4122'de anlatılan formattır | 57 | | 1 | 1 | 0 | Reserved, Microsoft Corporation backward compatibility | 58 | | 1 | 1 | 1 | Reserved for future definition. | 59 | 60 | Leach-Salz (RFC4122 yazarlarının soyadları) UUID'nin 2'inci varyantının (digit olarak bakıldığında varyant değeri "1") takma adı olarak birçok makalede kullanılmaktadır. 61 | 62 | UUID ilk olarak NCS'de (or Apollo Network Computing System) kullanılıyordu. Daha sonra Microsoft'ta kullanıldı. Daha sonra RFC yayımlandı. Bu sebeple NCS ve Microsoft'un kendi layout'larına geriye uyumluluk için RFC'de yer verildi. 63 | 64 | Microsoft kendi dökümanlarında RFC yayımlanana kadar GUUID terimini kulanmıştır. Bu sebeple GUUID'nin Microsoft'un standardı olduğu yanılgısı vardır. Oysa ikisi aynıdır. Aşağıda belirttiğim istisna durum için ise hiçbir resmi yayım bulamadım. 65 | 66 | Ek not: Microsoft resmi sitesinde https://docs.microsoft.com/en-us/windows/win32/msi/guid şu 2 cümleyi yazmaktadır: 67 | - The valid format for a GUID is {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} where X is a hex digit (0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F). 68 | - Note that utilities such as GUIDGEN can generate GUIDs containing lowercase letters. These must all be changed to uppercase letters before the GUID can be used by the installer as a valid product code, package code, or component code 69 | 70 | Oysa bu 2 madde RFC'de yazan bilgiler ile çakışıyor. Çünkü versiyon ve variant kısmında her karakter olamaz. Ve büyük harfe çevirme zorunluluğu vardır. Buda Microsoft tarafında üretilen bir UUID'nin kendi sistemimizde parse edilememesine yol açabilir. Fakat bu döküman çok yüzeysel görünüyor, muhtemelende Microsoft tarafındaki kod implementasyonlarında RFC dikkate alınmıştır diye düşünebiliriz fakat burada bu konunun hataya sebep olduğu ve Microsoft'un RFC dışında farklı data ürettiği görülmektedir: (source-id: 478) Bu bug içerisinde Microsoft teknolojileri ile üretilmiş UUID'nin bir kütüphane tarafından parse edilemediği ve bu konunun çözülmediği görülmüştür. 71 | 72 | - Java code of version vs variant 73 | 74 | ```java 75 | UUID uuid = UUID.randomUUID(); 76 | int variant = uuid.variant(); 77 | int version = uuid.version(); 78 | ``` 79 | 80 | - Tekil bir stringdir. 128 bittir = 32 karakterdir = 16 byte'dir. 81 | 82 | - Alabildiği karakterler: 0-9 ve A,B,C,D,E,F (Aslında hex digit'i temsil ettiği için böyle) 83 | 84 | - UUID kümesi çok büyük olduğundan, aynı UUID'nin sadece aynı uygulama içinde veya farklı bir sistemdeki bağımsız uygulamada üretilmesi matematiksel olarak çok azdır. bu sebeple standart olarak kullanılır. 85 | 86 | version-4 UUI'den ortalama 5*(10^36) adet vardır. Bu da ortalama 85 sene boyunca, her saniye 1 milyar UUID üretilmesi durumunda %50 çakışma 1 kere olacağı oranı yaratmaktadır. 87 | 88 | - örnek kullanım alanlar: 89 | - MAC adresler 90 | - dosya sistemlerinde partition ID'leri 91 | - database'lerde ID'ler 92 | 93 | - 36 karakterdir ve arada tire koyularak (tireler sadece notasyondur, 128 bite dahil değildir) 5 grup olarak gösterilir: 94 | > 123e4567-e89b-12d3-a456-426655440000 95 | 96 | her grup bir data'yı temsil eder: 97 | 98 | - time 99 | - version 100 | - clock_seq_hi 101 | - clock_seq_lo 102 | - node 103 | 104 | - sadece küçük harf karakterler geçerlidir. 105 | 106 | - Uniform Resource Name (or URN) gösterimi bu şekildedir: 107 | 108 | > urn:uuid:123e4567-e89b-12d3-a456-426655440000 109 | 110 | - Nil UUID 111 | 112 | tümü sıfır olan UUID'dir. 113 | -------------------------------------------------------------------------------- /tutorials/solid.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # SOLID 5 | ############################ 6 | 7 | ############################ 8 | 9 | # SOLID prensipleri 10 | object orianted için çıkmış 5 tane prensibi birarada bulunduran bir terimdir (baş harflerini birleştirilmiştir): SRP, OCP, LSP, ISP, DIP. 11 | 12 | ## Single Responsibility Principle (or SRP or Tek Sorumluluk Prensibi) 13 | Bir sınıfın yahut metotun tek bir sorumluluğu olmalıdır. eğer metotun/sınıfın değişmesi gerekiyorsa; muhtemelen ona yeni sorumluluklar mı eklenecek şüphesi yaratmalıdır. 14 | 15 | ## Open/closed principle (or OCP) 16 | code/software should be open for extension, but closed for modification. yani; yeni eklemeler yapıldığında programda minimum değişiklik yeterli olabilmelidir. örneğin; online ödemeler. yeni bir ödeme geldiğinde yeni ödemeyi bir sınıftan implemente edip bir listeye eklememiz yeterli olabilmelidir. 17 | 18 | Farklı bir değişle; yeni geliştirme geldiğinde; var olan kodumuzu az düzenlemeliyiz fakat yeni sınıflar yaratmalıyız. Bunu ne kadar iyi yapabiliyorsak, kodumuz OCP'ye o kadar yakındır. 19 | 20 | 2 gerçek örnek: 21 | - Observer pattern. Yeni observer class'ları yarattığımızda, subject'i değiştirmeye gerek kalmıyordu. 22 | - JDBC-driver. Yeni driver eklediğimizde, sistemde daha önceden kullanılan driver'ları hiç değiştirme gereği duymuyoruz. 23 | 24 | ## Liskov'un Yerine Geçme Prensibi (or Liskov Substitution Principle or LSP) 25 | Alt sınıflardan oluşan nesnelerin, üst sınıfın nesneleri ile yer değiştirdikleri zaman, aynı davranışı sergilemesi gerekmektedir. 26 | 27 | implementasyonlarımızda not-implemented hatası fırlatan metotumuz varsa, bu kuralı ihlal ediyoruz anlamına gelir. 28 | 29 | Örneğin Ördek sınıfımız olsun. Bu sınıftan oyuncak örnek ve gerçek ördeği implemente edelim. gerçek ördeğin fly metotu varken, oyuncak ördeğin fly metotu not-implemented fırlatacaktır. Bu durumda alt sınıfı üst sınıf ile yer değiştirirse kodumuz hata verecektir. Bunu istemiyoruz. Bunun için farklı çözümlere gidilebilir. Örneğin; UçanÖrdek (sadece fly metotunu implemente eder) ve YüzenÖrdek arayüzlerimizi yazarız. Her implementasyon birkaç hangi özellikleri destekliyorsa sadece onları implemente eder. 30 | 31 | ## Interface Segregation Principle (or ISP or Arayüz Ayrımı Prensibi) 32 | Direk örnek üzerinden gidelim: Mesaj arayüzümüz olsun. bunu implemente eden bir MesajImpl sınıfımız olsun. MesajImpl kendi içinde attachmentVideo, attachmentPhoto gibi özellikler içerecek. fakat her mesajda video olmayabilir. sadece foto olabilir. bu sebeple burada önerilen; birden fazla MesajImpl olsun ve her biri video için yada photo için spesifik geliştirilsin. (bir mesajda hem foto hem video olamayacağını varsayarak örnek verilmiştir). bu şekilde her implementasyon sadece tek bir işe odaklı yani; arayüzün metotlarını implemente etmeye odaklı olmalıdır. böylece kullanılmayan metotlar çıkarılmış olacaktır. 33 | 34 | ## ISP vs LSP 35 | Bu 2'si aynı kapıya çıkmaktadır. ISP arayüzlerin, gruplanıp tek bir arayüz haline gitirilmemesini anlatırken, LSP arayüz, yerine subclass'lardan birini çağırınca aynı davranışların sergilenmesini beklemelizi der. Bu iki prensipten birini tamamen düzgün şekilde yaptığımızda, diğer prensibi de düzgün uygulamış oluruz. 36 | 37 | ## Bağımlılığın Ters Çevrilmesi Prensibi (or Dependency Inversion Principle or DIP) 38 | iki kuralı vardır: 39 | 40 | 1. High-level modules should not depend on low-level modules. Both should depend on other high levels. 41 | 42 | __Örnek-1:__ 43 | 44 | Good design: shopping servisi (high level module), ödeme servisini(high level module) çağırarak işlem yapıyor. 45 | 46 | Bad design: shopping servisi (high level module), CreditCard (low-level module) servisini direk çağırıyor. 47 | 48 | __Örnek-2:__ 49 | 50 | Good design: shopping servisi (high level module), database servisini(high level module) çağırarak işlem yapıyor. 51 | 52 | Good design: shopping servisi (high level module), mysql servisini(low level module) çağırarak işlem yapıyor. 53 | 54 | ```java 55 | public abstract Shopping { 56 | 57 | // Bad design example: 58 | private MySqlDatabase mySqlDatabase = new MySqlDatabase(); 59 | 60 | // Good design example: 61 | private Database database = new MySqlDatabase(); 62 | 63 | public pay(){ 64 | 65 | // payment operations... 66 | 67 | // log the result to DB at the end of the payment 68 | 69 | // bad design: 70 | mySqlDatabase.insert("payment finished"); 71 | 72 | // good design: 73 | database.insert("payment finished"); 74 | } 75 | } 76 | ``` 77 | 78 | 2. Abstractions should not depend on details. Details should depend on abstractions. 79 | 80 | ```java 81 | // ExternalMessageProcessService class is abstraction. 82 | public abstract ExternalMessageProcessService { 83 | 84 | boolean httpParserLogException; 85 | 86 | public processMessage(Message message){ 87 | 88 | // Example-1 for bad design 89 | if(httpParserLogException == true){ 90 | processMessageWithoutLog(message); 91 | } else { 92 | processMessage(message); 93 | } 94 | 95 | // Example-2 for bad design 96 | if(Type.KAFKA == getType()){ 97 | log.warn("prefer Http Service which because it is faster (or any warnign here about implementation!)") 98 | } 99 | } 100 | 101 | public Type getType(); 102 | } 103 | 104 | // KafkaMessageProcessService class is detail. 105 | public abstract KafkaMessageProcessService implements ExternalMessageProcessService { 106 | 107 | public Type getType(){ 108 | return Type.KAFKA; 109 | } 110 | 111 | public processMessage(KafkaMessage message){ 112 | // code here... 113 | } 114 | } 115 | 116 | // HttpMessageProcessService class is detail. 117 | public abstract HttpMessageProcessService implements ExternalMessageProcessService { 118 | 119 | public Type getType(){ 120 | return Type.HTTP; 121 | } 122 | 123 | public processMessage(HttpMessage message){ 124 | throw new Exception("Unimplemented!"); 125 | } 126 | 127 | public processMessageWithoutLog(HttpMessage message){ 128 | 129 | // code here... 130 | } 131 | } 132 | ``` -------------------------------------------------------------------------------- /tutorials/web_custom_elements.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # WEB CUSTOM COMPONENTS 5 | ############################ 6 | 7 | ############################ 8 | 9 | # micro-frontends (or micro frontends) 10 | web-component teknolojilerinden yararlanarak, her component'i farklı projeler olarak geliştirmeyi ve bunları önyüzde hepsini birlikte load edip çalıştırma yöntemidir. 11 | 12 | - web-component altyapısı kullanılmazsa, web-component'i sağlayan polyfill'lerden yararlanılması şarttır. 13 | - Hepsini birlikte load edip etmeyeceğimiz aslında bize kalmış, ihtiyaç durumunda da load edilebilir. (kısmen business'e bağlı) 14 | - Her proje tamamen farklı repo'larda geliştirilebilir ve farklı teknolojiler içerebilir. 15 | - Tüm projeler aslında tek bir proje tarafından call edilmelidir. Bu main proje web sitemizin ilk açıldığı index.html'dir. Burada tüm diğer projeler import edileceği için, isim çakışması olmaması gerekir. Bunun için ya web-pack'e ayar yapacağız yada her proje baştan kendi standartlarını (diğer projelerle çakışmayan prefix'lerini) belirleyecek. 16 | 17 | • • • • • • • • • • • • • • • • • • • • • • • • 18 | 19 | • • • • • • • • • • • • • • • • • • • • • • • • 20 | 21 | • • • • • • • • • • • • • • • • • • • • • • • • 22 | 23 | # reflow 24 | reflow is the name of the web browser process for re-calculating the positions and geometries of elements in the document, for the purpose of re-rendering part or all of the document. 25 | 26 | # DocumentFragment 27 | bunun "web component" ile hiçbir bağlantısı yoktur. 28 | 29 | Elimizde bir dizi olsun ve dizinin her elemanını bir DOM nesnesinin içine append edelim. Bunun için for-loop döner ve her defasında append child çağırırız. İşte her appendChild metotunu çağırdığımızda re-flow gerçekleşir. Performansı olumsuz etkiler. 30 | 31 | Bunu önlemek için boş bir DocumentFragment yaratırız ve bu DocumentFragment'a ekleme yaparız. En sondada bu DocumentFragment'ı append ederiz. 32 | 33 | Bunun yerine boş bir div element'i oluşturup içine RAM'de ekleme yapıp for-loop bittiğinde RAM'deki nesnesi tek hamlede de append edebilirdik. AYnı kapıya çıkardı. Fakat DocumentFragment bu iş için sunuldu ve gereksiz div elementleri oluşturmaktan kaçmamızı sağladı. 34 | 35 | Boş bir DocumentFragment oluşturma: 36 | 37 | ```js 38 | let fragment = new DocumentFragment(); 39 | // or 40 | var fragment = document.createDocumentFragment(); 41 | ``` 42 | 43 | içine bir şeyler ekleyelim: 44 | 45 | ```js 46 | const myDiv = document.createElement('div'); 47 | fragment.appendChild(myDiv); 48 | ``` 49 | 50 | fragment'ımızı DOM'a append edelim: 51 | 52 | ```js 53 | parentElement.appendChild(fragment); 54 | ``` 55 | 56 | • • • • • • • • • • • • • • • • • • • • • • • • 57 | 58 | • • • • • • • • • • • • • • • • • • • • • • • • 59 | 60 | • • • • • • • • • • • • • • • • • • • • • • • • 61 | 62 | # Web component 63 | HTML ortamında 3 farklı şekilde "web component" yapılabilir (Mozilla bu şekilde kategorilendirmiş: (source-id: 455) title: "Concepts and usage"): 64 | 65 | - custom elements 66 | - shadow DOM 67 | - HTML template 68 | - template 69 | - slot 70 | 71 | 3ü birbirinden bağımsız özelliklerdir. 72 | 73 | # custom elements 74 | tarayıcılar tarafından yeni desteklenmeye başlanan özellik. custom HTML'e elementleri yaratmamıza yarıyor. kendi event'leri ve içinde birçok HTML elementi barındırabiliyor. 75 | 76 | ```html 77 |
78 | ``` 79 | 80 | gibi var olan alternatif çözümler ile neredeyse aynı kapıya çıkıyor. fakat okunabilirlik açısından çok daha ileri seviyede olmaktadır. 81 | 82 | yazdığımız bir HTML tag'ini register etmezsek (tarayıcının desteklemesi gerekir) DOM üzerinde aktif olamaz fakat yine de tarayıcı hata vermediği için çalışmaya devam edebilir. fakat custom-component'ini destekleyen bir tarayıcı ise, yeni tip HTML objemizi tarayıcıya register ederiz ve gerçek bir HTML objesiymiş gibi kullanabilir (best practice'e uygun). 83 | 84 | Custom component'imizi yaratalım: 85 | 86 | ```js 87 | // below extends the "p" elemen. we can also extends others. 88 | // If we don't want to extend any element, we can use the most generic class which is: "HTMLElement". 89 | class MyCustomClass extends HTMLParagraphElement { 90 | constructor() { 91 | // this is calling when a new instance is creating. 92 | 93 | // Always call super first in constructor. this is required (only for constructor). 94 | super(); 95 | 96 | this.setAttribute('prop1', 'val1'); 97 | this.innerHTML = "Hello world"; 98 | 99 | } 100 | 101 | connectedCallback(){ 102 | // this is called when we attach custom-element to DOM. 103 | } 104 | 105 | // any custom method 106 | isDisabled() { 107 | return this.hasAttribute('disabled'); 108 | } 109 | 110 | disconnectedCallback(){ 111 | // this is calling when removed from DOM. 112 | // use this when the component use data from indexedDB, cookies... 113 | } 114 | 115 | attributeChangedCallback(attrName, oldVal, newVal){ 116 | // this is calling when prop changes. 117 | // this function is only calling props on "observedAttributes". 118 | } 119 | 120 | static get observedAttributes() { 121 | return ['prop1', 'prop2']; 122 | } 123 | 124 | adoptedCallback(){ 125 | // The custom element has been moved into a new document (e.g. someone called document.adoptNode(el)). 126 | } 127 | 128 | } 129 | ``` 130 | 131 | hemen ardından global olarak tarayıcıya tanıtalım: 132 | 133 | ```js 134 | // customElements is under window object. class type: "CustomElementRegistry". 135 | customElements.define('my-custom-component-name', MyCustomClass, { extends: 'p' }); 136 | ``` 137 | 138 | artık istediğimiz yerde kullanabiliriz: 139 | 140 | ```html 141 | 142 | ``` 143 | 144 | # Template 145 | custom-component'ten tamamen bağımsız bir özelliktir. 146 | 147 | ```html 148 | 151 | ``` 152 | 153 | Template'ler güncel tarayıcılarca desteklenen bir elementtir. Template içerisinde koyduğumuz herşeyin kolayca başka yere klonlayabilmemizi (re-use) sağlanır: 154 | 155 | ```js 156 | let template = document.getElementById('my-paragraph'); 157 | let templateContent = template.content; 158 | document.body.appendChild(templateContent); 159 | ``` 160 | 161 | # shadow Dom 162 | Shadow DOM kavramı Web browser'ların sunduğu bir teknolojidir. React veya virtual DOM ile hiçbir bağlantısı yoktur. Shadow DOM query ile erişilemeyen DOM objeleri yaratabilmemizi sağlıyor. böylece sayfadaki CSS'lerden ve JS event'leri bu Objelere etki edemiyor. Örneğin Facebook'un "share" button'u. tüm dünyadaki web sayfalarında standart CSS ve event'lerle çalışması bekleniyor ise; bu "share" objelerini shadow DOM ile yapmalıyız. 163 | 164 | shadow DOM'lar web tarayıcı inspector'ünde görülebilir fakat JS ile erişilemezler. 165 | 166 | ```js 167 | 168 | 169 | 170 | // select element by class ID 171 | const shadowEl = document.querySelector(".shadow-host"); 172 | 173 | // make this element shadow 174 | // attachShadow fonksiyonu "shadowEl" içindeki tüm DOM objelerini shadow'a olarak set ediyor. 175 | // bizim örnekte "shadowEl" içinde hiçbir şey yok. bu sebeple hiçbir DOM objesi shadow içine alınmayacak fakat "shadowEl" ve içi artık shadow DOM'a aittir. 176 | const shadow = shadowEl.attachShadow({mode: 'open'}); 177 | 178 | // create a new element 179 | const link = document.createElement("a"); 180 | link.href = "Facebook.com/share" 181 | 182 | // add the new element inside the shadow element 183 | shadow.appendChild(link); 184 | ``` 185 | -------------------------------------------------------------------------------- /tutorials/web_http_status_codes_iana.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # WEB HTTP STATUS CODES IANA 5 | ############################ 6 | 7 | ############################ 8 | 9 | Aşağıdaki tablo buradan alınmıştır: (source-id: 327) 10 | 11 | | Value | Description | Reference | 12 | |---------|---------------------------------|-----------------------------------------------| 13 | | 100 | Continue | [RFC7231, Section 6.2.1] | 14 | | 101 | Switching Protocols | [RFC7231, Section 6.2.2] | 15 | | 102 | Processing | [RFC2518] | 16 | | 103 | Early Hints | [RFC8297] | 17 | | 104-199 | Unassigned | | 18 | | 200 | OK | [RFC7231, Section 6.3.1] | 19 | | 201 | Created | [RFC7231, Section 6.3.2] | 20 | | 202 | Accepted | [RFC7231, Section 6.3.3] | 21 | | 203 | Non-Authoritative Information | [RFC7231, Section 6.3.4] | 22 | | 204 | No Content | [RFC7231, Section 6.3.5] | 23 | | 205 | Reset Content | [RFC7231, Section 6.3.6] | 24 | | 206 | Partial Content | [RFC7233, Section 4.1] | 25 | | 207 | Multi-Status | [RFC4918] | 26 | | 208 | Already Reported | [RFC5842] | 27 | | 209-225 | Unassigned | | 28 | | 226 | IM Used | [RFC3229] | 29 | | 227-299 | Unassigned | | 30 | | 300 | Multiple Choices | [RFC7231, Section 6.4.1] | 31 | | 301 | Moved Permanently | [RFC7231, Section 6.4.2] | 32 | | 302 | Found | [RFC7231, Section 6.4.3] | 33 | | 303 | See Other | [RFC7231, Section 6.4.4] | 34 | | 304 | Not Modified | [RFC7232, Section 4.1] | 35 | | 305 | Use Proxy | [RFC7231, Section 6.4.5] | 36 | | 306 | (Unused) | [RFC7231, Section 6.4.6] | 37 | | 307 | Temporary Redirect | [RFC7231, Section 6.4.7] | 38 | | 308 | Permanent Redirect | [RFC7538] | 39 | | 309-399 | Unassigned | | 40 | | 400 | Bad Request | [RFC7231, Section 6.5.1] | 41 | | 401 | Unauthorized | [RFC7235, Section 3.1] | 42 | | 402 | Payment Required | [RFC7231, Section 6.5.2] | 43 | | 403 | Forbidden | [RFC7231, Section 6.5.3] | 44 | | 404 | Not Found | [RFC7231, Section 6.5.4] | 45 | | 405 | Method Not Allowed | [RFC7231, Section 6.5.5] | 46 | | 406 | Not Acceptable | [RFC7231, Section 6.5.6] | 47 | | 407 | Proxy Authentication Required | [RFC7235, Section 3.2] | 48 | | 408 | Request Timeout | [RFC7231, Section 6.5.7] | 49 | | 409 | Conflict | [RFC7231, Section 6.5.8] | 50 | | 410 | Gone | [RFC7231, Section 6.5.9] | 51 | | 411 | Length Required | [RFC7231, Section 6.5.10] | 52 | | 412 | Precondition Failed | [RFC7232, Section 4.2][RFC8144, Section 3.2] | 53 | | 413 | Payload Too Large | [RFC7231, Section 6.5.11] | 54 | | 414 | URI Too Long | [RFC7231, Section 6.5.12] | 55 | | 415 | Unsupported Media Type | [RFC7231, Section 6.5.13][RFC7694, Section 3] | 56 | | 416 | Range Not Satisfiable | [RFC7233, Section 4.4] | 57 | | 417 | Expectation Failed | [RFC7231, Section 6.5.14] | 58 | | 418-420 | Unassigned | | 59 | | 421 | Misdirected Request | [RFC7540, Section 9.1.2] | 60 | | 422 | Unprocessable Entity | [RFC4918] | 61 | | 423 | Locked | [RFC4918] | 62 | | 424 | Failed Dependency | [RFC4918] | 63 | | 425 | Too Early | [RFC8470] | 64 | | 426 | Upgrade Required | [RFC7231, Section 6.5.15] | 65 | | 427 | Unassigned | | 66 | | 428 | Precondition Required | [RFC6585] | 67 | | 429 | Too Many Requests | [RFC6585] | 68 | | 430 | Unassigned | | 69 | | 431 | Request Header Fields Too Large | [RFC6585] | 70 | | 432-450 | Unassigned | | 71 | | 451 | Unavailable For Legal Reasons | [RFC7725] | 72 | | 452-499 | Unassigned | | 73 | | 500 | Internal Server Error | [RFC7231, Section 6.6.1] | 74 | | 501 | Not Implemented | [RFC7231, Section 6.6.2] | 75 | | 502 | Bad Gateway | [RFC7231, Section 6.6.3] | 76 | | 503 | Service Unavailable | [RFC7231, Section 6.6.4] | 77 | | 504 | Gateway Timeout | [RFC7231, Section 6.6.5] | 78 | | 505 | HTTP Version Not Supported | [RFC7231, Section 6.6.6] | 79 | | 506 | Variant Also Negotiates | [RFC2295] | 80 | | 507 | Insufficient Storage | [RFC4918] | 81 | | 508 | Loop Detected | [RFC5842] | 82 | | 509 | Unassigned | | 83 | | 510 | Not Extended | [RFC2774] | 84 | | 511 | Network Authentication Required | [RFC6585] | 85 | | 512-599 | Unassigned | | 86 | -------------------------------------------------------------------------------- /tutorials/web_websocket_spring.md: -------------------------------------------------------------------------------- 1 | ############################ 2 | 3 | ############################ 4 | # WEB WEBSOCKET SPRING 5 | ############################ 6 | 7 | ############################ 8 | 9 | # Websocket examples with Spring 10 | 11 | ## Example without STOMP and SocksJS 12 | https://github.com/yusuf-daglioglu/raw-websocket-with-spring 13 | 14 | ## Example with STOMP and SocksJS 15 | https://github.com/yusuf-daglioglu/gs-messaging-stomp-websocket 16 | 17 | This is the fork of: https://github.com/spring-guides/gs-messaging-stomp-websocket 18 | 19 | The stable version is on this git tag: https://github.com/spring-guides/gs-messaging-stomp-websocket/tree/2.1.6.RELEASE 20 | 21 | This is the minimalist example of Websocket (via SocksJS and STOMP & on back-end Spring). 22 | 23 | # Web UI 24 | http://localhost:8080 25 | 26 | # Websocket URL 27 | After first HTTP request, client start a websocket from this URL: 28 | 29 | ``` 30 | /gs-guide-websocket/953/0lej1i41/websocket 31 | ``` 32 | 33 | - /gs-guide-websocket 34 | 35 | is the config which we wrote on Spring side 36 | 37 | - /953 38 | 39 | This is random 3 number generated by client. It named as "Server-id" on SockJS protocol. Optionally server can route the requests on different servers (via load balancer...). SockJS tells nothin about server side for this value. 40 | 41 | - /0lej1i41 42 | 43 | "session-id" is the standart of SocksJS. Each new connection (not message or subscription!) of SockJS, creates a new random session-id. It is generated by client. 44 | 45 | - /websocket 46 | 47 | "transport" information. with which technology the client wants to transmit data. the value could be: xhr-streaming. 48 | 49 | ## URL with /info path 50 | Client send HTTP-upgrade request to /info suffixed URL. "info" is a standart of SockJS. So we did not write any config to Spring about this URL. SockJS integration of Spring added this suffix automatically. 51 | 52 | ## Explanations of Java source code 53 | 54 | ```java 55 | @Override 56 | public void configureMessageBroker(MessageBrokerRegistry config) { 57 | 58 | // This config makes to run a built-in message-broker. 59 | // All topics that will be simulated via that broker should start with /topic. 60 | // In another word, when a message comes to /topic prefixed destination, 61 | // the subscriptions and broadcasting will be managed by Spring built-in message broker. 62 | config.enableSimpleBroker("/topic"); 63 | 64 | // if client send a message to destination which has prefix "/app", 65 | // that message will be redirected to @MessageMapping methods in @Controller classes. 66 | config.setApplicationDestinationPrefixes("/app"); 67 | } 68 | 69 | @Override 70 | public void registerStompEndpoints(StompEndpointRegistry registry) { 71 | 72 | // This URL will be called by client on the upgrade-HTTP request. 73 | registry.addEndpoint("/gs-guide-websocket").withSockJS(); 74 | } 75 | ``` 76 | 77 | ```java 78 | @MessageMapping("/hello") // if client will send a STOMP message to /app/hello, this method will be triggered by Spring. 79 | @SendTo("/topic/greetings") // return value from this value will be sent to /topic/greetings automatically by Spring. 80 | public Greeting greeting(HelloMessage message) throws Exception { 81 | Thread.sleep(1000); // simulated delay 82 | return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!"); 83 | } 84 | ``` 85 | --------------------------------------------------------------------------------