analytics

martes, 26 de marzo de 2019

Java JIRA API Ejemplo

Ejemplo JAVA para el API de JIRA


Veamos un ejemplo de como utilizar el API de JIRA desde Java

Empecemos con el fichero POM.XML

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>jirat</groupId>
    <artifactId>jirat</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>com....xxxxxx....Main</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>com.atlassian.fugue</groupId>
            <artifactId>fugue</artifactId>
            <version>2.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.6.4</version>
        </dependency>
        <dependency>
            <groupId>com.atlassian.jira</groupId>
            <artifactId>jira-rest-java-client</artifactId>
            <version>4.0.0</version>
            <exclusions>
                <exclusion>
                    <groupId>stax</groupId>
                    <artifactId>stax-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.atlassian.jira</groupId>
            <artifactId>jira-rest-java-client-core</artifactId>
            <version>4.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.atlassian.util.concurrent</groupId>
            <artifactId>atlassian-util-concurrent</artifactId>
            <version>2.6.2</version>
        </dependency>
    </dependencies>
    <repositories>
        <repository>
            <id>atlassian-public</id>
            <url>https://m2proxy.atlassian.com/repository/public</url>
            <snapshots>
                <enabled>true</enabled>
                <updatePolicy>daily</updatePolicy>
                <checksumPolicy>warn</checksumPolicy>
            </snapshots>
            <releases>
                <enabled>true</enabled>
                <checksumPolicy>warn</checksumPolicy>
            </releases>
        </repository>
    </repositories>
</project>


Y ahora veamos el código JAVA relacionado

import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.joining;
import static org.apache.http.client.utils.DateUtils.formatDate;

import com.atlassian.jira.rest.client.api.IssueRestClient;
import com.atlassian.jira.rest.client.api.JiraRestClient;
import com.atlassian.jira.rest.client.api.domain.BasicUser;
import com.atlassian.jira.rest.client.api.domain.Comment;
import com.atlassian.jira.rest.client.api.domain.Issue;
import com.atlassian.jira.rest.client.api.domain.SearchResult;
import com.atlassian.jira.rest.client.api.domain.Version;
import com.atlassian.jira.rest.client.api.domain.Worklog;
import com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.ExecutionException;
import java.util.stream.StreamSupport;

public class Main {
    private static final int PAGE_SIZE = 1000;

    public static void main(final String... args) throws URISyntaxException, 
ExecutionException, InterruptedException {
        final URI uri = new URI("URL DEL JIRA...");
        final AsynchronousJiraRestClientFactory factory = new 
AsynchronousJiraRestClientFactory();
        final JiraRestClient jira = factory.createWithBasicHttpAuthentication
(uri, "USER", "PASS");
        final IssueRestClient issueCli = jira.getIssueClient();

        final SearchResult rs = jira.getSearchClient().searchJql("status != 
closed AND updatedDate >= startOfWeek() AND status != dismissed AND status != 
\"QA validated\" AND status != aborted AND status != resolved AND assignee = 
USER ORDER BY updatedDate DESC").get();
        
    for (final Issue i : rs.getIssues())
            show(issueCli.getIssue(i.getKey()).get());

        System.out.printf("Hi!%n");
    }

    private static void show(final Issue i) {
        System.out.printf("== %s ===%n", i.getKey());
        System.out.printf("  Status .................. : %s%n", 
i.getStatus().getName());
        System.out.printf("  Summary ................. : %s%n", 
i.getSummary());
        System.out.printf("  FixVersions ............. : %s%n", 
ofNullable(i.getFixVersions()).map(t -> StreamSupport.stream(t.spliterator(), 
false).map(Version::getName).collect(joining(", "))).orElse("n/a"));
        System.out.printf("  Orig. estimated time .... : %s%n", 
ofNullable(i.getTimeTracking()).flatMap(t -> ofNullable(t.getOriginalEstimateMinutes())).map(t 
-> formatSeconds(60 * t)).orElse("n/a"));
        System.out.printf("  Rem. estimated time ..... : %s%n", 
ofNullable(i.getTimeTracking()).flatMap(t -> ofNullable(t.getRemainingEstimateMinutes())).map(t 
-> formatSeconds(60 * t)).orElse("n/a"));
        System.out.printf("  Spent time .............. : %s%n", 
ofNullable(i.getTimeTracking()).flatMap(t -> ofNullable(t.getTimeSpentMinutes())).map(t -> 
formatSeconds(60 * t)).orElse("n/a"));
        System.out.printf("  Comments:%n");
        for (final Comment c : i.getComments())
            System.out.printf("      %s (%s) %s%n",
                    formatDate(c.getUpdateDate().toDate(), "dd-MM-yy HH:mm:ss"),
                    ofNullable(c.getAuthor()).map(BasicUser::getDisplayName).orElse("n/a"),
                    "(body here)" //c.getBody()            );
        for (final Worklog w : i.getWorklogs())
            System.out.printf("%s%n", w.getAuthor().getDisplayName());
    }

    private static String formatSeconds(final Integer seconds) {
        if (seconds == null)
            return "(n/a)";
        final int s = seconds % 60;
        final int m = (seconds / 60) % 60;
        final int h = seconds / 60 / 60;
        return String.format("%d:%02d", h, m);
    }
}

lunes, 25 de marzo de 2019

Java CORS frontend backend seguridad

JAVA CORS Seguridad entre FRONTEND y BACKEND


El CORS es un sistema de seguridad para acceso a backend donde hay un API desde una dirección remota. (Por defecto, no se permite un acceso vía JSON, y para que funcione, se debe habilitar mediante una configuración del Tomcat)

Para el CORS, no conviene poner ninguna header a mano en el código desde el server, pero  sí que se debe configurar el tomcat, en el fichero web.xml añadiendo esto (de forma que el propio TOMCAT nos incluirá las header)


<filter>
   <filter-name>CorsFilter</filter-name>
   <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>CorsFilter</filter-name>
   <url-pattern> /* </url-pattern>
</filter-mapping>


y una llamada de ejemplo desde ajax, (obviamente, el backend espera recibir un JSON)

function testing(){
  var login = {
      username:'a@a.com',
      password:'a'
  }
  var toJson = JSON.stringify(login);
  alert(JSON.stringify(login));

  $.ajax({
  url: 'http://xxxxxxxxxx:8080/xxx/xxx/xxxx',
  dataType: 'json',
  type: 'post',
  data:JSON.stringify(login),
  contentType:"application/json",


  success: function( data, textStatus, jQxhr ){
      alert(JSON.stringify(data));
  },
  error: function( jqXhr, textStatus, errorThrown ){
      alert( errorThrown );
  }
} );
}

Java Tomcat Pool Datasources Resources

JAVA POOL DATASOURCES desde TOMCAT !!


    Vamos a ver cómo configurar un Datasource (conexión a Base de datos) para acceder a él desde nuestro código, pero configurado en Tomcat. Además, contaremos con un POOL de conexiones, de manera que los accesos a base de datos serán más eficientes.

En el fichero /conf/context.xml de TOMCAT, dentro de la sentencia <Context>, añadir el datasource:
<Resource name="jdbc/ConexionMySQL" auth="Container" type="javax.sql.DataSource"
       maxActive="20" maxIdle="10" maxWait="5000"
       username="xxxxx" password="xxxx#" driverClassName="com.mysql.jdbc.Driver"
       url="jdbc:mysql://xxxxxxxx:3306/xxxxxxx"/>

Por otro lado, en el /WEB-INF/web.xml, añadir lo siguiente dentro de <web-app>
<resource-ref>
   <description>Pool conexiones MySQL</description>
   <res-ref-name>jdbc/ConexionMySQL</res-ref-name>
   <res-type>javax.sql.DataSource</res-type>
   <res-auth>Container</res-auth>
</resource-ref>

Por último, así es como se obtiene conexión

public boolean conectar() {

   Context initContext;
   try {
       initContext = new InitialContext();
       DataSource ds = (DataSource) initContext.lookup("java:/comp/env/jdbc/ConexionMySQL");
       myCon = ds.getConnection();
       return true;
   } catch (SQLException ex) {
       logger.error("Error (" + ex.getErrorCode() + "): " + ex.getMessage());
       return false;
   } catch (NamingException ex) {
       logger.error("Error al intentar obtener el DataSource: " + ex.getMessage());
       return false;
   }

}