środa, maja 08, 2013
Poczta Polska - ostatni bastion socjalizmu
UKE zbadał terminowość doręczania przesyłek. Nadal jest źle, ale trochę lepiej. Są takie przypadki, że na zwykły list czeka się 6 dni albo dłużej (priorytetowy 4+).
wtorek, kwietnia 30, 2013
How get real JDBC connection in BW Java
com.tibco.plugin.java.JavaConnectionAccessor ac = (com.tibco.plugin.java.JavaConnectionAccessor) conn;
java.sql.Connection wrappedConn = ac.getDBConnection();
java.sql.PreparedStatement ps = null;
java.sql.Clob val_binary = null;
try {
java.lang.reflect.Field connField = null;
for (java.lang.reflect.Field f : wrappedConn.getClass().getDeclaredFields()) {
if (java.sql.Connection.class.isAssignableFrom(f.getType()))
connField = f;
}
if (connField==null)
throw new RuntimeException("Cannot get original JDBC connection from Tibco Wrapper");
connField.setAccessible(true);
java.sql.Connection oraConn = (java.sql.Connection) connField.get(wrappedConn);
/* do the work */
}
catch (java.sql.SQLException sqle) {
sqle.printStackTrace();
ac.releaseConnection(sqle);
wrappedConn = null;
throw sqle;
}
catch (Throwable t) {
t.printStackTrace();
ac.releaseConnection();
wrappedConn = null;
throw new RuntimeException("Unexpected Java code error", t);
}
finally {
if (ps!=null) {
try {
ps.close();
}
catch (Exception e) {}
}
if (wrappedConn!=null)
ac.releaseConnection();
}
java.sql.Connection wrappedConn = ac.getDBConnection();
java.sql.PreparedStatement ps = null;
java.sql.Clob val_binary = null;
try {
java.lang.reflect.Field connField = null;
for (java.lang.reflect.Field f : wrappedConn.getClass().getDeclaredFields()) {
if (java.sql.Connection.class.isAssignableFrom(f.getType()))
connField = f;
}
if (connField==null)
throw new RuntimeException("Cannot get original JDBC connection from Tibco Wrapper");
connField.setAccessible(true);
java.sql.Connection oraConn = (java.sql.Connection) connField.get(wrappedConn);
/* do the work */
}
catch (java.sql.SQLException sqle) {
sqle.printStackTrace();
ac.releaseConnection(sqle);
wrappedConn = null;
throw sqle;
}
catch (Throwable t) {
t.printStackTrace();
ac.releaseConnection();
wrappedConn = null;
throw new RuntimeException("Unexpected Java code error", t);
}
finally {
if (ps!=null) {
try {
ps.close();
}
catch (Exception e) {}
}
if (wrappedConn!=null)
ac.releaseConnection();
}
niedziela, kwietnia 28, 2013
Java file names encoding
public static void main(String[] args) throws IOException {
Path p1 = Files.newDirectoryStream(Paths.get("/home/user/jdk/test"))
.iterator().next();
System.out.println("API 1.7: "+p1.toUri().getPath());
System.out.println("API 1.7: "+p1.toFile().getAbsolutePath());
String p2 = new java.io.File("/home/user/jdk/test").list()[0];
System.out.println("API 1.4: "+p2);
}
user@user-Aspire-4530:~/workspace/TestApp/bin$ LC_ALL="pl_PL.cp1250" java -Dfile.encoding=utf8 TestApp
API 1.7: /home/user/jdk/test/gżegżółka-ąęćśń
API 1.7: /home/user/jdk/test/gżegżółka-ąęćśń
API 1.4: g��eg������ka-����������
user@user-Aspire-4530:~/workspace/TestApp/bin$ LC_ALL="pl_PL.cp1250" java -Dfile.encoding=cp1250 TestApp
API 1.7: /home/user/jdk/test/g�eg���ka-����
API 1.7: /home/user/jdk/test/gżegżółka-ąęćśń
API 1.4: g??eg??????ka-??????????
user@user-Aspire-4530:~/workspace/TestApp/bin$ LC_ALL="pl_PL.utf-8" java -Dfile.encoding=cp1250 TestApp
API 1.7: /home/user/jdk/test/g�eg���ka-����
API 1.7: /home/user/jdk/test/gżegżółka-ąęćśń
API 1.4: g�eg���ka-����
user@user-Aspire-4530:~/workspace/TestApp/bin$ LC_ALL="en_US" java -Dfile.encoding=utf8 TestApp
API 1.7: /home/user/jdk/test/gżegżółka-ąęćśń
API 1.7: /home/user/jdk/test/gżegżółka-ąęćśń
API 1.4: g��eg������ka-����������
user@user-Aspire-4530:~/workspace/TestApp/bin$ LC_ALL="en_US" java TestApp
API 1.7: /home/user/jdk/test/g?eg???ka-?????
API 1.7: /home/user/jdk/test/g??eg??????ka-??????????
API 1.4: g??eg??????ka-??????????
user@user-Aspire-4530:~/workspace/TestApp/bin$ LC_ALL="pl_PL.utf8" java -Dfile.encoding=utf8 TestApp
API 1.7: /home/user/jdk/test/gżegżółka-ąęćśń
API 1.7: /home/user/jdk/test/gżegżółka-ąęćśń
API 1.4: gżegżółka-ąęćśń
Path p1 = Files.newDirectoryStream(Paths.get("/home/user/jdk/test"))
.iterator().next();
System.out.println("API 1.7: "+p1.toUri().getPath());
System.out.println("API 1.7: "+p1.toFile().getAbsolutePath());
String p2 = new java.io.File("/home/user/jdk/test").list()[0];
System.out.println("API 1.4: "+p2);
}
user@user-Aspire-4530:~/workspace/TestApp/bin$ LC_ALL="pl_PL.cp1250" java -Dfile.encoding=utf8 TestApp
API 1.7: /home/user/jdk/test/gżegżółka-ąęćśń
API 1.7: /home/user/jdk/test/gżegżółka-ąęćśń
API 1.4: g��eg������ka-����������
user@user-Aspire-4530:~/workspace/TestApp/bin$ LC_ALL="pl_PL.cp1250" java -Dfile.encoding=cp1250 TestApp
API 1.7: /home/user/jdk/test/g�eg���ka-����
API 1.7: /home/user/jdk/test/gżegżółka-ąęćśń
API 1.4: g??eg??????ka-??????????
user@user-Aspire-4530:~/workspace/TestApp/bin$ LC_ALL="pl_PL.utf-8" java -Dfile.encoding=cp1250 TestApp
API 1.7: /home/user/jdk/test/g�eg���ka-����
API 1.7: /home/user/jdk/test/gżegżółka-ąęćśń
API 1.4: g�eg���ka-����
user@user-Aspire-4530:~/workspace/TestApp/bin$ LC_ALL="en_US" java -Dfile.encoding=utf8 TestApp
API 1.7: /home/user/jdk/test/gżegżółka-ąęćśń
API 1.7: /home/user/jdk/test/gżegżółka-ąęćśń
API 1.4: g��eg������ka-����������
user@user-Aspire-4530:~/workspace/TestApp/bin$ LC_ALL="en_US" java TestApp
API 1.7: /home/user/jdk/test/g?eg???ka-?????
API 1.7: /home/user/jdk/test/g??eg??????ka-??????????
API 1.4: g??eg??????ka-??????????
user@user-Aspire-4530:~/workspace/TestApp/bin$ LC_ALL="pl_PL.utf8" java -Dfile.encoding=utf8 TestApp
API 1.7: /home/user/jdk/test/gżegżółka-ąęćśń
API 1.7: /home/user/jdk/test/gżegżółka-ąęćśń
API 1.4: gżegżółka-ąęćśń
Why there are differences?
sun.nio.fs.UnixDirectoryStreamIterator creates String from bytes with default JVM encoding:
private Path readNextEntry() {
assert Thread.holdsLock(this);
for (;;) {
byte[] nameAsBytes = null;
// prevent close while reading
readLock().lock();
try {
if (isOpen()) {
nameAsBytes = readdir(dp);
}
} catch (UnixException x) {
IOException ioe = x.asIOException(dir);
throw new DirectoryIteratorException( ioe);
} finally {
readLock().unlock();
}
...
File.list() is a native C/C++ method (suprise!):
JNIEXPORT jobjectArray JNICALL
JNIEXPORT jobjectArray JNICALL
Java_java_io_UnixFileSystem_ list(JNIEnv *env, jobject this,
jobject file)
{
DIR *dir = NULL;
struct dirent64 *ptr;
struct dirent64 *result;
int len, maxlen;
jobjectArray rv, old;
WITH_FIELD_PLATFORM_STRING( env, file, ids.path, path) {
dir = opendir(path);
} END_PLATFORM_STRING(env, path);
if (dir == NULL) return NULL;
ptr = malloc(sizeof(struct dirent64) + (PATH_MAX + 1));
if (ptr == NULL) {
JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
closedir(dir);
return NULL;
}
/* Allocate an initial String array */
len = 0;
maxlen = 16;
rv = (*env)->NewObjectArray(env, maxlen, JNU_ClassString(env), NULL);
if (rv == NULL) goto error;
/* Scan the directory */
while ((readdir64_r(dir, ptr, &result) == 0) && (result != NULL)) {
jstring name;
if (!strcmp(ptr->d_name, ".") || !strcmp(ptr->d_name, ".."))
continue;
if (len == maxlen) {
old = rv;
rv = (*env)->NewObjectArray(env, maxlen <<= 1,
JNU_ClassString(env), NULL);
if (rv == NULL) goto error;
if (JNU_CopyObjectArray(env, rv, old, len) < 0) goto error;
(*env)->DeleteLocalRef(env, old);
}
name = JNU_NewStringPlatform(env, ptr->d_name);
...
JNIEXPORT jstring JNICALL
JNU_NewStringPlatform(JNIEnv *env, const char *str)
{
jstring result;
result = nativeNewStringPlatform(env, str);
if (result == NULL) {
jbyteArray hab = 0;
int len;
if (fastEncoding == NO_ENCODING_YET)
initializeEncoding(env);
if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET))
return newString8859_1(env, str);
if (fastEncoding == FAST_646_US)
return newString646_US(env, str);
if (fastEncoding == FAST_CP1252)
return newStringCp1252(env, str);
if ((*env)->EnsureLocalCapacity(env, 2) < 0)
return NULL;
len = (int)strlen(str);
hab = (*env)->NewByteArray(env, len);
if (hab != 0) {
(*env)->SetByteArrayRegion(env, hab, 0, len, (jbyte *)str);
if (jnuEncodingSupported(env)) {
result = (*env)->NewObject(env, JNU_ClassString(env),
String_init_ID, hab, jnuEncoding);
} else {
/*If the encoding specified in sun.jnu.encoding is not endorsed
by "Charset.isSupported" we have to fall back to use String(byte[])
explicitly here without specifying the encoding name, in which the
StringCoding class will pickup the iso-8859-1 as the fallback
converter for us.
*/
jmethodID mid = (*env)->GetMethodID(env, JNU_ClassString(env),
"", "([B)V");
result = (*env)->NewObject(env, JNU_ClassString(env), mid, hab);
}
(*env)->DeleteLocalRef(env, hab);
return result;
}
}
return NULL;
}
Conclusions: When you get file names of everything other than native filesystem, you may have damaged strings. It they are not damaged, but in different UTF-8 representations you can translate them with Normalizer.
JNIEXPORT jstring JNICALL
JNU_NewStringPlatform(JNIEnv *env, const char *str)
{
jstring result;
result = nativeNewStringPlatform(env, str);
if (result == NULL) {
jbyteArray hab = 0;
int len;
if (fastEncoding == NO_ENCODING_YET)
initializeEncoding(env);
if ((fastEncoding == FAST_8859_1) || (fastEncoding == NO_ENCODING_YET))
return newString8859_1(env, str);
if (fastEncoding == FAST_646_US)
return newString646_US(env, str);
if (fastEncoding == FAST_CP1252)
return newStringCp1252(env, str);
if ((*env)->EnsureLocalCapacity(env, 2) < 0)
return NULL;
len = (int)strlen(str);
hab = (*env)->NewByteArray(env, len);
if (hab != 0) {
(*env)->SetByteArrayRegion(env, hab, 0, len, (jbyte *)str);
if (jnuEncodingSupported(env)) {
result = (*env)->NewObject(env, JNU_ClassString(env),
String_init_ID, hab, jnuEncoding);
} else {
/*If the encoding specified in sun.jnu.encoding is not endorsed
by "Charset.isSupported" we have to fall back to use String(byte[])
explicitly here without specifying the encoding name, in which the
StringCoding class will pickup the iso-8859-1 as the fallback
converter for us.
*/
jmethodID mid = (*env)->GetMethodID(env, JNU_ClassString(env),
"
result = (*env)->NewObject(env, JNU_ClassString(env), mid, hab);
}
(*env)->DeleteLocalRef(env, hab);
return result;
}
}
return NULL;
}
Conclusions: When you get file names of everything other than native filesystem, you may have damaged strings. It they are not damaged, but in different UTF-8 representations you can translate them with Normalizer.
czwartek, kwietnia 25, 2013
Tibco Software Support is a failure
8 months of diagnosing and fixing XA issue and... Tibco Software cannot fix XA transactions in their ESB stack. If you deal with money you shouldn't use EMS + BW, otherwise you will end up with inconsistent balances, stucked transactions, missing data and fatal manual recovery cases - everything without proper help from vendor. Leaving clients alone with serious problems can be the just that one argument to switch to different vendor. This bird won't fly. Where is 2 second advantage?
czwartek, kwietnia 18, 2013
Płatności mobilne
Dwa lata prac, więcej niż kilka milionów wydatków i 10000* użytkowników w 5 miesięcy - to płatności mobilne T-Mobile (PTC na chwilę obecną nie jest w stanie ustalić ilu jest realnych użytkowników płatności, 10000 to tylko liczba sprzedanych usług). 10000 użytkowników w niecałe 3 tygodnie i dalszy dynamiczny wzrost - to aplikacja IKO od PKO B.P. Czemu PTC odniosło taką porażkę a PKO sukces?
PTC:
PTC:
- wymagana dedykowana karta SIM z zapisaną aplikacją i kluczami kryptograficznymi
- niewiele wspieranych telefonów z NFC, w zasadzie tylko Samsung Galaxy S3, skomplikowany dewelopment, brak własnych ekspertów
- skomplikowana architektura systemu
- specjaliści od bezpieczeństwa twierdzą, że NFC ma luki '0 day/in the wild'
- usługa wymaga kooperacji z bankiem: Raiffeisen, mBank, Getin.
- drogi abonament
- wysokie koszty operatora (infrastruktura własna, T-Mobile DE, opłaty operatora transakcji Gemalto)
- aplikacja IKO na dowolna komórkę z Androidem, iOS-em, Blackberry (ale wymaga internetu)
- bezpieczeństwo oparte na kryptografii i tokenach
- usługa jest darmowa
- można płacić w sklepach i robić wypłaty z bankomatów
- można sprawdzić bieżący stan konta i historię wpływów/wydatków
Latem mało wygodnie jest nosić ze sobą portfel albo karty luzem, a komórkę ma się zawsze. PKO pokazuje, że jest bankiem otwartym na młodych ludzi i zależy im na wygodzie klientów.
Dla myWallet powinny zostać zrobione badania rynkowe: przepytanie grupy docelowej przez SMG/KRC co potencjalni klienci sądzą o usłudze, czy by chcieli jej używać, jakie widzą plusy a jakie minusy. Wyniki badania powinny zostać przeanalizowane i stanowić podstawę do nowej bardziej szczegółowej ankiety a potem warsztatów grupy testowej z makietą. Właścicieli biznesowi powinni wcześniej odrobić pracę domową jak wygląda proces kreacji produktu, wybrać do tego metodykę uwzględniającą strategiczną konieczność synergii między biznesem a NT/IT. Czy biznes plan był naciągany ze względu na naciski z Niemiec i wszystkie te rzeczy pominięto? Nie wiadomo. Jedno jest jednak pewne - każdy duży projekt powinien mieć dobrze sprawdzone uzasadnienie biznesowe.
Dla myWallet powinny zostać zrobione badania rynkowe: przepytanie grupy docelowej przez SMG/KRC co potencjalni klienci sądzą o usłudze, czy by chcieli jej używać, jakie widzą plusy a jakie minusy. Wyniki badania powinny zostać przeanalizowane i stanowić podstawę do nowej bardziej szczegółowej ankiety a potem warsztatów grupy testowej z makietą. Właścicieli biznesowi powinni wcześniej odrobić pracę domową jak wygląda proces kreacji produktu, wybrać do tego metodykę uwzględniającą strategiczną konieczność synergii między biznesem a NT/IT. Czy biznes plan był naciągany ze względu na naciski z Niemiec i wszystkie te rzeczy pominięto? Nie wiadomo. Jedno jest jednak pewne - każdy duży projekt powinien mieć dobrze sprawdzone uzasadnienie biznesowe.
czwartek, kwietnia 11, 2013
Massively parallel BW XML processing
1. Create Java Code parsing XML and finding appropriate nodes, with asynchronous requests creation and response handling:
Document doc = XmlHelper.getDocumentBuilder().parse(new InputSource(new StringReader(xml)));
List<Node> matchingParentNodes = XmlHelper.getNestedElementsByTagNs(doc, "http://namespace.example.com", "EntityNode");
int cnt = matchingParentNodes.size();
final CountDownLatch gate = new CountDownLatch(cnt);
for (Node node : matchingParentNodes) {
final Message m = new Message();
m.param1 = XmlHelper.getNodeValueNs(node, "Param1");
m.cookie = node;
m.requestReply(timeoutMillis, new MessageCallback() {
@Override
public void onMessage(Message resp) {
Node owner = (Node) resp.cookie;
XmlHelper.setNodeValueNs(owner, "Param2", resp.param2);
gate.countDown();
}
});
}
gate.await(timeoutMillis, TimeUnit.MILLISECONDS);
if (gate.getCount() != 0)
throw new RuntimeException("Not all subrequests "+gate.getCount()+" of "+matchingParentNodes.size()+" has been handled in given time "+timeoutMillis+"ms");
return XmlHelper.nodeToString(doc);
2. Java Event Starter reads Messages from LinkedBlockingQueue and handles single record.
Document doc = XmlHelper.getDocumentBuilder().parse(new InputSource(new StringReader(xml)));
List<Node> matchingParentNodes = XmlHelper.getNestedElementsByTagNs(doc, "http://namespace.example.com", "EntityNode");
int cnt = matchingParentNodes.size();
final CountDownLatch gate = new CountDownLatch(cnt);
for (Node node : matchingParentNodes) {
final Message m = new Message();
m.param1 = XmlHelper.getNodeValueNs(node, "Param1");
m.cookie = node;
m.requestReply(timeoutMillis, new MessageCallback() {
@Override
public void onMessage(Message resp) {
Node owner = (Node) resp.cookie;
XmlHelper.setNodeValueNs(owner, "Param2", resp.param2);
gate.countDown();
}
});
}
gate.await(timeoutMillis, TimeUnit.MILLISECONDS);
if (gate.getCount() != 0)
throw new RuntimeException("Not all subrequests "+gate.getCount()+" of "+matchingParentNodes.size()+" has been handled in given time "+timeoutMillis+"ms");
return XmlHelper.nodeToString(doc);
2. Java Event Starter reads Messages from LinkedBlockingQueue and handles single record.
sobota, marca 30, 2013
środa, marca 20, 2013
MSSQL Server 2008 and Tibco BW: Connection closed.
MSSQL Server 2008 is using Start TLS on plain socket, but Tibco old Entrust security provider doesn't support it.
Set java.property.TIBCO_SECURITY_VENDOR=j2se.
Set java.property.TIBCO_SECURITY_VENDOR=j2se.
niedziela, marca 17, 2013
piątek, marca 15, 2013
O zakupach online
Ponad 90% ankietowanych kupuje nieprzypadkowo (minimum kilka razy w roku, do kilku zakupów w miesiącu). Większe upowszechnienie zakupów online nie następuje, bo przez Internet nie można dokładnie obejrzeć i sprawdzić produktu oraz nie można wszystkiego kupić (choć na przykład zakupy spożywcze z dowozem oferuje Tesco) - uważa więcej niż 40%. Prawie 17% boi się oszukania przez nieuczciwego sprzedawcę. Około 10% woli nie udostępniać swoich danych osobowych, a 9% obawia się długiego oczekiwania na przesyłkę. Najczęściej kupowana jest odzież, obuwie, dodatki, sprzęt elektroniczny, akcesoria do domu i ogrodu (wszystkie kategorie ponad 40%). Prawie 24% ankietowanych zostało oszukanych przy zakupie przynajmniej raz (najczęściej: towar niezgodny z opisem lub uszkodzony, klient nie dostał towaru), ale tylko około 10% obawia się sposobu online robienia zakupów. W celu sprawdzenia wiarygodności sprzedawcy internauci czytają opinie innych użytkowników (ok. 60-70%) oraz regulamin sklepu (~47%). Ponad 23% konsultuje się ze znajomymi.
Dla kupujących w sieci najważniejsze są dokładne opisy i zdjęcia produktów, szybka dostawa i bezpieczeństwo transakcji (90% +). Ważne też są komentarze o produktach, informacje o siedzibie sklepu oraz duży wybór sposobów płatności. Prawie 84% trzyma się przy nowych zakupach sprawdzonego sprzedawcy, jeśli ceny i szybkość dostawy pozostają nadal atrakcyjne.
Ankietowani sprzedawcy zdają sobie sprawę przed strachem kupujących przed byciem oszukanym i brakiem możliwości przetestowania produktu online oraz że ważne jest wzajemne zaufanie (~60%). Sprzedawcy wiedzą, że ważna jest obsługa na wysokim poziomie, dokładne informacje o produktach oraz szybka wysyłka od momentu zamówienia, płatności.
Dla kupujących w sieci najważniejsze są dokładne opisy i zdjęcia produktów, szybka dostawa i bezpieczeństwo transakcji (90% +). Ważne też są komentarze o produktach, informacje o siedzibie sklepu oraz duży wybór sposobów płatności. Prawie 84% trzyma się przy nowych zakupach sprawdzonego sprzedawcy, jeśli ceny i szybkość dostawy pozostają nadal atrakcyjne.
Ankietowani sprzedawcy zdają sobie sprawę przed strachem kupujących przed byciem oszukanym i brakiem możliwości przetestowania produktu online oraz że ważne jest wzajemne zaufanie (~60%). Sprzedawcy wiedzą, że ważna jest obsługa na wysokim poziomie, dokładne informacje o produktach oraz szybka wysyłka od momentu zamówienia, płatności.
How to log from Java inside Tibco BW
Create JavaEventSource class with its own static LinkedBlockingQueue and Logger class inserting to this queue. Create Tibco BW process receiving logging events and inside use your own logging subsystem. Please notice that onEvent activity should use some form of string holder class for clean solution.
niedziela, marca 10, 2013
Toyota RAV4 2013
Począwszy od trzeciej generacji Yarisa Toyota zapoczątkowała trend zwiększania miejsca w środku za pomocą zmniejszenia szerokości kokpitu. Widać to również w nowej RAV-ce. Samochód jest od 13 cm dłuższy, a subiektywnie wydaje się, że urósł sporo więcej: z tyłu dużo wygodniejsza (bo dłuższa) kanapa oraz ogromny bagażnik (o 137 litrów więcej, prawie 550). Wróćmy do przodu auta. Odległość od szyby do płaszczyzny kierownicy jest mniejsza w modelu z 2013 roku, ale kokpit robi się szerszy na środku samochodu - jest to niewygodne przy patrzeniu na panel radia/nawigacji/kamery cofania. Przyciski sterownia systemami samochodu zostały umieszczone pod fałdą kokpitu - to również jest mało ergonomiczne, lepiej nie używać ich w trakcie jazdy.
W nowej RAV-ce wyżej pociągnięta jest linia okien. Do spółki z krótszym kokpitem dla małych wzrostem kierowców oznacza to subiektywne przytłoczenie samochodem. Nie oznacza to jednak, że siedzi się niewygodnie - można wyregulować kolumnę kierownicy i siedzenie. W lusterku środkowym widać mniejszą tylną szybę, ale w cofaniu pomogą czujniki i kamera.
O ile styl w nowym Aurisie zachwyca, to w przypadku RAV-ki bardziej subtelne i milsze dla oka jest starsze wnętrzne.
Bagażnik może być otwierany i zamykany elektrycznie. Pierwsza reakcja to szukanie przycisku otwierania klapy - trzeba zajrzeć pod spód, by odnaleźć czarny prostokąt, a następnie dość mocno przycisnąć jego środek - nie ma tu żadnego guzika. Elektronika wychwytuje ruch zamykania i sama kończy akcję użytkownika.
Nowy model RAV4 sprawia trochę zadziorne wrażenie. Prezentuje się jak nowoczesny SUV. Patrząc z boku tył samochodu wygląda trochę dziwnie, ale musimy pamiętać, że jest to efekt dużego bagażnika.
Podczas jazdy po dziurach ma się wrażenie, że samochód woli jednak autostradę. Silnik DCAT 2.2l 150KM wydaje się trochę mało żwawy, ale za to cichy - wszystko to do momentu wciśnięcia przycisku Sport. Robi się wtedy dynamiczniej i głośniej, silnik z charakterystycznym odgłosem żwawo wkręca się na obroty. Toyota musiała pójść na kompromis z ekologami - standardowy diesel stuningowany na oszczędność, motoru 177KM już nie ma, pojawił się mały i bardzo oszczędny diesel 124KM (ma teraz system Start&Stop). Podsumowując: przyjemne auto dla całej rodziny, którym można pojeździć ekonomicznie po mieście i dynamicznie w trasie. Jednak za 150 tys. złotych duzi chłopcy pewnie woleliby odchodzącego X-a, czyli najmocniejszą wersję wyposażenia z najmocniejszym silnikiem.
Tesco nieprzyjazne dla klienta
![]() |
| Tesco przy Górczewskiej |
wtorek, marca 05, 2013
Porównywanie elementów tablic w Tibco BW
for $left in $Map-Matcher/input/data return
(for $right in $Map-Data/input/records return
if ($left/matchRepeatable/matchField = $right/entry/field and $left/matchAnotherField = $right/anotherField) then $right else ()
)
(for $right in $Map-Data/input/records return
if ($left/matchRepeatable/matchField = $right/entry/field and $left/matchAnotherField = $right/anotherField) then $right else ()
)
piątek, marca 01, 2013
Grails Spring Security LDAP AD
// Added by the Spring Security Core plugin:
grails.plugins.springsecurity.userLookup.userDomainClassName = 'security.AuthUser'
grails.plugins.springsecurity.userLookup.authorityJoinClassName = 'security.AuthUserAuthRole'
grails.plugins.springsecurity.authority.className = 'security.AuthRole'
// LDAP config
grails.plugins.springsecurity.ldap.context.managerDn = 'domain\\user'
grails.plugins.springsecurity.ldap.context.managerPassword = 'passw0rd'
grails.plugins.springsecurity.ldap.context.server = 'ldap://dc:389/'
grails.plugins.springsecurity.ldap.authorities.ignorePartialResultException = true
grails.plugins.springsecurity.ldap.search.base = 'dc=domain,dc=internal'
grails.plugins.springsecurity.ldap.search.filter="sAMAccountName={0}"
grails.plugins.springsecurity.ldap.search.searchSubtree = true
grails.plugins.springsecurity.ldap.auth.hideUserNotFoundExceptions = false
grails.plugins.springsecurity.ldap.search.attributesToReturn = ['mail', 'displayName', 'title']
grails.plugins.springsecurity.providerNames = ['ldapAuthProvider', 'daoAuthenticationProvider', 'anonymousAuthenticationProvider', 'rememberMeAuthenticationProvider']
grails.plugins.springsecurity.ldap.useRememberMe = false
grails.plugins.springsecurity.ldap.authorities.retrieveGroupRoles = true
grails.plugins.springsecurity.ldap.authorities.retrieveDatabaseRoles = true
grails.plugins.springsecurity.ldap.authorities.groupSearchBase ='dc=domain,dc=internal'
grails.plugins.springsecurity.ldap.authorities.groupSearchFilter = 'member={0}'
grails.plugins.springsecurity.ldap.authorities.groupSearchFilter = '(member:1.2.840.113556.1.4.1941:={0})'
//grails.plugins.springsecurity.ldap.context.baseEnvironmentProperties
grails.plugins.springsecurity.ldap.authorities.clean.uppercase = true
Akcje na kontrolerach można zabezpieczyć za pomocą adnotacji grails.plugins.springsecurity.Secured np.
@Secured(['ROLE_ITSM_ADMINS','ROLE_ADMIN'])
def list() {
Log.find(params)
}
gdzie "ITSM Admins" to nazwa grupy w Active Directory.
public static String describeLogin() {
if (springSecurityService.principal instanceof String)
return "Authorization: "+springSecurityService.principal
def user = AuthUser.findByUsername(springSecurityService.principal.username)
if (user)
return "Logged in as: "+user.username
return "Not logged in"
}
grails.plugins.springsecurity.userLookup.userDomainClassName = 'security.AuthUser'
grails.plugins.springsecurity.userLookup.authorityJoinClassName = 'security.AuthUserAuthRole'
grails.plugins.springsecurity.authority.className = 'security.AuthRole'
// LDAP config
grails.plugins.springsecurity.ldap.context.managerDn = 'domain\\user'
grails.plugins.springsecurity.ldap.context.managerPassword = 'passw0rd'
grails.plugins.springsecurity.ldap.context.server = 'ldap://dc:389/'
grails.plugins.springsecurity.ldap.authorities.ignorePartialResultException = true
grails.plugins.springsecurity.ldap.search.base = 'dc=domain,dc=internal'
grails.plugins.springsecurity.ldap.search.filter="sAMAccountName={0}"
grails.plugins.springsecurity.ldap.search.searchSubtree = true
grails.plugins.springsecurity.ldap.auth.hideUserNotFoundExceptions = false
grails.plugins.springsecurity.ldap.search.attributesToReturn = ['mail', 'displayName', 'title']
grails.plugins.springsecurity.providerNames = ['ldapAuthProvider', 'daoAuthenticationProvider', 'anonymousAuthenticationProvider', 'rememberMeAuthenticationProvider']
grails.plugins.springsecurity.ldap.useRememberMe = false
grails.plugins.springsecurity.ldap.authorities.retrieveGroupRoles = true
grails.plugins.springsecurity.ldap.authorities.retrieveDatabaseRoles = true
grails.plugins.springsecurity.ldap.authorities.groupSearchBase ='dc=domain,dc=internal'
grails.plugins.springsecurity.ldap.authorities.groupSearchFilter = 'member={0}'
grails.plugins.springsecurity.ldap.authorities.groupSearchFilter = '(member:1.2.840.113556.1.4.1941:={0})'
//grails.plugins.springsecurity.ldap.context.baseEnvironmentProperties
grails.plugins.springsecurity.ldap.authorities.clean.uppercase = true
Akcje na kontrolerach można zabezpieczyć za pomocą adnotacji grails.plugins.springsecurity.Secured np.
@Secured(['ROLE_ITSM_ADMINS','ROLE_ADMIN'])
def list() {
Log.find(params)
}
gdzie "ITSM Admins" to nazwa grupy w Active Directory.
public static String describeLogin() {
if (springSecurityService.principal instanceof String)
return "Authorization: "+springSecurityService.principal
def user = AuthUser.findByUsername(springSecurityService.principal.username)
if (user)
return "Logged in as: "+user.username
return "Not logged in"
}
Subskrybuj:
Posty (Atom)
















