Pokazywanie postów oznaczonych etykietą development. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą development. Pokaż wszystkie posty

czwartek, sierpnia 03, 2017

Schemaless JSON REST store




czwartek, lutego 19, 2015

Aerospike goes AIO!



Modified source code is here. I need to give it back to be compliant with GNU AGPLv3 licence.

środa, sierpnia 20, 2014

GenericRa.rar with JBoss 5.1 and Oracle AQ


Generic JMS RA from Glassfish (created by Sun Microsystems, maintained by Oracle Corporation) is usable with Oracle AQ.

Adjust system properties:
oracle.jms.traceLevel=6
oracle.jms.useNativeXA=true
oracle.jms.useEmulatedXA=false
oracle.jms.j2eeCompliant=false.

<mbean code="org.jboss.jms.jndi.JMSProviderLoader"
          name="jboss.messaging:service=JMSProviderLoader,name=AQProvider">
      <attribute name="ProviderName">DefaultAQProvider</attribute>
      <attribute name="ProviderAdapterClass">org.jboss.jms.jndi.JNDIProviderAdapter</attribute>
      <attribute name="FactoryRef">XAConnectionFactory</attribute>
      <attribute name="QueueFactoryRef">XAQueueConnectionFactory</attribute>
      <attribute name="TopicFactoryRef">XATopicConnectionFactory</attribute>
 <attribute name="Properties">
java.naming.factory.initial=oracle.jms.AQjmsInitialContextFactory
java.naming.security.principal=XA
java.naming.security.credentials=toortoor
db_url=jdbc:oracle:thin:@localhost:1521:XE
datasource=java:XAOracleDS
 </attribute>
   </mbean>

czwartek, sierpnia 14, 2014

jbossts-properties.xml

<properties depends="arjuna" name="jta">
    <property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.JBM01"  value="org.jboss.jms.server.recovery.MessagingXAResourceRecovery;java:DefaultJMSProvider"/>
    <property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.EMS01"  value="org.jboss.jms.server.recovery.MessagingXAResourceRecovery;java:DefaultEMSProvider"/>
<property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.Oracle" value="com.arjuna.ats.internal.jdbc.recovery.OracleXARecovery;oraclejta-properties.xml"/>
    <property name="com.arjuna.ats.jta.xaRecoveryNode" value="1"/>
</properties>

wtorek, sierpnia 12, 2014

MySQL to amatorska baza danych


czwartek, maja 22, 2014

VAT - Validation of Architecture in Tests

1. Flood test / capacity test
We call component with assumed load, see distribution of response times (min, max, avg, med, 80 percentile, 95 percentile, 99 percentile) - are they deterministic. We increase load linearly up to 10x (one order of magnitude higher) and monitor performance. Components should be able to be tuned to handle load 2x higher than current business requirement. Tests should define limits when below application is still responsive and above crashes.
2 Duplicates test
We call services with duplicated messages and check handling of duplicates. Application may not recognize duplicates, may throw errors due to detection of repeating unique ids and may accept duplicates, but internally skip processing of them. Tests should check for not aimed data multiplication and stalled flows due to rejected duplicates errors.
3 Timeout test
We inject long sleep activities and check timeout handling. We look for snowball effect (backlog aggregation due to repeating on timeout), not defined capacity limits causing whole components/flows to be stucked/failing with OutOfMemory errors, overloaded components and servers.
4 Kill & restart test
We kill and restart whole application/(application) servers. We look for missing (lost) data, duplicates and other inconsistencies. We verify transactional requirements and actual implementation.
5 Error injection and negative path
We inject errors inside process execution and check for missing error handlers. We verify error codes to see if they match actual exception. We also verify assigned error categories (business, technical, repeatable, non-repeatable).
6 Logging test
We check if logging works, payloads are available and we have enough file/database storage. We check if flows are traceable using log frontend.
7. Active-Active, Active-Standby
We kill components and check switching between endpoints. We measure times and verify against configured application timeouts. We detect weak points / single points of failure, recovery errors. It is important to test all possible permutations, with various timings etc. We should create and execute test case when whole HA infrastructure does not deliver working HA for connected applications.
8. Poller test
We run many pollers at once and check if they are protected against working in multithreading. We configure limits to comply with singleton design or implement missing (b)locking. We check data consistency/duplication.
9  Data republication
We check if data republication is possible, how to trigger it, how to detect republication from external systems, how to protect against flood/snowball effect/not controllable backlog.
10  Long term stability test
We execute normal load tests for 24/48/72 hours and check for any stability issues caused by daily IT usage patterns.

piątek, listopada 22, 2013

Configure Tibco EMS provider for JBoss EAP 5.x

Put jms.jar and tibjms.jar to lib/endorsed.

Add into server/default/deploy/messaging/jms-ds.xml:
<mbean code="org.jboss.jms.jndi.JMSProviderLoader"
          name="jboss.messaging:service=JMSProviderLoader,name=EMSProvider">
      <attribute name="ProviderName">DefaultEMSProvider</attribute>
      <attribute name="ProviderAdapterClass">org.jboss.jms.jndi.JNDIProviderAdapter</attribute>
      <attribute name="FactoryRef">ConnectionFactory</attribute>
      <attribute name="QueueFactoryRef">QueueConnectionFactory</attribute>
      <attribute name="TopicFactoryRef">TopicConnectionFactory</attribute>
   <attribute name="Properties">
  java.naming.security.principal=admin
  java.naming.security.credentials=Adm1n
  java.naming.factory.initial=com.tibco.tibjms.naming.TibjmsInitialContextFactory
  java.naming.factory.url.pkgs=com.tibco.tibjms.naming
  java.naming.provider.url=tibjmsnaming://tb-dev2.dc2:7222
   </attribute>
   </mbean>
In tibemsadmin execute:
create queue queue/DLQ
create queue testQueue
commit

Write MDB:

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.Message;
import javax.jms.MessageListener;

@MessageDriven(
activationConfig = {
 @ActivationConfigProperty(propertyName = "destination", propertyValue = "testQueue"),
 @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
 @ActivationConfigProperty(propertyName = "providerAdapterJNDI", propertyValue = "java:/DefaultEMSProvider"),
 @ActivationConfigProperty(propertyName = "user", propertyValue = "user"),
 @ActivationConfigProperty(propertyName = "password", propertyValue = "pass"),
 @ActivationConfigProperty(propertyName = "DLQUser", propertyValue = "user"),
 @ActivationConfigProperty(propertyName = "DLQPassword", propertyValue = "pass")
},
mappedName = "testQueue")
public class TestQueue implements MessageListener {
    public TestQueue() {}
    public void onMessage(Message message) {
        System.out.println(message+"");    
    }
}

/** see org.jboss.resource.adapter.jms.inflow.JmsActivationSpec for all properties **/

And you've got it:

10:39:37,064 INFO [STDOUT] TextMessage={ Header={ JMSMessageID={ID:EMS-TEST.D965 28614F411790C:7} JMSDestination={Queue[testQueue]} JMSReplyTo={null} JMSDelivery Mode={PERSISTENT} JMSRedelivered={false} JMSCorrelationID={null} JMSType={null} JMSTimestamp={Fri Nov 22 10:39:36 CET 2013} JMSExpiration={0} JMSPriority={4} } Properties={ } Text={2013-11-22T10:39:37.028+01:00} }

środa, listopada 20, 2013

Standalone JBoss Messaging JMS client with EAP 5.1.0 jars

commons-logging.jar
concurrent.jar
javassist.jar
jboss-aop-client.jar
jboss-client.jar
jboss-common-core.jar
jboss-ha-client.jar
jboss-ha-legacy-client.jar
jboss-javaee.jar
jboss-logging-jdk.jar
jboss-logging-log4j.jar
jboss-logging-spi.jar
jboss-main-client.jar
jboss-messaging-client.jar
jboss-metadata.jar
jboss-mdr.jar
jboss-remoting.jar
jboss-security-spi.jar
jboss-serialization.jar
jbossall-client.jar
jbosscx-client.jar
jbossjts-integration.jar
jbossjts.jar
jnp-client.jar
log4j.jar
logkit.jar
policy.jar
scout.jar
slf4j-api.jar
slf4j-jboss-logging.jar
trove.jar

czwartek, października 17, 2013

NestedJarClassLoader

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;


public class NestedJarClassLoader extends URLClassLoader {

private HashMap jarCache = new HashMap();

@Override
public InputStream getResourceAsStream(String s) {
byte[] data = jarCache.get(s);
if (data==null)
data = jarCache.get("/"+s);
return (data!=null) ? new ByteArrayInputStream(data) : null;
}

@Override
public URL findResource(String name) {
return null; // not supported
}

@Override
public Class loadClass(String s) throws ClassNotFoundException {
byte[] bc = jarCache.get(s+".class");
if (bc!=null)
return super.defineClass(s, bc, 0, bc.length);
return super.loadClass(s);
}

public NestedJarClassLoader(URL url) throws Exception {
super(new URL[] {}, NestedJarClassLoader.class.getClassLoader());
String sURL = url.toString();
String u = url.toString().substring(4);
String name = new File(u.substring(9)).getName();
URL firstJarUrl = new URL(sURL.substring(0, sURL.lastIndexOf("/")+1));
JarFile jf = ((JarURLConnection)firstJarUrl.openConnection()).getJarFile();
InputStream is = jf.getInputStream(jf.getEntry(name));
byte[] binaryJar = new byte[is.available()];
/* read through compressed stream is tricky */
int n = 0;
int cnt = 0;
do {
n = is.read(binaryJar, cnt, binaryJar.length - cnt);
if (n>0)
cnt += n;
}
while (n > 0);
ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(binaryJar));
ZipEntry ze = null;
while ((ze = zis.getNextEntry()) != null) {
byte[] buff = new byte[4096];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int s = 0;
do {
s = zis.read(buff);
if (s>0)
baos.write(buff, 0, s);
}
while (s > 0);
if (baos.size() > 0 && ze.getName() != null) {
jarCache.put(ze.getName(), baos.toByteArray());
if (ze.getName().endsWith(".class")) {
String className = ze.getName().replace('$', '.').replace('/', '.');
jarCache.put(className, baos.toByteArray());
}
}
}
}

public static void main(String[] args) throws Exception {
URL url = new URL("jar:file:C://tibco/bw/5.10/hotfix/lib/tibcoverage.jar!/tdi.jar");
NestedJarClassLoader ucl = new NestedJarClassLoader(url);
ucl.loadClass("tdi.com.tibco.pe.Logger");
}
}

poniedziałek, października 07, 2013

Zarządzanie zasobami w projekcie

Przełączanie się między kontekstami/zadaniami jest kosztowne nie tylko w przypadku systemu operacyjnego ale też w przypadku pracujących ludzi. Jak zatem pogodzić N projektów i jednego pracownika? Jeden projekt na dzień - dana osoba jest przydzielona do projektu na 100% w ten sam cyklicznie powtarzający się dzień tygodnia np. poniedziałek. W innym projekcie uczestniczy we wtorki. Jeśli projekt jest ważny/priorytetowy to osoba jest przydzielona do niego w piątki i poniedziałki. Co jeśli nie można zebrać danego zespołu w dany dzień/spełnić warunków brzegowych niezbędnych do startu kolejnej iteracji? Ludzie czekają na zaistnienie sprzyjających okoliczności za sprawą kierownika projektu, a jeśli po dwóch godzinach stan się nie zmieni to przechodzą do swoich bieżących nieprojektowych zadań. Dzień taki z punktu widzenia kierownika projektu jest zmarnowany - z tak odebranej kary powinien wyciągnąć wnioski. Jeżeli nie starcza dni tygodnia do podziału, to w oczywisty sposób brakuje ludzi do wykonywania pracy.

czwartek, sierpnia 15, 2013

XML digest in a few lines

com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer11_OmitComments c =
new com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer11_OmitComments();
java.security.MessageDigest md = java.security.MessageDigest.getInstance("SHA1");
md.reset();
md.update(c.engineCanonicalize(xml.getBytes()));
StringBuilder sb = new StringBuilder();
for (byte b : md.digest())
sb.append( String.format("%02x", b) );
digest = sb.toString();

czwartek, lipca 11, 2013

Jak łamać tekst w HTML-u

-ms-word-break: break-all; word-break: break-all; word-break: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto;

czwartek, czerwca 13, 2013

Java EE 7: JMS 2.0

Co nowego w JMS 2.0 - Session.createSharedDurableConsumer pozwala na wielu konsumentów na tej samej subskrypcji durable. JMSDeliveryTime pozawala na opóźnione wysyłanie/dostarczanie komunikatów. Wysyłanie może być asynchroniczne z notyfikacją za pomocą interfejsu CompletionListener.

Java EE 7: Concurrency

Interfejs javax.enterprise.concurrent.ManagedExecutorService dostępny przez JDNI pozwala na zlecanie zadań przez kontener i wykonywanie ich po stronie serwera aplikacyjnego (submit(), execute(), invoke*(), schedule*()):

@Resource(name=”concurrent/LongRunningTasksExecutor”)
ManagedExecutorService mes;

Future reportFuture = mes.submit(new Runnable() { public void run() { /* do the work */} });

Zadania wysyłane do Executora mogą być indetyfikowalne dzięki użyciu metody getIdentityName() z interfejsu javax.enterprise.concurrent.ManagedTask.
Specyfikacja definiuje przykładowe typy Executorów w zależności od parametrów puli wątków, czasu życia zadania i polityki kolejkowania/powtarzania zadań:
Typical Thread Pool, Long-RunningTasks Thread Pool, Shared OLTP Thread Pool, Typical Timer. Executor obsługuje transakcje. Zadania moga korzystać z ContextService-u.
Logowanie w kontenerze może być realizowane przez Executor-a, co może znacząco przyspieszyć wykonywanie zadań, jeśli logowanie jest bazodanowe.

niedziela, czerwca 02, 2013

Fail fast

Duże firmy mają tendencję do przedłużania projektów już skazanych na porażkę, pompowania w nie pieniędzy i dodawania zasobów mimo braku sensu kontynuowania projektu. Tymczasem pozwolenie na upadek projektu byłoby czasem oczekiwanym i pozytywnym działaniem. Jeśli projekt nie toczy się zgodnie z założeniami, to znaczy że był źle zdefiniowany. Lepiej jest zamknąć projekt i zacząć od nowa, oszczędzając pieniądze. Przeterminowany projekt oznacza zazwyczaj niespełnienie biznes planu i rynkowe fiasko. Metodyką przyjazną koncepcji fail fast jest Rational/Open Unified Process.

piątek, maja 24, 2013

How to generate standalone GRAILS/GORM views

import java.util.Calendar
import org.codehaus.groovy.grails.web.servlet.DefaultGrailsApplicationAttributes;
import org.codehaus.groovy.grails.commons.*
import grails.gsp.PageRenderer
import grails.gsp.ExtendedPageRenderer

class StandaloneContentGenerator {

def PageRenderer groovyPageRenderer

def generateContent() {
  ...
  HashMap map = new HashMap()
  map.put(DefaultGrailsApplicationAttributes.CONTROLLER_NAME_ATTRIBUTE, 'logEntry')
  map.put(DefaultGrailsApplicationAttributes.APP_URI_ATTRIBUTE, 'http://host:port/App')

  def content = new ExtendedPageRenderer(groovyPageRenderer, map).render(view: "/logEntry/list",
model: [logEntryInstanceList: results, logEntryInstanceTotal: results.size,
"flash.message": 'Content generated'])
  return content
}
}

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"
}

poniedziałek, stycznia 14, 2013

Grails GSP params

Tworząc w Grailsach formularz podłączony do wyszukiwania w ramach klasy domenowej należy pamiętać o uaktualnieniu atrybutu params we wszystkich możliwych kontrolkach. Dla spójności formularz powinien zawierać wbudowane standardowe parametry wyszukiwania GORM (czyli max, offset, sort, order).




sobota, marca 10, 2012

XML Sig



Referencja do elementu drzewa DOM posiada listę transformat stosowaną na elemenie przed obliczeniem z niego wartości funkcji skrótu. Lista ta stosowana jest zawsze i nie jest zamienna z parametrami podanymi w SignedInfo. W zależności od podanych dla referencji transformat, wartość wynikowa DigestValue będzie różna.

Ten sam logiczny XML będzie miał różne wartości skrótu w zależności od:
  • prefiksów przestrzeni nazw na elemencie
  • 'pretty print' - CR LF i tabulatory w drzewie DOM są widoczne jako nienazwane węzły
  • kolejności (posortowania) atrybutów w elemencie (i użycia metody exclusive w sprowadzaniu drzewa DOM do postaci kanonicznej)

sobota, marca 03, 2012

Lean

Otwartość, szczerość, zaufanie, chęć zrozumienia, empatia, myślenie popłaca.