quinta-feira, 8 de março de 2012

Alfresco - Configuração do CIFS + Kerberos




Após muito tentar e estudar consegui fazer o Alfresco funcionar perfeitamente com o CIFS. Bom primeiramente tentei configura-lo junto ao Samba (estava sem opções), mas de nenhum jeito o treco queria funcionar.


Alfresco roda independente do Samba, mas pelo menos uma coisa boa deu certo ao perdemos um tempo configurando o Samba. Viu-se que a sua autenticação usando Kerberos atendia perfeitamente as requisições. Então passamos a configurar o Alfresco para que também utiliza-se a autenticação do Kerberos no CIFS, em vez do Passthru.
:D

As configurações do sistema são as seguintes:

- Sistema Operacional: Debian Squeeze (6.0.4)

- Alfresco: 4.1.a (compilação da HEAD)

As configurações da rede:

- Deve ser acessado por Windows XP, 32 bits

- Deve ser acessado por Windows 7, 64 bits


Para a configuração básica do Alfresco + Kerberos foi usado o manual disponível no site do Alfresco, visto nesse link: http://docs.alfresco.com/4.0/index.jsp? ... props.html


Essas configurações bastaram para realizar a troca de autenticação de usuários via HTTP, mas não possibilitava a integração com o CIFS. Isso gerou um certo desanimo, pois todas as tentativas pareciam nulas e os resultados não saiam. Após uma longa busca achei um forum que tratava de um erro semelhante com autenticação do CIFS usando Kerberos, nele era sugerido que a classe para autenticação deveria ser uma intância de org.alfresco.repo.security.authentication.SimpleAcceptOrRejectAllAuthenticationComponentImp.


Segue os arquivos de configuração.


/opt/alfresco/tomcat/webapps/alfresco/WEB-INF/classes/alfresco/authentication-services-context.xml

 ...

<!-- The chaining authentication component -->
   <!--bean id="authenticationComponent"
      class="org.alfresco.repo.security.authentication.subsystems.SubsystemChainingAuthenticationComponent"
      parent="authenticationComponentBase"-->
   <bean id="authenticationComponent"
      class="org.alfresco.repo.security.authentication.SimpleAcceptOrRejectAllAuthenticationComponentImp"
      parent="authenticationComponentBase">
      <property name="nodeService">
         <ref bean="nodeService" />
      </property>
      <property name="personService">
         <ref bean="personService" />
      </property>
      <property name="transactionService">
         <ref bean="transactionService" />
      </property>
      <property name="applicationContextManager">
         <ref bean="Authentication" />
      </property>
      <property name="sourceBeanName">
         <value>authenticationComponent</value>
      </property>
   </bean>

...



/opt/alfresco/tomcat/shared/classes/alfresco/extension/file-serveres-custom.xml

<alfresco-config area="file-servers">

   <config evaluator="string-compare" condition="Filesystem Security" replace="true"> 
      <!-- Enterprise authentication with Kerberos -->
      <authenticator type="enterprise"/>
         <KDC>${kerberos.authentication.server.kdc}</KDC>
         <Realm>${kerberos.authentication.realm}</Realm>
         <Password>${kerberos.authentication.cifs.password}</Password>
         <!--LoginEntry>${kerberos.authentication.cifs.configEntryName}</LoginEntry-->
         <Principal>${kerberos.authentication.cifs.principal}<Principal>
         <Debug/>
         <kerberosDebug/>
      </authenticator>
   </config>

   <config evaluator="string-compare" condition="CIFS Server" replace="true">
      <serverEnable enabled="${cifs.enabled}"/>
     
      <host name="${cifs.serverName}" domain="${cifs.domain}"/>
      <comment>Intranet Server</comment>

      <!-- Set to the broadcast mask for the subnet -->
      <broadcast>${cifs.broadcast}</broadcast>
     
      <!-- Set to the IP for the adapter for Java socket -->
      <bindto>${cifs.bindto}</bindto>

      <!-- Use Java socket based NetBIOS over TCP/IP and native SMB on linux -->
       <!-- Can be mapped to non-privileged ports, then use firewall rules to forward
            requests from the standard ports -->
      <tcpipSMB port="${cifs.tcpipSMB.port}" ipv6="${cifs.ipv6}" platforms="linux,solaris,macosx"/>
      <netBIOSSMB sessionPort="${cifs.netBIOSSMB.sessionPort}" namePort="${cifs.netBIOSSMB.namePort}" datagramPort="${cifs.netBIOSSMB.datagramPort}" platforms="linux,solaris,macosx"/>

      <!-- Announce the server to the EMPINT/domain -->
      <!-- Use enabled="false" attribute to disable announcements -->             
      <hostAnnounce interval="5" enabled="${cifs.hostannounce}"/>

      <!-- Use Win32 NetBIOS interface on Windows -->
      <!--Win32NetBIOS/-->

      <!-- Announce the server to the EMPINT/domain -->
      <!-- Use enabled="false" attribute to disable announcements -->             
      <!--Win32Announce interval="5" enabled="${cifs.hostannounce}"/-->
     
      <!-- CIFS Passthru authentication -->
      <!-- Also see the <DomainMappings> config in the 'Filesystem Security' section below -->
      <!--
      <authenticator type="passthru">
        <Server>${passthru.authentication.servers}</Server>
   <Domain>${passthru.authentication.domain}</Domain>
        <protocolOrder>${passthru.authentication.protocolOrder}</protocolOrder>
        <offlineCheckInterval>${passthru.authentication.offlineCheckInterval}</offlineCheckInterval>
      </authenticator>
      -->

      <!-- CIFS Enterprise authentication with Kerberos -->
      <authenticator type="enterprise"/>
         <KDC>${kerberos.authentication.server.kdc}</KDC>
         <Realm>${kerberos.authentication.realm}</Realm>
         <Password>${kerberos.authentication.cifs.password}</Password>
         <!--LoginEntry>${kerberos.authentication.cifs.configEntryName}</LoginEntry-->
         <Principal>${kerberos.authentication.cifs.principal}<Principal>
         <Debug/>
         <kerberosDebug/>
      </authenticator>
     
      <!-- Disable the use of asynchronous sockets/NIO code -->
      <!--
      <disableNIO/>
      -->
     
      <!-- Disable the use of JNI code -->
      <!-- Only currently affects Windows -->
      <!--
      <disableNativeCode/>
      -->
     
      <!-- Session timeout, in seconds -->
      <!-- Defaults to 15 minutes, to match the default Windows client setting        -->
      <!-- If no I/O is received within that time the session is closed by the server -->
      <!--
      <sessionTimeout>${cifs.sessionTimeout}</sessionTimeout>
      -->
     
      <!-- Enable WINS if used for NetBIOS name lookups -->
      <!--
      <WINS>
         <primary>${cifs.WINS.primary}</primary>
         <secondary>${cifs.WINS.secondary}</secondary>
      </WINS>
      -->
     
      <!-- CIFS server debug settings -->
      <!-- Enable 'log4j.logger.org.alfresco.fileserver=debug' in log4j.properties file -->
      <sessionDebug flags="NetBIOS,Pkttype,Streams,Negotiate,Socket,Tree,Errors,State"/>
   </config>

   <config evaluator="string-compare" condition="FTP Server" replace="true">
      <serverEnable enabled="${ftp.enabled}"/>
     
      <!-- Run on a non-privileged port -->
      <port>${ftp.port}</port>

      <!-- IPv6 support -->
      <IPv6 state="${ftp.ipv6}"/>

      <rootDirectory>/${filesystem.name}/</rootDirectory>

      <!-- FTP authentication -->
      <!-- Available types are 'alfresco' and 'passthru' -->
      <authenticator type="alfresco" />
           
      <!-- FTP server debug settings -->
      <!-- Enable 'log4j.logger.org.alfresco.fileserver=debug' in log4j.properties file -->
      <debug flags="File,Search,Error,Directory,Info,DataPort"/>

   </config>
   
   <config evaluator="string-compare" condition="NFS Server" replace="true">
      <serverEnable enabled="${nfs.enabled}"/>

      <!-- Map NFS user/group ids to Alfresco users -->     
      <rpcAuthenticator>
         <userMappings>
            <user name="admin" uid="0" gid="0"/>
         </userMappings>
      </rpcAuthenticator>
   </config>
   
   <config evaluator="string-compare" condition="Filesystems" replace="true">
      <filesystems>

         <filesystem name="${filesystem.name}">
            <store>workspace://SpacesStore</store>
            <rootPath>/app:company_home</rootPath>

            <!-- Add a URL file to each folder that links back to the web client -->
            <urlFile>
               <filename>__Alfresco.url</filename>
               <webpath>http://${localname}:8080/alfresco/</webpath>
            </urlFile>

            <!-- Mark locked files as offline -->
            <offlineFiles/>

            <!-- Desktop actions -->

            <desktopActions>
               <global>
                  <path>alfresco/desktop/Alfresco.exe</path>
                  <webpath>http://${localname}:8080/alfresco/</webpath>
               </global>
               <action>
                  <class>org.alfresco.filesys.repo.desk.CheckInOutDesktopAction</class>
                  <name>CheckInOut</name>
                  <filename>__CheckInOut.exe</filename>
               </action>
               <action>
                  <class>org.alfresco.filesys.repo.desk.JavaScriptDesktopAction</class>
                  <name>JavaScriptURL</name>
                  <filename>__ShowDetails.exe</filename>
                  <script>alfresco/desktop/showDetails.js</script>
                  <attributes>anyFiles</attributes>
                  <preprocess>copyToTarget</preprocess>
               </action>

            </desktopActions>

<!--
            <accessControl default="Write">
               <user name="admin" access="Write"/>
               <address subnet="90.1.0.0" mask="255.255.0.0" access="Write"/>
            </accessControl>
-->
         </filesystem>
       
       <!-- AVM virtualization view of all stores/versions for WCM -->
         <avmfilesystem name="AVM">
            <virtualView/>
         </avmfilesystem>
       
      </filesystems>
   </config>
</alfresco-config>



/opt/alfresco/tomcat/shared/classes/salfresco-global.properties

#
# File System
#
filesystem.name=Intranet
#filesystem.acl.global.defaultAccessLevel=
filesystem.domainMappings=EMPINT
filesystem.domainMappings.value.EMPINT.subnet=172.16.0.0
filesystem.domainMappings.value.EMPINT.mask=255.255.0.0

### Authentication ###
authentication.chain=alfrescoNtlm1:alfrescoNtlm,kerberos1:kerberos,passthru1:passthru,ldap1:ldap-ad
alfresco.authentication.allowGuestLogin=true
alfresco.authentication.authenticateCIFS=false
### NTLM ###
#ntlm.authentication.sso.enabled=true
#ntlm.authentication.mapUnknownUserToGuest=true
### Kerberos ###
kerberos.authentication.server.kdc=172.16.1.250
kerberos.authentication.realm=EMPINT.LOCAL
kerberos.authentication.sso.enabled=true
kerberos.authentication.authenticateCIFS=true
kerberos.authentication.cifs.principal=cifs/intranet.empint.local
kerberos.authentication.cifs.configEntryName=AlfrescoCIFS
kerberos.authentication.http.configEntryName=AlfrescoCIFS
kerberos.authentication.cifs.password=uuh@123
kerberos.authentication.http.password=uuh@123
kerberos.authentication.defaultAdministratorUserNames=administrator,intranet
kerberos.authentication.cifs.enableTicketCracking=true
#
# CIFS
#
cifs.enabled=true
cifs.localname=intranet
cifs.serverName=${cifs.localname}
cifs.domain=EMPINT
cifs.broadcast=172.16.255.255
#cifs.bindto=172.16.1.116
cifs.bindto=0.0.0.0
cifs.ipv6=disabled
cifs.hostannounce=true
# Enable the use of asynchronous sockets/NIO code
cifs.disableNIO=false
# Disable the use of JNI code. Only currently affects Windows
cifs.disableNativeCode=true
# Session timeout, in seconds. Defaults to 15 minutes, to match the default Windows client setting.
# If no I/O is received within that time the session is closed by the server
cifs.sessionTimeout=900
# Can be mapped to non-privileged ports, then use firewall rules to forward requests from the standard ports
cifs.tcpipSMB.port=445
cifs.netBIOSSMB.sessionPort=139
cifs.netBIOSSMB.namePort=137
cifs.netBIOSSMB.datagramPort=138
# Optional WINS server primary and secondary IP addresses. Ignored if autoDetectEnabled=true
cifs.WINS.autoDetectEnabled=false
cifs.WINS.primary=1.2.3.4
cifs.WINS.secondary=5.6.7.8
#
# FTP
#
ftp.enabled=true
ftp.port=2121
ftp.ipv6=disabled
#
# NFS
#
nfs.enabled=false
#
# Passthru
#
passthru.authentication.useLocalServer=false
passthru.authentication.domain=EMPINT
passthru.authentication.servers=EMPINT\\srv-domain,172.16.1.250
passthru.authentication.guestAccess=false
passthru.authentication.defaultAdministratorUserNames=administrator,intranet
#Timeout value when opening a session to an authentication server, in milliseconds
passthru.authentication.connectTimeout=5000
#Offline server check interval in seconds
passthru.authentication.offlineCheckInterval=300
passthru.authentication.protocolOrder=TCPIP,NetBIOS
passthru.authentication.sso.enabled=true
passthru.authentication.authenticateCIFS=false
passthru.authentication.authenticateFTP=true
#
# LDAP
#
ldap.authentication.active=false
ldap.authentication.allowGuestLogin=true
ldap.authentication.userNameFormat=%s
ldap.authentication.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
ldap.authentication.java.naming.provider.url=ldap://srv-domain:389
ldap.authentication.java.naming.security.authentication=DIGEST-MD5
ldap.authentication.escapeCommasInBind=false
ldap.authentication.escapeCommasInUid=false
ldap.authentication.defaultAdministratorUserNames=Administrator
ldap.synchronization.active=true
ldap.synchronization.java.naming.security.authentication=DIGEST-MD5
ldap.synchronization.java.naming.security.principal=user.it
ldap.synchronization.java.naming.security.credentials=xpasswd
ldap.synchronization.queryBatchSize=1000
ldap.synchronization.attributeBatchSize=1000
ldap.synchronization.groupQuery=(objectClass\=*)
ldap.synchronization.groupDifferentialQuery=(objectClass\=*)
ldap.synchronization.personQuery=(&(objectClass=top)(&(!(OU=Desligados))(!(CN=ldap sync))))
ldap.synchronization.personDifferentialQuery=(objectClass\=*)
ldap.synchronization.groupSearchBase=OU=Grupos,DC=EMPINT,DC=local
ldap.synchronization.userSearchBase=OU=Usuarios,DC=EMPINT,DC=local
ldap.synchronization.modifyTimestampAttributeName=modifyTimestamp
ldap.synchronization.timestampFormat=yyyyMMddHHmmss'.0Z'
ldap.synchronization.userIdAttributeName=sAMAccountName
ldap.synchronization.userLastNameAttributeName=sn
ldap.synchronization.userEmailAttributeName=mail
ldap.synchronization.userOrganizationalIdAttributeName=company
ldap.synchronization.defaultHomeFolderProvider=userHomesHomeFolderProvider
ldap.synchronization.groupIdAttributeName=cn
ldap.synchronization.groupDisplayNameAttributeName=displayName
ldap.synchronization.groupType=group
ldap.synchronization.personType=user
ldap.synchronization.groupMemberAttributeName=member
ldap.synchronization.enableProgressEstimation=true
synchronization.synchronizeChangesOnly=true
synchronization.import.cron=0 0 0 * * ?
synchronization.syncWhenMissingPeopleLogIn=true
synchronization.syncOnStartup=true
synchronization.autoCreatePeopleOnLogin=true
synchronization.loggingInterval=100
synchronization.workerThreads=2

/opt/alfresco/java/jre/lib/security/java.login.config


Alfresco {
   com.sun.security.auth.module.Krb5LoginModule sufficient;
};
AlfrescoCIFS {
   com.sun.security.auth.module.Krb5LoginModule required
   storeKey=true
   useKeyTab=true
   keyTab="/etc/intranetcifs.keytab"
   principal="cifs/intranet.empint.local@EMPINT.LOCAL";
};
com.sun.net.ssl.client {
   com.sun.security.auth.module.Krb5LoginModule sufficient;
};
other {
   com.sun.security.auth.module.Krb5LoginModule sufficient;
};

/opt/alfresco/java/jre/lib/security/java.security

 ...
#Alfresco login
login.config.url.1=file:${java.home}/lib/security/java.login.config

/etc/krb5.conf

[libdefaults]
   default_realm = EMPINT.LOCAL
# The following krb5.conf variables are only for MIT Kerberos.
   krb4_config = /etc/krb.conf
   krb4_realms = /etc/krb.realms
   kdc_timesync = 1
   ccache_type = 4
   forwardable = true
   proxiable = true
# The following encryption type specification will be used by MIT Kerberos
# if uncommented.  In general, the defaults in the MIT Kerberos code are
# correct and overriding these specifications only serves to disable new
# encryption types as they are added, creating interoperability problems.
#
# Thie only time when you might need to uncomment these lines and change
# the enctypes is if you have local software that will break on ticket
# caches containing ticket encryption types it doesn't know about (such as
# old versions of Sun Java).
        default_tkt_enctypes = rc4-hmac
        default_tgs_enctypes = rc4-hmac
       
# The following libdefaults parameters are only for Heimdal Kerberos.
   v4_instance_resolve = false
   v4_name_convert = {
      host = {
         rcmd = host
         ftp = ftp
      }
      plain = {
         something = something-else
      }
   }
   fcc-mit-ticketflags = true
[realms]
   EMPINT.LOCAL = {
      kdc = srv-domain.empint.local
      admin_server = srv-domain.empint.local
      default_domain = empint.local
      }
[domain_realm]
   .empint.local = EMPINT.LOCAL
   empint.local = EMPINT.LOCAL
[login]
   krb4_convert = true
   krb4_get_tickets = false

Se notarem o Passthru não foi abandonado, pois o FTP ainda funciona com ele. Não testei substitui-lo pelo Kerberos ainda.
Outras configurações de rede que podem ser uteis. Pois precisaram ser feitas para o funcionamento correto da comunicação entre o Windows e o Debian.
/etc/hosts

127.0.0.1       localhost.localdomain   localhost       SRV-ECM.EMPINT.local SRV-ECM
127.0.1.1       SRV-ECM.EMPINT.local localhost       SRV-ECM
172.16.1.116    intranet.empint.local intranet
172.16.1.250    srv-domain.empint.local      srv-domain

Assim o serviço do Alfresco no nosso sistema pode ser acessado pelo endereço de rede: \\intranet.empint.local\Intranet


quarta-feira, 19 de janeiro de 2011

Gaia Framework - utilizando API do Ant para gerar Jar

Como primeiro post técnico sobre o Gaia Framework escolhi a integração feita com a API do Ant. Mais especificamente a task que fazia a compactação dos arquivos e criar um Jar bacana. Basicamente o XML visto a baixo:

<project default="createJar">
   <target
name="createJar" >
     <jar
destfile="gaia-dynamic-entity-2.0.jar" basedir="." />
   </target>
</project>


O foda é fazer esse XML virar código Java. Depois de muito procurar no Google eu descobri que não sei procurar ahhahhahaha. Por isso parti pro velho e sábio método milenar da "Tentativa e Erro" ... basicamente é simples ... adicionamos o jar do Ant no projeto e vamos chutando as classes a serem usadas. Não deve ser muito difícil né? eheheheheheh

Bom para inlcuir o Jar do Ant no projeto basta que seja importada a seguinte dependência:

<dependency>
   <groupId>
org.apache.ant</groupId>
   <artifactId>
ant</artifactId>
   <version>
1.8.2</version>
</dependency>


Segundo passo é decobrir as classes que tinha que usar, mas até que foi simples. O nome delas é igual ao das tags, veja o código Java:

package net.sf.gaia.util;

import java.io.File;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Target;
import org.apache.tools.ant.taskdefs.Jar;

public abstract class GaiaUtils {

  private static final Log logger = LogFactory.getLog(GaiaUtils.class);

  public final static String getGaiaPath() {
    String path = System.getProperty("gaia.dir");
    if (path == null) {
       path = System.getProperty("user.dir");
    }
    return path;
  }

  public final static String getGaiaTempPath() {
    return getGaiaPath() + File.separator + "temp";
  }

  public final static String getGaiaServicePath() {
    String path = System.getProperty("gaia.service.dir");
    if (path == null) {
       path = System.getProperty("user.dir");
    }
    return path;
  }
  public final static void createJarFile(String jarName, String classPath) {
    try {
       if (classPath == null) {
          classPath = getGaiaTempPath() + File.separator + "classes";
       }
       
       logger.info("Creating pack classes from: " + classPath + " ...");
       long l = System.currentTimeMillis();

       if (!jarName.endsWith(".jar")) {
          jarName += ".jar";
       }
       
       File jarDir = new File(getGaiaServicePath());
       if (!jarDir.exists()) {
          jarDir.mkdir();
       }
       
       File jarTempDir = new File(classPath);
       if (!jarTempDir.exists()) {
          jarTempDir.mkdir();
       }

       Project proj = new Project();
       Target target = new Target();
       Jar jar = new Jar();
       jar.setBasedir(jarTempDir);
       
       File fileJar = new File(jarDir, jarName);
       // Delete the jar file if it already exists
       if (fileJar.exists() == true) {
          fileJar.delete();
       }
       
       jar.setDestFile(fileJar);

       jar.setProject(proj);
       
       target.addTask(jar);
       target.setName("createJar");
       target.setProject(proj);
       
       proj.addTarget(target);
       proj.setDefault("createJar");
       
       jar.execute();
       logger.info("Created jar file: " + jarName + " ... " + (System.currentTimeMillis() - l) + " ms");
    } catch (Exception e) {
       logger.error("Can't create " + jarName, e);
    }
  }
}

Gaia Framework - O Inicio

Bom senhores compatriotas ... eheheh ... faz um bom tempo que não escrevo um post. Não por falta de assunto, mas sim por falta de tempo. Tinha selecionado uns bons tópicos pra escrever, mas ainda não achei a voia pra escrevo-los.

Os assuntos variavam um pouco era sobre Hibernate, Java, Maven e afins ... mas ai pensei porque não juntar tudo e fazer algo de útil ... sei lá uma ideiazinha de uma API Java ... mas o que?

Bem a resposta veio quando estava conversando com um amigo meu e ele comentou que estava fazendo um projetozinho com E-Forms. De inicio a ideia não parecia grande coisa, mas ai surgiu a vontade de juntar um pouco do conceito dos E-Forms e adapta-los num sistema Georreferenciado. Convidei-o para participar mas ele fico com medinho e desistiu logo de inicio.

Aproveitei que eu já tinha um SVN e comecei a organizar o projeto. Todo estruturado no Maven, isso eu não tinha dúvida. O foda era o nome. Que nome botar? ... Fazer uma API que adivinha qual a codificação de um arquivo é moleza, mas escolher o nome dela é o que demora ... Bem que nome escolher? E o que fazer de inicio?

Como diz meu avó - "No é facile" ... Mas de inicio pensei em fazer uma especie de framework. Algo que me disponibiliza-se classes e métodos para gerar as minhas tabelas, fazer as transações com o banco de dados e disponibilizar funções utilitárias para as mais diversas situações. Viajei um pouco mas no fim surgiu o projeto do Gaia.

O que vem a ser e porque do nome? Bem Gaia na mitologia é a mãe de vários seres (titãs, deuses, semideuses e uns outros lá que ainda num sei digitar). E como essa API tem por ser o corpo vital do projeto do Georreferenciamento (e outros que por ventura venham a surgir) o nome caiu como uma luva ... pelo menos eu achei e nesse caso a minha opinião é a que importa ahahahahaha :D

Bom nos próximos tópicos vou começar a publicar algumas das funções e integrações com bibliotecas que achei muito interessante e que deram um pouco de trabalho. Até estava pensando em já disponibilizar o link do repositório do Maven para utilizar a API, mas num adianta porque mesmo querendo baixar você não vai saber usar direito :P. Espere os próximos post e ai sim da de brincar com o filhote ^^.

sábado, 16 de outubro de 2010

PostgreSQL 9.0 - Instalando no Ubuntu 10.04

É faz tempo que não posto nada e já estava até nem ligando mais, mas hoje fiquei brincando e configurando o PostgreSQL no trabalho e gostei muito. Já mexia antes com a versão 8.3 mas resolvi baixar hoje a 9.0 para configurar o Alfresco nela e gostei muito. Principalmente com o pgAdmin 1.12.1 que vem junto com o instalador para Windows.

Chegando em casa liguei o pc e deu vontade de tentar configurar o PostgreSQL no meu Ubuntu, mas tive alguns probleminhas então logo surgiu uma ótima ideia - "porque não fazer um post?" ehehehe ... bem vamos lá.

Bom antes de mais nada é preciso que você instale o seguinte pacote:
$ sudo apt-get install python-software-properties
Depois de feito isso vamos a velha e já boa conhecia atualização de repositórios :D. Basicamente para instalarmos o PostgreSQL 9.0 e o pgAdmin 1.12 precisamos utilizar os seguintes comandos:
$ sudo add-apt-repository ppa:pitti/postgresql                            $ sudo apt-get update                                                     $ sudo apt-get install postgresql-9.0 libpq-dev pgadmin3
Feito isso seu banco de dados já está em funcionamento e o pgAdmin já está instalado e possui um icone de atalho no seu menu. Mas mesmo depois disso ainda tive um problema ao tentar conectar no banco, não sei a senha :(.

Para isso basta digitar no terminal:
$ cd /etc/init.d/                                                          $ sudo -u postgres plsl postgres
Feito isso você estará no plql ai basta alterar a senha via linha de comando, que no meu caso mudei para postgres mesmo. Fiquei um bom tempo tentando o que os tutoriais indicavam para digitar o comando:
postgres=# ALTER USER postgres WITH PASSWORD 'postgres'                postgres=# \q
Mas o que funcionou mesmo foi um bem mais simples:
postgres=# \password postgres                                              Enter new password:                                                    Enter it again:                                                           postgres=# \q
Depois disso você ainda precisa realizar algumas configurações no seu banco de dados, para isso é necessário editar o arquivo postgresql.conf que está no diretório /etc/postgresql/9.0/main/, nele altere as seguintes linhas para:
listen_addresses = '*'                                              password_encryption = on
Desta forma, o PostgreSQL vai poder responder as requisições provenientes de outras máquinas e também cifrará as senhas. Lembre-se de remover o # para descomentar a linha. Mas você ainda precisa configurar o seu ip ou a rede que poderá acessar o banco de dados, para isso edite o arquivo pg_hba.conf no diretório /etc/postgresql/9.0/main/ e adicione a nova configuração lá em baixo, a minha por exemplo foi:
#My Ip                                                                   host    all      all             192.168.1.102/24         md5
Agora antes de reiniciar o serviço eu sugiro que você libere a edição dos arquivos de configuração do PostgreSQL usando o chmod, exemplo:
$ sudo chmod 777 /etc/postgresql/9.0/main/pg_hba.conf                     $ sudo chmod 777 /etc/postgresql/9.0/main/postgresql.conf 
Pronto agora você pode reiniciar o serviço e começar a usar
$ sudo /etc/init.d/postgresql restart
Exemplo da minha configuração no pgAdmin



domingo, 25 de julho de 2010

NS-2 - Instalando no Ubuntu 10.04

Bom se você é assim como eu que sempre quando vai começar algo novo e não faz nem idéia por onde começar, abre o navegador e busca por alguém tenha a mesma dúvida que a sua ou um tutorial de um nobre ser que gastou seu tempo para que nós meros mortais pudessemos continuar a boa e velha mata ehehehe (claro que não é bem assim mas...).

Bom mas vamos ao que interessa, neste post eu vou reescrever umas coisas que uma vez eu li no blog do arthurfurlan mas agora não o encontro mais. O tópico era sobre a instalação do Network Simulator no Ubuntu. Eu até procurei no Google e achei um outro post dele no Viva Linux que ele dava um geral (o do blog dele estava melhor ... tinha mais detalhes e comentários). Estranho que sumiu, bom foi por esse motivo que resolvi escrever o post parecido e aproveitando e já atualizando a versão do Ubuntu da 7.10 para a 10.04 e também a do NS-2.30 para NS-2.34.

Antes de tudo precisamos instalar alguns pacotes para poder compilar corretamente o NS-2.34.
$ sudo apt-get install build-essential autoconf automake libxmu-dev gcc-4.4
Próximo passo vamos baixar o NS-2.34.
$ wget http://ufpr.dl.sourceforge.net/sourceforge/nsnam/ns-allinone-2.34.tar.gz
Termiando o download podemos então descompactar os arquivos e finalmente instalar o Simulador de Rede.
$ tar xzvf ns-allinone-2.34.tar.gz                                        $ cd ns-allinone-2.34/                                                    $ ./install
Agora o NS-2 vai ser compilado e instalado no Ubuntu, isso demora alguns minutos então se quiser fazer outras coisas sinta-se a vontade.

Ao final se tudo ocorrer bem aparecerá no console para que você faça a validação da instalação mas se por algum a caso no processo de instalação for verificado algum erro, como por exemplo: make: *** [libotcl.so] Error 127 otcl-1.13 make failed! . Não se assute pode ser que na hora da compilação o compilador não foi selecionado corretamente, neste caso de uma olhada neste link que explica uma simples solução para o caso. Lembrando que em vez de usar a gcc-4.3 que ele demosntra use a gcc-4.4 que você baixou inicialmente.

Agora para que possamos usar o NS-2 normalmente teremos que configurar algumas variáveis de ambiente.
$ OTCL_LIB=~/ns-allinone-2.34/otcl-1.13                                   $ NS2_LIB=~/ns-allinone-2.34/lib                                          $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$OTCL_LIB:$NS2_LIB              $ export TCL_LIBRARY=~/ns-allinone-2.34/tcl8.4.18/library                 $ PATH=$PATH:~/ns-allinone-2.34/ns-2.34/
Feito isso podemos ir para faze final e validar a instação do NS-2. A já aviso que isso demora. Então se tiver que ir no mercado ou quiser assistir um filme vá em frente. Digite os comando no shell e bom divertimento.
$ cd ns-2.34/                                                             $ ./validate 
Pronto agora você tem o simulador instaldo no seu Ubuntu 10.04 e pode aproveitar para fazer suas modificações nos procolos ou mesmo se aventurar e implementar um nele como eu vou fazer eheheheh. Abraços e até a próxima.

domingo, 20 de junho de 2010

Hibernate - Visão básica das annotation

Bom é isso vamos a mais um post e desta vez vamos falar as anotações usando o Hibernate.

Antes de mais nada vale ressaltar que para você configurar o Hibernate na sua aplicação não necessariamente você precisa usar JPA, isto é, annotation ou anotações. As configurações do banco poderiam muito bem serem feitas usando os arquivos hbm.xml, mas como isso (no meu caso) é muito chato de fazer vamos para as annotation.

Para quem tiver o interesse ou já usa mas não sabe, o Hibernate oferece uma API que serve para eliminar de vez o uso dos complexos arquivos hbm.xml para simplificar o desenvolvimento das aplicações e facilitar a manutenção. Isso graças a vantagem de que toda essa configuração fica na classe e não em arquivos separados que em muitos caso não é de fácil entendimento.

1. @Id : é a anotação de atributo que o identifica como uma chave primaria.

2. @GeneratedValue  : é a anotação de atributo que faz com que a chave primaria tenha seu valor gerado automaticamente. em geral essa anotação vem acompanhada por @Id.

3. @Entity : é uma anotação de classe que diz que o objeto em questão possui uma tabela associada no banco de dados.

4. @Table (name="table") : anotação de classe que diz o nome da tabela a qual o objeto está mapeado. Ela não é obrigatória e por tanto se não for declara a tabela terá p mesmo nome do objeto.

5. @Column (name="column", nullable=false, length=32) : anotação de atributo que o relaciona a uma coluna da tabela atribuindo as características da coluna não poder conter um valor nulo e o seu tamanho não pode passar de 32 bytes. Essa anotação não é obrigatória e por tanto se não for declara a coluna terá o mesmo nome do atributo, podendo conter valor nulo de tamanho definido no banco.

6. @Lob : anotação de atributo que identifica que ele é um tipo Clob ou Blob.

7. @OneToMany (mappedBy="order", cascade=CascadeType.ALL, fech=FetchType.LAZY)
    @OrderBy (value="id ASC")
      - anotações de atributo que declaram que é uma relação de 1-N. A anotação @OrderBy não é obrigatória.

    @ManyToOne (cascade=CascadeType.REFRESH, optional=false)
    @JoinColumn (name="order_id")
       - anotação de atributo que declara que é uma relação de N-1. A anotação @JoinColumn só é necessário quando não houver explicitamente um campo que una as duas tabelas.

8. @Temporal (value=TemporalType.DATE) : anotação de atributo que descreve a precisão esperada no banco de dados.

9. @OneToOne (optional=true, cascade=CascadeType.ALL, mappedBy="person") : anotação de atributo que o associa a um objeto também mapeado por @Entity. Há casos em que é necessário utilizar a anotação @JoinColumn para dizer explicitamente a associação, exemplo:
   @OneToOne (optional=false, cascade=CascadeType.ALL, mappedBy="person")
   @JoinColumn (name="Person_ID", referencedColumnName="personid", unique=true)
    - anotação de atributo 1-1.

10. @ManyToMany (mappedBy="students") : anotação de atributo que declara que é uma relação de N-N. Há casos em que é necessário utilizar o @JoinColumn para dizer explicitamente a associação, exemplo:
     @ManyToMany (cascade=CascadeType.PERSIST, fetch=FeatchType.LAZY)
     @JoinColumn (name="Teacher_Student",
             joinColumns = (@JoinColumn (name="Teacher_ID", referencedColumnName="teacherid")),
             inverseJoinColumns = (@JoinColumn (name="Student_ID", referencedColumnName="Studentid")))

11. @Transient : anotação de atributo que que indica que ela não está mapeada na tabela e deve ser ignorada.

12. @Cache (usage=CacheConcurrencyStrategy.READ_WRITE) : anotação de classe que indica que para essa aplicação o objeto em questão usa cache.

terça-feira, 4 de maio de 2010

Pivot - Hello World com Maven

Saudações Rangos!

Esse post vai tratar de ajudar a fazer seu primeiro "hello world!" no Apache Pivot. Deve estar se perguntando o porque disso? Bom é simples. O tutorial que tem no site oficial está errado! E também vou aproveitar para dar uma desenferrujada e digitar um pouco ... eheheheh.

Bom para inicio de conversa eu estruturei meu exemplo no Maven. Porque? Porque eu gosto da maneira que o Maven gerencia minhas dependências de outros jars, segue o meu POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>net.sf.gaia.test</groupId>
    <artifactId>pivot-tutorial</artifactId>
    <name>Pivot Maven Tutorial</name>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.apache.pivot</groupId>
            <artifactId>pivot-core</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.pivot</groupId>
            <artifactId>pivot-wtk</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.pivot</groupId>
            <artifactId>pivot-web</artifactId>
            <version>1.4</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <inherited>true</inherited>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
    </build>
</project>


Basicamente no POM eu adicionei as dependências utilizada no tutorial para compilar a classe. E também adicionei o pluging para compilar utilizando o Java 6 com codificação de texto UTF-8.

A classe de exemplo eu usei a mesma que está no site oficial Apache Pivot - Hello World, mas segue ele ai:

package org.apache.pivot.tutorials;

import java.awt.Color;
import java.awt.Font;

import org.apache.pivot.collections.Map;
import org.apache.pivot.wtk.Application;
import org.apache.pivot.wtk.DesktopApplicationContext;
import org.apache.pivot.wtk.Display;
import org.apache.pivot.wtk.HorizontalAlignment;
import org.apache.pivot.wtk.Label;
import org.apache.pivot.wtk.VerticalAlignment;
import org.apache.pivot.wtk.Window;

public class HelloJava implements Application {
    private Window window = null;
 
    @Override
    public void startup(Display display, Map<String, String> properties) {
        Label label = new Label();
        label.setText("Hello World!");
        label.getStyles().put("font",
new Font("Arial", Font.BOLD, 24));
        label.getStyles().put("color", Color.RED);
        label.getStyles().put("horizontalAlignment", HorizontalAlignment.CENTER);
        label.getStyles().put("verticalAlignment", VerticalAlignment.CENTER);
 
        window = new Window();
        window.setContent(label);
        window.setTitle("Hello World!");
        window.setMaximized(true);
        window.open(display);
    }
 
    @Override
    public boolean shutdown(boolean optional) {
        if (window != null) {
            window.close();
        }
 
        return false;
    }
 
    @Override
    public void suspend() {
    }
 
    @Override
    public void resume() {
    }
 
    public static void main(String[] args) {
        DesktopApplicationContext.main(HelloJava.class, args);
    }
}


O que mais incomodo não foram nem o Maven e nem o classe. O que estava errado mesmo era o código HTML para adicionar a Applet e ver o exemplo funcionando. Tudo por causa de um que no tutorial era dito para usar o parâmetro "applicationClassName" quando na verdade era para ser usado "application_class_name". Esse simples troca já da uma dor de cabeça, segue como ficou:

<applet code="org.apache.pivot.wtk.BrowserApplicationContext$HostApplet" archive="lib/pivot-core-1.4.jar,lib/pivot-wtk-1.4.jar,lib/pivot-wtk-terra-1.4.jar,lib/pivot-tutorial-1.0-SNASHOT.jar" width="400" height="200" >
     <param name="application_class_name" value="org.apache.pivot.tutorials.HelloJava" >
</applet>