http://blog.trackets.com/2013/02/01/ember-dot-js-router-and-template-naming-convention.html
понедельник, 15 декабря 2014 г.
вторник, 2 декабря 2014 г.
Если истек рутовый сертификат для подписки собственных ключей
Новое сражение с обновлением сертификатов.
На этот раз как я понял истекал рутовый CA сертификат и один сертификат заказчика, который был подписан первым.
Они сгенерили новый свой сертификат, но опять подписали его не тем, потом прислали новый рутовый и сказали что нужно его переподписать.
С этой задачей справиться легко(по опыту), а вот что делать с ключами, которые были подписаны старым истекающим рутом, но самих их время еще не пришло? Тут пришлось добавть этот новый рут отдельным сертификатом в страстстор и тогда все заработало
Несменный сайт помошник https://www.sslshopper.com/article-most-common-java-keytool-keystore-commands.html
На этот раз как я понял истекал рутовый CA сертификат и один сертификат заказчика, который был подписан первым.
Они сгенерили новый свой сертификат, но опять подписали его не тем, потом прислали новый рутовый и сказали что нужно его переподписать.
$ openssl pkcs12 -export -in newcertificate.crt -inkey newcertificate.key -out newcertificate.p12 -name newcertificate -CAfile "VeriSign Class 3 Public Primary Certification Authority - G5.crt"
keytool -importkeystore \
-srckeystore newcertificate.p12 \
-srcalias newcertificate \
-destkeystore my.jks -destalias newcertificate -srcstoretype PKCS12 \
-destkeypass mypass
"VeriSign Class 3 Public Primary Certification Authority - G5.crt" - это новый рутовый, гарантирующий подлинность выпущенных заказчиком собственных сертификатов и ключей
С этой задачей справиться легко(по опыту), а вот что делать с ключами, которые были подписаны старым истекающим рутом, но самих их время еще не пришло? Тут пришлось добавть этот новый рут отдельным сертификатом в страстстор и тогда все заработало
keytool -import -trustcacerts -alias rootcaverisign -file VeriSign\ Class\ 3\ Public\ Primary\ Certification\ Authority\ -\ G5.crt -keystore myTrust.jtsКроме того колега показал, как он справляется с проблемами когда у них не работают какие-то внешние сервисы. Когда удаленный сервис работает с открытым ключем, и нам не нужно от него иметь свой для гарантий своей подлинности, мы можем заполучить его публичный ключ и добавить его в свой трастстор так:
openssl s_client -connect someserviceprovider.com:443 > letssaveinthisfile.ceropenssl обычно подвисает в этом месты мы рвем соединение ^C, но файл сохраняется, проверям если он нормального веса значит все прошло нормально и такой сертификат можно добавлять в трастстор:)
Несменный сайт помошник https://www.sslshopper.com/article-most-common-java-keytool-keystore-commands.html
суббота, 29 ноября 2014 г.
Как запустить пришедшее в браузер приложение на Backbonejs без дополнительных ajax запросов
var AppointmentApp = new (Backbone.View.extend({
Collections: {},
Models: {},
Views: {},
events: {
'click a[data-backbone]': function(e){
e.preventDefault();
Backbone.history.navigate(e.target.pathname, { trigger: true });
}
},
start: function(bootstrap){
this.appointments = new AppointmentApp.Collections.Appointments(bootstrap.appointments);
var appointmentsView = new AppointmentApp.Views.Appointments({collection: this.appointments});
$('#app').html(appointmentsView.render().el);
}
}))({el: document.body});
серевер же старзу вставляет данные-колекцию в страницы и где-нибудь пониже мы вызываем:
var bootstrap = {
appointments: [
//сюда выводятся при рендеринге данные на сервере
]
}
$(function(){ AppointmentApp.start(bootstrap); })
Ярлыки:
Backbone,
Javascript
Как не вязать вью на модель в new Backbone.js
В новом бекбоне появилось встроенное решение отвязки модели от разрешенного дома вьюхи.
Было:
Стало(Added in Backbone 0.9.9):
Было:

var AppointmentView = Backbone.View.extend({
template: _.template("<%= title %>"),
initialize: function(){
this.model.on('change:title', this.changedTitle, this);
},
render: function(){
this.$el.html(this.template(this.model.attributes));
},
changedTitle: function(model, value, options){
this.$('span').html(value);
if (options.highlight !== false){
this.$el.effect('highlight', {}, 1000);
}
},
remove: function() {
Backbone.View.prototype.remove.apply(this, arguments);
this.model.off(null, null, this);
}
});
var appointmentView = new AppointmentView({model: someModel});
appointmentView.remove();
Стало(Added in Backbone 0.9.9):
var AppointmentView = Backbone.View.extend({
template: _.template("<%= title %>"),
initialize: function(){
this.listenTo(this.model, 'change:title', this.changedTitle);
},
render: function(){
this.$el.html(this.template(this.model.attributes));
},
changedTitle: function(model, value, options){
this.$('span').html(value);
if (options.highlight !== false){
this.$el.effect('highlight', {}, 1000);
}
}
});
var appointmentView = new AppointmentView({model: someModel});
appointmentView.remove();// автоматически вызовет appointmentView.stopListening();
Ярлыки:
Backbone,
Javascript
суббота, 22 ноября 2014 г.
четверг, 16 октября 2014 г.
Objective-C основные коцепции
Первоначально Objective-C появился как настройка над C, в виде новых синтаксических конструкций заимствованных у Smalltalk, которые переводились препроцессором в обычные функции C. Кроме того библиотека времени выполнения обрабатывала такие вызовы. Так язык C имея в своем синтаксисе только структуру struct, становился обьектно ориентированным языком.
По сути Objective-C является и сейчас настройкой над C, потому что мы можем написать программу на чистом C, и передать компилятору Objective-C.
"Мир" Objective-C воспринимает как наличие обьектов, которые общаются друг с другом путем передачи сообщений - вызовом методов. Состояние обьектов определяются инвариантами и закрыты от внешнего мира, а поведение методами, которые принимают сообщения и могут измененять в результате состояние обьекта.
Файлы модулей *.m (есть применяется сметь Objective-C и C++, то *.mm)
Файлы заголовков *.h
Все создаваемые обьекты размещаются в динамической памяти, от сюда есть специальный тип id, который является под капотом void*, то есть указателем на обьект любого типа.
Чтобы узнать какого же типа текущий обьект NSObject - базовый класс для всех классов - приносит инвариант isa класса Class(позволяет узнавать имена своего и базового класса, а также инварианты класса и какие прототипы методов реализованые этим обьектом в нем).
Зарезервированные слова Objective-C, отличающиеся от слов C, начинаются с @.
Вывод в стандартный вывод
NSLog(@"Hello, World!");
Префикс NS от OS NeXTSTEP - это вроде образовательная операционная система над которой трудился Стив Джобс, когда его попросили из собственного Apple Computers, именно там развили Objective-C
Переменный и стандарный классы
Чтобы создать переменную типа строки мы должны использовать тип NSString*, это мы создаем ссылку на созданный обьект:NSString* firstName = @"World";
Как всегда в С-мире есть плейсхолдеры,
NSLog(@"Hello there, %@.", firstName);%@ - это плейсхолдер для любой переменной, которая передается вместе со строкой.
Есть тип числовой:
NSNumber* age = @28; NSLog(@"%@", age);
Массив, опять же нужно обратить внимание как мы создаем обьекты в памяти с помощью указания символом @, и потом ссылаемся на общую обвертку типом-ссылкой:
NSArray *apps = @[@"AngryFowl", @"Lettertouch", @"Tweetrobot"]; NSLog(@"%@", apps[1]);Так создаются неизменяемые массивы, но в Objective-C есть всегда изменяемый брат близнец: например NSMutableArray, NSMutableString
Мапа:
NSDictionary *appRatings = @{@"AngryFowl": @3, @"Lettertouch": @5};
NSLog(@"%@", appRatings[@"AngryFowl"]);
Ярлыки:
Objective-C
пятница, 19 сентября 2014 г.
Backbone - общая структура
Главная концепция - держать данные отдельно от ДОМа страницы, так креши во вью не приводят к потерям данных на странице.
Создание модели
var MyModel = Backbone.Model.extend({});
var myModel = new MyModel({myField: "..."});
myModel.set('myField', 'some value');
Создание вьюхи:
var MyView = Backbone.View.extend({
render: function(){
$(this.el).html('<li>' + this.model.get('myField') + '</li>
');
}
});
var myView = new MyView({model: myModel});
myView.render();
$('#app').html(myView);
Ярлыки:
Backbone,
Frontend,
Javascript
четверг, 18 сентября 2014 г.
Js FE modularity
Если каждый js файл будет создавать свои глобальные переменные и пользоваться ими в процессе работы приложения-страницы, то другие файлы-модули могут перетереть такие переменные не зная, что их выбранное имя уже кем-то занято.
Для это и придумали подход к модульности через неймспейсинг
module1.js:
Когда мы их испльзуем внутри наших моделей мы сталкиваемся с главными проблемами:
1) Мы можем их случайно изменить.
2) У нас очень много вложенностей-замыканий и это очень неефективно обращаться из них в глобальный скоуп с точки зрения произодительности. Эти проблемы решаются передачей глобальной переменной на этапе создания модуля на странице:
Эта процедура называется global imports
Augmentation
Процедура, которая помогает нам расширить существующий модуль
augmentation1-for-module1.js:
Для это и придумали подход к модульности через неймспейсинг
module1.js:
var MODULE1 = (function(){
var privateField1={...};
var privateField2={...};
var privateMethod1=function{...};
var privateMethod2=function{...};
return {
publicField1: {...},
publicField2: {...},
publicMethod1: function(){...},
publicMethod2: function(){...}
};
})();
Global Imports
Ну если быть до конца искренним, то глобальные переменные все же нужны, но очень в ограниченном и аргументированном количестве.Когда мы их испльзуем внутри наших моделей мы сталкиваемся с главными проблемами:
1) Мы можем их случайно изменить.
2) У нас очень много вложенностей-замыканий и это очень неефективно обращаться из них в глобальный скоуп с точки зрения произодительности. Эти проблемы решаются передачей глобальной переменной на этапе создания модуля на странице:
var MODULE1 = (function(neededGlobalInside){
var privateField1={...};
var privateField2={...};
var privateMethod1=function{...};
var privateMethod2=function{...};
return {
publicField1: {...},
publicField2: {...},
publicMethod1: function(){...},
publicMethod2: function(){...}
};
})(global1);
Эта процедура называется global imports
Augmentation
Процедура, которая помогает нам расширить существующий модуль
augmentation1-for-module1.js:
MODULE1 = function(oldNS){
var newprivateField1={...};
var newprivateMethod1=function{...};
oldNS.newpublicMethod1: function(){...};
return oldNS;
}(MODULE1);
Ярлыки:
Frontend,
Javascript
Работа с исчислениями
Работа с денежными рассчетами:
int result = parseFloat((0.2 + 0.3).toFixed(1));С плавающей точкой дают сбив с очень маленькой цифрой за рядом нулей, это фиксится строгим указанием сколько цифр мы хотим видеть после точки, но проблема в том, что тоФиксед возвращает строку, для этого мы парсим ее обратно в число:)
typeof NaN; // -> "number"
console.log(NaN === NaN); // -> false
isNaN("42"); // -> false, потому что строка
parseInt(intStr, radix); //radix -> 10, 8, 16, 2
Ярлыки:
Javascript
пятница, 12 сентября 2014 г.
Тестирование производительности в Js
Грубый метод измерения времени выполнения блока кода
console.time("Id");
//блок кода
console.timeEnd("Id");
Более точный:
console.time("Id");
//блок кода
console.timeEnd("Id");
Более точный:
function SpeedTest(testImplement, testParams, repetitions){
this.testImplement = testImplement;
this.testParams = testParams;
this.repetitions = repetitions || 10000;
this.average = 0;
}
SpeedTest.prototype = {
startTest: function(){
var beginTime, endTime, sumTimes = 0;
for (var i = 0, x = this.repetitions; i < x; i++){
beginTime = +new Date();
this.testImplement( this.testParams );
endTime = +new Date();
sumTimes += endTime - beginTime;
}
this.average = sumTimes / this.repetitions;
return console.log("Average execution across " +
this.repetitions + ": " +
this.average);
}
}
Ярлыки:
Javascript,
Javascript Optimization
четверг, 11 сентября 2014 г.
Полезные Js
http://www.smashingmagazine.com/2009/02/08/50-extremely-useful-javascript-tools/
http://www.javascriptkit.com/cutpastejava.shtml
http://www.scripterlative.com/
http://www.javascriptkit.com/cutpastejava.shtml
http://www.scripterlative.com/
Ярлыки:
Javascript
Прототипирование в Javascript
valueOf - возвращается сам обьект, на котором вызван данный метод, смысл только для классов, которым мы переопределим этот метод и будем обьект предствлять как простое значение типа хеш.
constructor - что создало обьект. Например для строки: function String(){[native code]}, для обьекта {}: function Object(){[native code]}, или для кастомного класса: function MyClass(a, b){this.a = a; this.b = b;}
toLocaleString - для обьекта класса Date значения результата данного метода будут отличаться в зависимости под какую локаль настроен браузер клиента, а так обычно результат идентичен со следующей вункцией.
toString - функции представляются в виде строки сорцов, для этих обьектов это самое интересное применение.
isPrototypeOf - true если объект на котором вызывают этот метод является прямым прототипом параметра.
propertyIsEnumerable - true возвращает только на свойства определенные именно в этом обьекте, на свойства выше в цепочке прототипов возвращается false, если true - то это поле появится в for..in. Но почему тогда если добавить в прототип Array, то такие поля появятся в for..in?
hasOwnProperty - true если свойство принадлежит именно самому объекту, а не одному из прототипов по цепочке. Я так понимаю с предыдущим методом есть оличие в том, что некоторые поля прототипов ответятся как тру в предыдущем методе.
Пример использование методом Object
Можно ставить прототипом и не класс, а обьект:
Этот новый метод криэйт в последнийх реализациях JS позволил упростить старый добрый метод наследования.
Допустим у нас есть два класса:
Старый метод:
constructor - что создало обьект. Например для строки: function String(){[native code]}, для обьекта {}: function Object(){[native code]}, или для кастомного класса: function MyClass(a, b){this.a = a; this.b = b;}
toLocaleString - для обьекта класса Date значения результата данного метода будут отличаться в зависимости под какую локаль настроен браузер клиента, а так обычно результат идентичен со следующей вункцией.
toString - функции представляются в виде строки сорцов, для этих обьектов это самое интересное применение.
isPrototypeOf - true если объект на котором вызывают этот метод является прямым прототипом параметра.
propertyIsEnumerable - true возвращает только на свойства определенные именно в этом обьекте, на свойства выше в цепочке прототипов возвращается false, если true - то это поле появится в for..in. Но почему тогда если добавить в прототип Array, то такие поля появятся в for..in?
hasOwnProperty - true если свойство принадлежит именно самому объекту, а не одному из прототипов по цепочке. Я так понимаю с предыдущим методом есть оличие в том, что некоторые поля прототипов ответятся как тру в предыдущем методе.
Пример использование методом Object
Object.prototype.findOwnerOfProperty = function(propName){
var currentObject = this;
while(currentObject !== null) {
if (currentObject.hasOwnProperty(propName)) {
return currentObject;
} else {
currentObject = currentObject.__proto__;
}
}
return "No property found!";
}
Можно ставить прототипом и не класс, а обьект:
var shoe = { size: 6, gender: "women", construction: "slipper"};
var magicShoe = Object.create(shoe);
magicShoe.jewels = "ruby";
magicShoe.travelAction = "click heels";
magicShoe.actionRequired = 3;
shoe.isPrototypeOf(magicShoe);//true
Этот новый метод криэйт в последнийх реализациях JS позволил упростить старый добрый метод наследования.
Допустим у нас есть два класса:
function Animal(name) {
this.name = name
this.canWalk = true
}
Animal.prototype = {
live: function(){}
};
function Rabbit(name) {
this.name = name
}
Старый метод:
function extend(Child, Parent) {
var F = function() { };
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.superclass = Parent.prototype;
}
extend(Animal, Rabbit);
Новый метод:
Rabbit.prototype = Object.create(Parent.prototype);
Ярлыки:
Javascript
вторник, 9 сентября 2014 г.
Собрать комиты по таске в буфер
git log --author="Andrii Ieremenko" --grep=PDR-520 --pretty=format:"%h" | pbcopy
среда, 3 сентября 2014 г.
воскресенье, 17 августа 2014 г.
BDD in JS
http://eamodeorubio.github.io/bdd-with-js
http://custardbelly.com/blog/blog-posts/2014/01/08/bdd-in-js-cucumberjs/
http://www.infoq.com/news/2014/04/cucumberjs-bdd-biezemans
http://custardbelly.com/blog/blog-posts/2014/01/08/bdd-in-js-cucumberjs/
http://www.infoq.com/news/2014/04/cucumberjs-bdd-biezemans
Ярлыки:
BDD,
Cucumber,
Javascript
суббота, 16 августа 2014 г.
Cтатьи с терминами и о самих Online Payment Systems
http://sixrevisions.com/tools/online-payment-systems/
http://www.awwwards.com/18-online-payment-services-and-systems.html
http://chineseseoshifu.com/blog/online-payment-methods-china.html
https://www.chinapaymentservices.com/online-payments-china
http://www.awwwards.com/18-online-payment-services-and-systems.html
http://chineseseoshifu.com/blog/online-payment-methods-china.html
https://www.chinapaymentservices.com/online-payments-china
Ярлыки:
Payment Systems
среда, 13 августа 2014 г.
Работа с радиобаттонами
Впечатлило:)
Say you had radio buttons like these, for example:
type='radio' name='gender' value='Male'>
type='radio' name='gender' value='Female'>
And you wanted to check the one with a value of "Male" onload if no radio is checked:
$(function() {
var $radios = $('input:radio[name=gender]');
if($radios.is(':checked') === false) {
$radios.filter('[value=Male]').prop('checked', true);
}
});
Ярлыки:
Javascript,
jQuery
вторник, 12 августа 2014 г.
JVM трастсторы и кисторы: как из полученного вставить куда нужно
Допустим нам прислали поставщик ключей следующие файлы:
У нас есть
javax.net.ssl.keyStore=keystore.jks
javax.net.ssl.trustStore=truststore.jts
Сначала для импорта в кистор мы должны обьединить ключ и сертификат в один p12 кистор. Делаем:
Вводим пароль от поставщика ключей и впринципе создаемся такой же для нового кистора и есть, теперь добавить из этого кистора в джавовский:
Теперь добавляем сертификат к трастору:
Теперь, как отличить по принту(даже короткому) в хранилище ключей лежит то, что представляет нас, или то, чему доверяем мы.
Ключ кому можем доверять мы выглядит так:
По чем доверяют нам:
-rwxr-xr-x@ 1 aieremenko staff 2616 Aug 12 13:29 portal.gala-coral-prod.ptec.ca.pem -rwxr-xr-x@ 1 aieremenko staff 1684 Aug 12 13:29 portal.prod.crt.pem -rwxr-xr-x@ 1 aieremenko staff 1704 Aug 12 13:29 portal.prod.key.pem
У нас есть
javax.net.ssl.keyStore=keystore.jks
javax.net.ssl.trustStore=truststore.jts
Сначала для импорта в кистор мы должны обьединить ключ и сертификат в один p12 кистор. Делаем:
openssl pkcs12 -inkey portal.prod.key.pem -in portal.prod.crt.pem -export -out portal.prod.crt.p12
Вводим пароль от поставщика ключей и впринципе создаемся такой же для нового кистора и есть, теперь добавить из этого кистора в джавовский:
keytool -importkeystore -destkeystore keystore.jks -srckeystore portal.prod.crt.p12 -srcstoretype PKCS12 -srcalias 1 -destalias 'MY_ALIAS' -destkeypass PASSWD_TO_JKSВводим пароль к кистору p12 и к джевеемовскому - есть кистор добавлен к нам.
Теперь добавляем сертификат к трастору:
keytool -importcert -file portal.prd.ca.pem -alias MY_ALIAS -trustcacerts -keystore truststore.jtsподтверждаем, что мы доверяем этому сертификату.
Теперь, как отличить по принту(даже короткому) в хранилище ключей лежит то, что представляет нас, или то, чему доверяем мы.
Ключ кому можем доверять мы выглядит так:
$ keytool -list -keystore truststore.jts MY_ALIAS, Feb 28, 2018, trustedCertEntry, Certificate fingerprint (SHA1): 76:3B:FA:D5:ED:40:6E:DB:B5:49:B8:56:91:08:3D:3C:5C:E1:47:3D
По чем доверяют нам:
$ keytool -list -keystore keystore.jks MY_ALIAS, Feb 28, 2018, PrivateKeyEntry, Certificate fingerprint (SHA1): 8B:B5:5B:55:62:3E:F1:EB:19:0C:DD:49:D1:71:50:71:B9:9C:E6:61
вторник, 5 августа 2014 г.
суббота, 26 июля 2014 г.
Хорошая статья про то как узнать апи мобильных приложений
http://timrogers.uk/2014/07/12/discovering-private-apis-with-charles-app/?utm_source=hackernewsletter&utm_medium=email&utm_term=fav
Ярлыки:
Charles,
HTTP Proxy
среда, 23 июля 2014 г.
Подебажить MySQL запросы
1. Заходим под рутом в mysql shell
2. Находим где у нас будут писаться логи
3. В другой оболочке идем и например начинаем тейлить этот файл лога.
4. Включаем логирование
6. Не забываем отключить логирование, чтобы не заполнить себе диск.
2. Находим где у нас будут писаться логи
mysql> SHOW VARIABLES LIKE "general_log%";
+------------------+----------------------------+
| Variable_name | Value |
+------------------+----------------------------+
| general_log | OFF |
| general_log_file | /var/run/mysqld/mysqld.log |
+------------------+----------------------------+
3. В другой оболочке идем и например начинаем тейлить этот файл лога.
4. Включаем логирование
mysql> SET GLOBAL general_log = 'ON';
5. Наблюдаем за запросами, находим проблему, решаем.6. Не забываем отключить логирование, чтобы не заполнить себе диск.
mysql> SET GLOBAL general_log = 'OFF';
7. Также будет полезно почистить за собой
rm /var/run/mysqld/mysqld.log
Ярлыки:
Logs monitoring,
MySQL
четверг, 10 июля 2014 г.
Default MongoDB Ports
Default MongoDB Port
The following table lists the default ports used by MongoDB:
| Default Port | Description |
|---|---|
| 27017 | The default port for mongod and mongos instances. You can change this port with port or --port. |
| 27018 | The default port when running with --shardsvr runtime operation or the shardsvr value for the clusterRolesetting in a configuration file. |
| 27019 | The default port when running with --configsvr runtime operation or the configsvr value for the clusterRolesetting in a configuration file. |
| 28017 | The default port for the web status page. The web status page is always accessible at a port number that is 1000 greater than the port determined by port. |
Ярлыки:
MongoDB
MongoDB replication
В контексте MongoDB процедура репликации связана с понятие репликасет. Реплика сет это:
- группа нод, в которых одна является праймери, другие - секондари;
- приложение подключается к праймери, все изменения, которые приходят на праймери, дублицируются на секондари ноды;
- когда праймери падает, репликасет решает какая из секондари нод становится новой праймери, и приложение переподключается на нее, таким образом если быть более точным, то приложение подключается к репликесету, а уже репликасет решает к какой ноде полючить соединение;
- когда упавший праймери подымается, он уже становится одним из секондари и вступает в работу с записи всех изменений, который пришли в репликусет без него;
- минимальное количесвто нод в репликесете 3.
- группа нод, в которых одна является праймери, другие - секондари;
- приложение подключается к праймери, все изменения, которые приходят на праймери, дублицируются на секондари ноды;
- когда праймери падает, репликасет решает какая из секондари нод становится новой праймери, и приложение переподключается на нее, таким образом если быть более точным, то приложение подключается к репликесету, а уже репликасет решает к какой ноде полючить соединение;
- когда упавший праймери подымается, он уже становится одним из секондари и вступает в работу с записи всех изменений, который пришли в репликусет без него;
- минимальное количесвто нод в репликесете 3.
Ярлыки:
MongoDB
среда, 9 июля 2014 г.
Comparison Matrix
| Operation description | MongoClient Shell | NodeJs Driver | Java Driver | Python Driver |
|---|---|---|---|---|
| Подключение к базе | $ mongo dbname $ mongo 192.169.0.5/dbname $ mongo 192.169.0.5:9999/dbname $ mongo >use dbname | var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/m101'), function(err, db) {
if(err) throw err;
db
}
| import com.mongodb.DB;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
final MongoClient client = new MongoClient(new MongoClientURI("mongodb://localhost"));
final DB db = mongoClient.getDB("dbname");
| |
| Получение ссылки на коллекцию | >db.collectionName | var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/m101'), function(err, db) {
if(err) throw err;
var collection = db.collection('collectionName');
}
| import com.mongodb.DB;
import com.mongodb.DBCollection;
final DBCollection collection = db.getCollection("collectionName");
| |
| Выборка | >db.students.find({
$or: [
{ "resume.projects.3.months": {$lte: 3}},
{currentProjects: {$in: ["Pizza Commerce", "AdvNet"]}}
]
})
| var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/m101'), function(err, db) {
if(err) throw err;
/*
следующий подход для варианта, когда есть вероятность,
что полей может быть очень много и нам нужно обеспечить
отпускание потока ноды
*/
db.collection('students').find({
$or: [
{ "resume.projects.3.months": {$lte: 3}},
{currentProjects: {$in: ["Pizza Commerce", "AdvNet"]}}
]
}).each(function(err, doc){
console.log(doc);
});
/*
следующий подход для большинства случаев, где мы
перестраховываемся лимитированием от чрезмерного
количества результатов
*/
db.collection('students').find({
$or: [
{ "resume.projects.3.months": {$lte: 3}},
{currentProjects: {$in: ["Pizza Commerce", "AdvNet"]}}
]
}).sort({name: -1}).limit(5).toArray(function(err, items){
console.log(items);
});
}
| import com.mongodb.BasicDBObject;
import com.mongodb.DBCursor;
import java.util.List;
List<DBobject> posts;
BasicDBObject query = new BasicDBObject("tags", tag);
DBCursor cursor = postsCollection.find(query).sort(new BasicDBObject().append("date", -1)).limit(10);
try {
posts = cursor.toArray();
} finally {
cursor.close();
}
...OR...
/*Можно также поработать с курсором определенное время*/
while (cursor.hasNext()) {
posts.add(cursor.next());
}
| |
| Изменение конкретной записи | >var j = db.students.findOne() >j.name = "Tim" >delete j.surname >db.students.save(j) | |||
| Получение информации о протекании запроса | > db.students.findOne().explain() | var cursor = db.collection('students').findOne({a: 1});
cursor.explain(function(err, explain_output){
if(err) throw err;
console.log(explain_output);
});
| ||
| Явное указание какой именно индекс использовать в запросе | > db.students.findOne({x: 100, y: 200, z: "Some string value"}).hint({x: 1, y:1, z: 1})
| var cursor = db.collection('students').find({a: 1}, {},
{ 'hint': {$natural: 1}}
);
| ||
| Подключение к репликасету | Запустить несколько процессов в данном случае на одном хосте:user@localhost$ mkdir -p /data/rs1 /data/rs2 /data/rs3 user@localhost$ mongod --replSet m101 --logpath "1.log" --dbpath /data/rs1 --port 27017 --oplogSize 64 --fork --smallfiles user@localhost$ mongod --replSet m101 --logpath "2.log" --dbpath /data/rs2 --port 27018 --oplogSize 64 --smallfiles --fork user@localhost$ mongod --replSet m101 --logpath "3.log" --dbpath /data/rs3 --port 27019 --oplogSize 64 --smallfiles --fork Теперь соединить всех в одну репликусет через введение данных в процесс, который будет праймери: $ mongo --port 27018 < echo "config = { _id: "m101", members:[ \
{ _id : 0, host : "localhost:27017", priority:0, slaveDelay:5}, \
{ _id : 1, host : "localhost:27018"},\
{ _id : 2, host : "localhost:27019"} ] \
}; \
rs.initiate(config); \
rs.status(); \
"
Или так:
user@localhost$ mongo --port 27018
> rs.status()
> rs.initiate()
> rs.add("localhost:27017")
> rs.add("localhost:27019")
| var MongoClient = require('mongodb').MongoClient;
MongoClient.connect("mongodb://localhost:30001," +
"localhost:30002," +
"localhost:30003/course", function(err, db) {
...
});
|
Ярлыки:
MongoDB,
MongoDB Java driver,
MongoDB NodeJs driver
воскресенье, 6 июля 2014 г.
Разница между load и get
load(Entity.class, idVal) - кинет исключение, если в базе нет такой сущности с указанным айди.
get(Entity.class, idVal) - вернет налл, если в базе нет такой сущности с указанным айди.
get(Entity.class, idVal) - вернет налл, если в базе нет такой сущности с указанным айди.
Ярлыки:
Hibernate ORM
четверг, 3 июля 2014 г.
MongoDB Aggregation
С помощью этого функционала мы можем групировать по неким полям наши результаты запросов, при этом проводить некие исчисления над полями одной групы для получения общего результата для группы; преобразовывать; фильтровать; сортировать; обрезать; а также строить пайпланы для обработки уже обработанных результатов.
$project - reshape - 1 : 1
$match - filter - n : 1
$group - aggregate - n : 1
$sort - sort - 1 : 1
$skip - skips - n : 1
$limit - limits - n : 1
$unwind - normalize - 1 : n
$out - output - 1 : 1 (направить результат в другую колекции из базы)
$redact - на сколько я понял, какие-то ограничения по пользователю, то есть эта директива позволяет проверять поля на значения и включать их или нет в ответ, а к пользователю приложение привязывает некое значение полей и на основании этих полей происходит фильтрация.
$geoNear - поиск относительно места расположения, в результате возвращается сначала самое близкое место и в конце самое отдаленное.
Aggregation Pipeline
Collection -> $project -> $match -> $group -> $sort -> Result$project - reshape - 1 : 1
$match - filter - n : 1
$group - aggregate - n : 1
$sort - sort - 1 : 1
$skip - skips - n : 1
$limit - limits - n : 1
$unwind - normalize - 1 : n
$out - output - 1 : 1 (направить результат в другую колекции из базы)
$redact - на сколько я понял, какие-то ограничения по пользователю, то есть эта директива позволяет проверять поля на значения и включать их или нет в ответ, а к пользователю приложение привязывает некое значение полей и на основании этих полей происходит фильтрация.
$geoNear - поиск относительно места расположения, в результате возвращается сначала самое близкое место и в конце самое отдаленное.
Ярлыки:
MongoDB
воскресенье, 29 июня 2014 г.
MongoDB Indexes
Table scan in RDBM
Collection scan in MongoDB
Both are a death for performance
Theory of indexing:
We keep our keys sorted.
Indexes in Mongo db are OrderedList of Keys.
Мы знаем по каким полям мы часто делаем выборку, поэтому для таких полей мы создаем индексы.
Типы идексов в Mongo:
Single Field Indexes
A single field index only includes data from a single field of the documents in a collection. MongoDB supports single field indexes on fields at the top level of a document and on fields in sub-documents.
Compound Indexes
A compound index includes more than one field of the documents in a collection.
Multikey Indexes
A multikey index references an array and records a match if a query includes any value in the array.
Geospatial Indexes and Queries
Geospatial indexes support location-based searches on data that is stored as either GeoJSON objects or legacy coordinate pairs.
Text Indexes
Text indexes supports search of string content in documents.
Hashed Index
Hashed indexes maintain entries with hashes of the values of the indexed field.
Эта отсортированная структура сохраняется на диске и по ней мы намного быстрее найдем ссылку в последовательности полных записей колекции на диске.
Например мы создаем ключ|индекс на поля
name, hear_color, age
На диск у нас сохраняется отсортированый список имен, в каждой ячейке имени хранится отсортированный список цвета волос, а в каждой ячейке цвета волос хранятся отсортированные возраста.
А уже на каждой ячейке возраста хранятся ссылки на целые записи всей колекции.
Collection scan in MongoDB
Both are a death for performance
Theory of indexing:
We keep our keys sorted.
Indexes in Mongo db are OrderedList of Keys.
Мы знаем по каким полям мы часто делаем выборку, поэтому для таких полей мы создаем индексы.
Типы идексов в Mongo:
Эта отсортированная структура сохраняется на диске и по ней мы намного быстрее найдем ссылку в последовательности полных записей колекции на диске.
Например мы создаем ключ|индекс на поля
name, hear_color, age
На диск у нас сохраняется отсортированый список имен, в каждой ячейке имени хранится отсортированный список цвета волос, а в каждой ячейке цвета волос хранятся отсортированные возраста.
А уже на каждой ячейке возраста хранятся ссылки на целые записи всей колекции.
Ярлыки:
MongoDB
Logging and Profiling
Логирование медленных запросов
Все логи который больше 100 мс считаются медленными и поэтому логируются монго.Profiler
Пишутся данные в колекцию system.profile
Существуют три уровня/режима
0 - Off
1 - Log my slow queries
2 - Log all my queries
Можно сразу запустить mongod в указанном режиме
> mongod -dbpath /usr/local/var/mongodb --profile 1 --slowms 2Мы указали режим и что меделнными мы считаем запросы от 2-х милисекунд
И вот мы выполнили медленный запрос в базу, и так мы его найдем в наших логах:
> db.system.profile.find().pretty()
Обычно там логов много и не редко из разных баз и с разных колекций, чтобы поискать можно воспользоваться следующими командами:
> db.system.profile.find({ns:/interestedDb.interestedColl/}).sort({ts: 1}).pretty()
Так мы ищем только интересующую нас базы и колекцию в ней, и сортируем по времени их создания
Или только какие-то очень медленные с любой колекции и базы:
> db.system.profile.find({millis: {$gt: 500}}).sort({ts: 1}).pretty()
Узнать поточный режим профайлера:
> db.getProfilingLevel() 1Узнать что у нас логируется и его дополнительный параметр(например у медленных, что считать медленным):
> db.getProfilingStatus()
{"was": 1, "slowms": 2}
Установка в уже запущенном монго:
> db.setProfilingLevel(1, 4)
{"was": 1, "slowms": 4, "ok": 1}
Mongotop
Аналог юниксового top.При запуске мы указываем параметром с каким диапазоном времени делать просмотр процессов в запащенном монгод.
Mongostat
Аналог юниксового iostat.
Ярлыки:
MongoDB
суббота, 28 июня 2014 г.
пятница, 27 июня 2014 г.
Как добавить сервис к запуску со стартом системы
ln -sfv /usr/local/opt/rabbitmq/homebrew.mxcl.rabbitmq.plist ~/Library/LaunchAgents
Запустить новосозданную ссылку сейчас:
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.rabbitmq.plist
Ярлыки:
mac os x
четверг, 26 июня 2014 г.
Изучение эфективности запросов, занимаемой памати и другое
Изучение того как был обработан запрос
для этого есть метод курсора .explain(), он выводит следующие пункты:cursor - если поиск прошел без использования индекса мы увидим DefaultCursor, если с индексом, то мы увидим что-нибудь вроде "BtreeCursor indexfield1_1_indexfield2_1_...indexfieldN_1"
isMultyKey - тру, если в ключ входит поле со значением массива.
n - количество документов, которые вернулись в результате запроса.
nscannedObjects - количество просканированных документов для получения результата запроса.
nscanned - это же поле количество просканированных индексов, если у нас поиск индексный, или документов, если результат был получен без сканирования индексов.
indexOnly - может ли запрос быть удовлетворен только идексом
indexBounds - если у нас поиск идексный, то для каждого поля индекса(для сборного их несколько, для несборного - один) показываются границы сколько минимально может быть просканировано индексов, и сколько максимально -- пока не понятно как это я видет эти два значения равными???
millis - время выполнения запроса в милисекундах.
Когда мы запрашиваем компонентный запрос, например выборка и потом сортировка, то в этой ситуации даже если под выборку не попадет индекс, он может пригодиться в сортировке. Например со следующим индексом, следующие запросы будут использовать индекс:
< db.foo.ensureIndex({a:1, b:1, c:1})
< db.foo.find({a:3})
< db.foo.find({c:1}).sort({a:1, b:1})
Но не:
< db.foo.find({b:3, c:4})
< db.foo.find({c:1}).sort({a:-1, b:1})
Как узнать размер
Размер колекции на диске:< db.collection.stats()
< db.foo.totalIndexSize()
Ярлыки:
MongoDB
вторник, 10 июня 2014 г.
Динамика состояния DBCollection
Мы получаем колекцию:
Это именно состояние колекции, а не курсор по ней. С него мы получаем информацию о состоянии.
То есть если мы получили ссылку на колекцию и посмотрели например к-во документов в ней:
А потом например удалили некие из нее элементы:
final DBCollection grades = db.getCollection("grades");
Это именно состояние колекции, а не курсор по ней. С него мы получаем информацию о состоянии.
То есть если мы получили ссылку на колекцию и посмотрели например к-во документов в ней:
System.out.println(grades.count());
800;
А потом например удалили некие из нее элементы:
grades.remove(new BasicDBObject(
"_id",
new BasicDBObject(
"$in",
forDeleteList//List
)
));
То это не означает что нам нужно делать новую ссылку на колекцию, повторное обращение к методу количества даст новый результат:System.out.println(grades.count());
600;
Ярлыки:
MongoDB,
MongoDB Java driver
понедельник, 9 июня 2014 г.
Spring Data JPA
Этот модуль фреймворка Spring помогает избежать шаблонного кода работы с ЭнтитиМенеджера.
И так Spring Data JPA:
- A wrapper for JPA
- Need to know JPA before you can use Spring Data JPA
- Replaces our Repository Tier
- Extremely powerful and eliminates boiler plate code
- Can be extended for additional functionality
И так Spring Data JPA:
- A wrapper for JPA
- Need to know JPA before you can use Spring Data JPA
- Replaces our Repository Tier
- Extremely powerful and eliminates boiler plate code
- Can be extended for additional functionality
Ярлыки:
JPA,
Spring Data,
Spring Data JPA
воскресенье, 8 июня 2014 г.
NamedQueries
- Cleaner than adhoc JPQL
- Not required, but focuses on the domain
- Named parameters
- Not required, but focuses on the domain
- Named parameters
@NamedQueries({ @NamedQuery(name=Goal.FIND_GOAL_REPORTS,
query="Select new com.domain.model.GoalReport(g.minutes, e.minutes, e.activity) " +
"from Goal g, Exercise e where g.id = e.goal.id"
)})
Ярлыки:
Hibernate ORM,
JPA,
Spring Data,
Spring ORM
Projection
- Great way to present objects to the UI
- Objects added using JPQL syntax
- Projection Objects can be JPA Entities
- Need a constructor for the projection
- Objects added using JPQL syntax
- Projection Objects can be JPA Entities
- Need a constructor for the projection
String jpql="Select new com.domain.model.GoalReport(g.minutes, e.minutes, e.activity) " + "from Goal g, Exercise e where g.id = e.goal.id";
Ярлыки:
Hibernate ORM,
JPA,
JPQL,
Spring ORM
Самая распространенная ошибка в приложениях SpringMVC-Hibernate/JPA
Это експешины связаны с ленивой подгрузкой из базы зависимостей.
Суть проблемы состоит вот в чем: когда запрос приходит от браузера то его обработка проходит несколько фаз.
На фазе сервисов создается сессия энтити менеджера здесь происходят всякие транзакционные штуки и обращения в базу, после чего обычно сессия закрывается и запрос обрабатывается дальше.
Дальше идет обработка вьюшки и вот здесь происходит проблема - одна из вьюшек обращается с методу модели, который пытается сделать выборку из базы, а поскольку сессия уже закрыта мы и получает иксепшин.
Проблема решается вот таким веб-фильтром OpenEntityManagerInViewFilter, который обеспечивает жизнь сессии ЭнтитиМенеджера на все время обработки веб-запроса:
Суть проблемы состоит вот в чем: когда запрос приходит от браузера то его обработка проходит несколько фаз.
На фазе сервисов создается сессия энтити менеджера здесь происходят всякие транзакционные штуки и обращения в базу, после чего обычно сессия закрывается и запрос обрабатывается дальше.
Дальше идет обработка вьюшки и вот здесь происходит проблема - одна из вьюшек обращается с методу модели, который пытается сделать выборку из базы, а поскольку сессия уже закрыта мы и получает иксепшин.
Проблема решается вот таким веб-фильтром OpenEntityManagerInViewFilter, который обеспечивает жизнь сессии ЭнтитиМенеджера на все время обработки веб-запроса:
<filter> <filter-name>Spring OpenEntityManagerInViewFilter</filter-name> <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>Spring OpenEntityManagerInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Ярлыки:
Hibernate ORM,
Spring MVC,
Spring ORM
Join Types and Fetch Type
4 join types:
- @OneToOne
- @OneToMany
- @ManyToOne
- @ManyToMany
Can be used in various configurations:
- Unidirectional
- Bidirectional
- Cascade
Fetch Types:
- Lazy - Queries the database when that property is called
- Eager - Queries the database when the object is originally created
Хибернейт имеет ограничение - он позвояет иметь только две колекции на объект, которые могут быть "нетерпеливо" выбраны в объект.
- @OneToOne
- @OneToMany
- @ManyToOne
- @ManyToMany
Can be used in various configurations:
- Unidirectional
- Bidirectional
- Cascade
Fetch Types:
- Lazy - Queries the database when that property is called
- Eager - Queries the database when the object is originally created
Хибернейт имеет ограничение - он позвояет иметь только две колекции на объект, которые могут быть "нетерпеливо" выбраны в объект.
@OneToMany(mappedBy="goal", cascade=CascadeType.ALL, fetch=FetchType.LAZY) private Listexercise = new ArrayList<>();
Ярлыки:
Hibernate ORM,
Spring ORM
суббота, 7 июня 2014 г.
Fat Arrow
Этот способ позволяет нам ссылаться на this из класса а не контекста более глубокого.
Например:
Именно для такого случая придумали Fat Arrow(=>) чтобы указать, что нас интересует контекст инстанции класса.
Например:
class Coffee
constructor: (@name, @strength=1, @inventory=0) ->
pourClick: ->
$("#pour-#{@name}").click (event) ->
if @inventory isnt 0
@inventory -= 1
alert "Poured a cup of #{name}"
В даном примере мы хотим внутри хендлера клика обратиться к @inventory (this.inventory) именно инстанции класса, но в данном контексе this будет представлять кнопку.Именно для такого случая придумали Fat Arrow(=>) чтобы указать, что нас интересует контекст инстанции класса.
class Coffee
constructor: (@name, @strength=1, @inventory=0) ->
pourClick: ->
$("#pour-#{@name}").click (event) =>
if @inventory isnt 0
@inventory -= 1
alert "Poured a cup of #{name}"
Ярлыки:
CoffeeScript,
Javascript
пятница, 6 июня 2014 г.
Splat Arguments
Фишка из Ruby, которая помогает в работе с переменным количеством аргументов.
With a trailing argument:
loadTruck = (firstDibs, secondDibs, tooSlow...) ->
truck:
driversSeat: firstDibs
passengerSeat: secondDibs
trunkBed: tooSlow
loadTruck("Amanda", "Joel")
# => { truck: { driversSeat: "Amanda", passengerSeat: "Joel", trunkBed: [] } }
loadTruck("Amanda", "Joel", "Bob", "Mary", "Phillip")
# => { truck: { driversSeat: "Amanda", passengerSeat: "Joel", trunkBed: ["Bob", "Mary", "Phillip"] } }
With a trailing argument:
loadTruck = (firstDibs, secondDibs, tooSlow..., leftAtHome) ->
truck:
driversSeat: firstDibs
passengerSeat: secondDibs
trunkBed: tooSlow
taxi:
passengerSeat: leftAtHome
loadTruck("Amanda", "Joel", "Bob", "Mary", "Phillip", "Austin")
# => { truck: { driversSeat: 'Amanda', passengerSeat: 'Joel', trunkBed: [ 'Bob', 'Mary', 'Phillip' ] }, taxi: { passengerSeat: 'Austin' } }
loadTruck("Amanda")
# => { truck: { driversSeat: "Amanda", passengerSeat: undefined, trunkBed: [] }, taxi: undefined }
Ярлыки:
CoffeeScript,
Javascript
среда, 4 июня 2014 г.
MongoDB mongoimport tool
Утилита для импорта документов в виде джейсона в указанную базу и колекцию.
Формат команды:
mongoimport -d <DATABASE> -c <COLLECTION> < FILE.js
Нужно обратить внимание, что формат файла не json - внутри не массив обьектов, а строки обьектов - можно понять что каждаю строка какбы инсертится в колекцию.
Формат команды:
mongoimport -d <DATABASE> -c <COLLECTION> < FILE.js
Нужно обратить внимание, что формат файла не json - внутри не массив обьектов, а строки обьектов - можно понять что каждаю строка какбы инсертится в колекцию.
Ярлыки:
MongoDB,
MongoDB administration
Подключение Java движка шаблонов Freemarker в приложение
import freemarker.template.Configuration;
import freemarker.template.Template;
public class MyApp {
public static void main(String[] args) throws Exception {
Configuration cfg = new Configuration();
cfg.setClassForTemplateLoading(MyApp.class, "/");//где искать шаблоны фримаркера, мы указываем что искать в корне класспаза
Template helloTmplt = cfg.getTemplate("hello.ftl");
StringWriter writer = new StringWriter();
Map helloMap = new HashMap();
helloMap.put("name", "Freemarker");
helloTmplt.process(helloMap, writer);
System.out.println(writer);
}
}
А где-то в recources/hello.ftl:
<html>
<head>
<title>Welcome!</title>
</head>
<body>
<h1>Hello ${name}</h1>
</body>
</html>
Ярлыки:
Freemarker,
Templates egines
MongoDB. What is it?
Is:
- NoSQL;
- Document Store (Document Database - key/value pairs, lists are also able to be used);
- Schemaless Database (has dynamic schema);
No:
- joins;
- transactions;
- sql.
Basic usage of mongo client tool:
> db // посмотреть имя выбраной поточной базы данных
> show dbs // показать имена доступных баз данных
> use mydbname // выбрать базу данных
> show collections // показать доступный коллекции документов в поточной базе данных
mongorestore path/to/dir/with/dumps ## залить в работающую монгу дампы из директории
- NoSQL;
- Document Store (Document Database - key/value pairs, lists are also able to be used);
- Schemaless Database (has dynamic schema);
No:
- joins;
- transactions;
- sql.
Basic usage of mongo client tool:
> db // посмотреть имя выбраной поточной базы данных
> show dbs // показать имена доступных баз данных
> use mydbname // выбрать базу данных
> show collections // показать доступный коллекции документов в поточной базе данных
mongorestore path/to/dir/with/dumps ## залить в работающую монгу дампы из директории
понедельник, 2 июня 2014 г.
jQuery Promises
$.ajax возвращает промис обьект, этот патерн делает код более читабельным.
Кроме того, если объект который приходит с удаленки сложной структуры, а нам из нее необходима только некая часть, мы можем руками создать обьект промиса и запонить его в колбеках аякса только нужными частями ответа, так мы можем написать максимально простой обработчик в промисе, но приэтом по закону мировоздания более сложными будут опции аякса:)
var promise = $.ajax('/url',{...});//опции без колбеков success&error
promise.done(function(args){});//callback on success
promise.fail(function(args){});//callback on error
Кроме того, если объект который приходит с удаленки сложной структуры, а нам из нее необходима только некая часть, мы можем руками создать обьект промиса и запонить его в колбеках аякса только нужными частями ответа, так мы можем написать максимально простой обработчик в промисе, но приэтом по закону мировоздания более сложными будут опции аякса:)
var promise = $.Deferred();
$.ajax('/weather', {
data: {q: location},
success: function(result){
promise.resolve(result.weather);
},
error: function(){
var error = 'invalid location';
promise.reject(error);
}
});
promise.done(function(args){});//callback on success
promise.fail(function(args){});//callback on error
ajax запросы заканчиваются в разное время, бывают моменты, когда процессинг ответов на разные запросы нужно произвести в одно и тоже время. Для этого ипользуются $.when & $.then
$.when(
Weather.today(loc),
City.find(loc)
).then(function(weatherResult, cityResult){
resultsDiv.append(cityResult);
resultsDiv.append(weatherResult);
Ярлыки:
Javascript,
jQuery
jQuery прояснение моментов
Axaj
$.ajax('/url/to/server/script', {
...
dataType: 'json', // сразу попытаться распарсить ответ как json(по умолчанию jQuery делает анализ)
contentType: 'application/json', //jQuery устанавливает соответствующий хттп заголовок, на основании которого сервер может принимать решение в каком формате отвечать
context: someWidgetEl, //в колбеках this будет ссылаться на указанный обьект
data: $('form').serialize(), //так мы собираем значение полей с формы в джейсон
});
Ярлыки:
Javascript,
jQuery
четверг, 29 мая 2014 г.
Способ ручного мониторинга логов
Искал как бы избавиться от навязчивых длинных ексепшинов в логах с сертификатами, когда меня интересовали другие строки не такие длинные.
Думал проблему нужно решать через выключения из логов ненужных ексепшинов, парился, но понял, что стектрейс имеет в себе переносы строк, поэтому нужно просто выводить корни, и это значительно решает проблему даже без вырезания надоедливых логов:
Вот что получилось:
Ну а где-то выключение все же полезно:
Думал проблему нужно решать через выключения из логов ненужных ексепшинов, парился, но понял, что стектрейс имеет в себе переносы строк, поэтому нужно просто выводить корни, и это значительно решает проблему даже без вырезания надоедливых логов:
Вот что получилось:
tail -f logs/app.log \ | egrep -A3 "^(DEBUG|INFO|WARN|ERROR)"
Ну а где-то выключение все же полезно:
tail -f ums.log \ | egrep -v "^INFO.*NotifyBalanceChange" \ | egrep -v "^INFO.*Ping"Вместо egrep можно пользоваться grep -E
Ярлыки:
Linux,
Logs monitoring,
Unix
среда, 28 мая 2014 г.
Подключение JPA настроек в приложении Spring Web MVC
Для этого нам нужно в web.xml подключить лисенер и предоставить для него context-param с именем contextConfigLocation, в нем должен находится путь к файлу настрое контекста, вринципе любого, но в нашем даном конкретном случае JPA
Этот файл содержит:
- EntityManagerFactory;
- JPA Vendor;
- JPA Properties;
- Transaction Manager;
- Annotation configuration;
- Datasource configuration or lookup.
EntityManagerFactory представлен в spring классом LocalContainerEntityManagerFactoryBean:
- класс находится в spring-orm.jar;
- представляет собой наш персистенс модуль;
- впрыскивает датасорс, если такой не определен в нашем персистенс модуле;
- поставляет специфические JPA свойства
Еще такой прикол в SpringMVC-Hibernate приложении. Чтобы у нас все работало гладко и с транзакциями, мы должны сканировать пакеты репозиториев, моделей и сервисов в jpaContext.xml. Потому что аннотация @Transactional, которой помечаются методы сервисов, должна именно обрабатываться бинами из контекста jpaContext.xml. Хоть на сервисы есть ссылки и с контроллеров, но как показывает практитка указав для сканирования только пакет с контроллерами в servlet-context.xml все работает - контейнер предоставляет сервисы из контекста jpaContext.xml, но вот наоборот не работает.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:jpaContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Разберемся за что отвечает jpaContext.xml, который мы используем всместо persistence.xml. Его имя не обязно быть таким как мы его определили в web.xml - оно будет таким как мы его определим, но по смыслу оно таково как мы его сейчас назвали.
Этот файл содержит:
- EntityManagerFactory;
- JPA Vendor;
- JPA Properties;
- Transaction Manager;
- Annotation configuration;
- Datasource configuration or lookup.
EntityManagerFactory представлен в spring классом LocalContainerEntityManagerFactoryBean:
- класс находится в spring-orm.jar;
- представляет собой наш персистенс модуль;
- впрыскивает датасорс, если такой не определен в нашем персистенс модуле;
- поставляет специфические JPA свойства
Еще такой прикол в SpringMVC-Hibernate приложении. Чтобы у нас все работало гладко и с транзакциями, мы должны сканировать пакеты репозиториев, моделей и сервисов в jpaContext.xml. Потому что аннотация @Transactional, которой помечаются методы сервисов, должна именно обрабатываться бинами из контекста jpaContext.xml. Хоть на сервисы есть ссылки и с контроллеров, но как показывает практитка указав для сканирования только пакет с контроллерами в servlet-context.xml все работает - контейнер предоставляет сервисы из контекста jpaContext.xml, но вот наоборот не работает.
Ярлыки:
JPA,
Spring MVC
persistence.xml
persistence.xml - в этом файле настраивается фреймворк JPA, определяются следующие настройки:
- Datasource;
- Allowed Operations;
- Caching;
- Etc.
Но если мы работаем в связке со Spring, мы оставляем этот файл пустым и используем файлы конфигурации спринга. Почему так?
- можно перегружать настройки для конкретного энваеренмента;
- легче проводить тестирование;
- можно вспрыскивать в другие ресурсы.
Но не нужно забывать, что мы все еще нуждаемся в этом файле настроек, хоть и пустой.
- Datasource;
- Allowed Operations;
- Caching;
- Etc.
Но если мы работаем в связке со Spring, мы оставляем этот файл пустым и используем файлы конфигурации спринга. Почему так?
- можно перегружать настройки для конкретного энваеренмента;
- легче проводить тестирование;
- можно вспрыскивать в другие ресурсы.
Но не нужно забывать, что мы все еще нуждаемся в этом файле настроек, хоть и пустой.
Ярлыки:
JPA
вторник, 27 мая 2014 г.
Блин! Нафиг я делал этот мердж? - Отмена мерджа с конфликтами.
После версии включительно 1.7.4
До версии 1.7.4:
До версии 1.6.2. Оно по сути делает то же самое, что и команда выше:
Теперь ты понимаешь что пулиться нудно было так, что ты и делаешь:
git pull -Xtheirs
Если же мерджим локальные бранчи то:
git merge --strategy-option theirs branch_name
git merge --abort
До версии 1.7.4:
git reset --merge
До версии 1.6.2. Оно по сути делает то же самое, что и команда выше:
git reset --hard
Теперь ты понимаешь что пулиться нудно было так, что ты и делаешь:
git pull -Xtheirs
Если же мерджим локальные бранчи то:
git merge --strategy-option theirs branch_name
Ярлыки:
git
понедельник, 26 мая 2014 г.
Mac OS X. Создать симлинку с /home на /Users
EDITOR=nano sudo -e /etc/auto_master
# add a "#" at the start of the line beginning with /home
# save changes
sudo automount -cv
sudo ln -s /Users /home
Ярлыки:
mac os x
mac os git by homebrew
Andriis-MacBook-Pro-2:~ aieremenko$ brew install git
==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/git-1.9.3.mavericks.bottle.1.tar.gz
######################################################################## 100.0%
==> Pouring git-1.9.3.mavericks.bottle.1.tar.gz
==> Caveats
The OS X keychain credential helper has been installed to:
/usr/local/bin/git-credential-osxkeychain
The 'contrib' directory has been installed to:
/usr/local/share/git-core/contrib
Bash completion has been installed to:
/usr/local/etc/bash_completion.d
zsh completion has been installed to:
/usr/local/share/zsh/site-functions
==> Summary
🍺 /usr/local/Cellar/git/1.9.3: 1325 files, 31M
пятница, 23 мая 2014 г.
Angularjs - общий конспект
- Directives - HTML annotations that trigger Javascript behaviors
- Modules - Where our application components live
- Controllers - Where we add application behavior
- Expressions - ow values get displayed within the page
Ярлыки:
Angularjs,
Javascript
среда, 7 мая 2014 г.
liquibase, сброс чексумм
Иногда мы замечаем, что форматирование какого-нибудь ченджсета желает быть учучшенным, но исправить его означает, вызвать панику liquibase и не позволить запустить приложение, потому что это будет выглядеть какбудто изменение в уже историческом изменении.
Чтобы обнулить чексуммы, чтобы изменения уже в примененных "изменениях базы" были восприняты, как тоже самое, но с улученным форматированием (то есть без повторного вызова указанных ченджсетов), нужно подправить записи в таблице логирования liquibase:
Чтобы обнулить чексуммы, чтобы изменения уже в примененных "изменениях базы" были восприняты, как тоже самое, но с улученным форматированием (то есть без повторного вызова указанных ченджсетов), нужно подправить записи в таблице логирования liquibase:
update DATABASECHANGELOG set MD5SUM=null;
Ярлыки:
liquibase
четверг, 24 апреля 2014 г.
Ant. запустить скрипт в зависимости от операционки
<target name="prepare-project">
<if>
<os family="unix" />
<then>
<echo>is unix........</echo>
<exec dir="./scripts" executable="/bin/sh">
<arg line="-c ./prepare-project.sh"/>
</exec>
</then>
<elseif>
<os family="windows" />
<then>
<echo>is windows........</echo>
<exec dir="./scripts" executable="/bin/sh">
<arg line="-c ./prepare-project.sh"/>
</exec>
</then>
</elseif>
</if>
</target>
Ярлыки:
Ant
Подписаться на:
Сообщения (Atom)


