Sunday, December 30, 2018

Swagger getting started

At first I tried to go to http://editor.swagger.io/ , generate the Maven project to generate a RestEasy-EAP server, build and deploy to Wildfly 12.

There I got this error:


ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) WFLYCTL0013: Operation ("deploy") failed - address: ([("deployment" => "swagger-jaxrs-resteasy-eap-server-1.0.0.war")]) - failure description: {
"WFLYCTL0412: Required services that are not installed:" => [
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.Filter30Dispatcher\".START",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.faces.webapp.FacetTag\".START",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher\".START",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService",
"jboss.naming.context.java.module.\"swagger-jaxrs-resteasy-eap-server-1.0.0\".\"swagger-jaxrs-resteasy-eap-server-1.0.0\".DefaultDataSource",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.ScriptFreeTLV\".START",
"jboss.undertow.deployment.default-server.default-host./v2",
"jboss.naming.context.java.jboss.datasources.ExampleDS",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"com.sun.faces.config.ConfigureListener\".START",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.PermittedTaglibsTLV\".START"
],
"WFLYCTL0180: Services with missing/unavailable dependencies" => [
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher\".START is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.ScriptFreeTLV\".START is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.faces.webapp.FacetTag\".START is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService is missing [jboss.naming.context.java.module.\"swagger-jaxrs-resteasy-eap-server-1.0.0\".\"swagger-jaxrs-resteasy-eap-server-1.0.0\".DefaultDataSource]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.Filter30Dispatcher\".START is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.PermittedTaglibsTLV\".START is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService]",
"jboss.undertow.deployment.default-server.default-host./v2 is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"com.sun.faces.config.ConfigureListener\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.Filter30Dispatcher\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.ScriptFreeTLV\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.faces.webapp.FacetTag\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.PermittedTaglibsTLV\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher\".START]",
"jboss.naming.context.java.module.\"swagger-jaxrs-resteasy-eap-server-1.0.0\".\"swagger-jaxrs-resteasy-eap-server-1.0.0\".DefaultDataSource is missing [jboss.naming.context.java.jboss.datasources.ExampleDS]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"com.sun.faces.config.ConfigureListener\".START is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".jndiDependencyService]",
"jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".deploymentCompleteService is missing [jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"com.sun.faces.config.ConfigureListener\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.Filter30Dispatcher\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.ScriptFreeTLV\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.faces.webapp.FacetTag\".START, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"javax.servlet.jsp.jstl.tlv.PermittedTaglibsTLV\".START, jboss.undertow.deployment.default-server.default-host./v2, jboss.deployment.unit.\"swagger-jaxrs-resteasy-eap-server-1.0.0.war\".component.\"org.jboss.resteasy.plugins.server.servlet.HttpServlet30Dispatcher\".START]"
]
}



and the deployment fails. I felt discouraged and I turned to something simpler.

First I will implement my own Rest Service:

https://spring.io/guides/gs/rest-service/

then I run as http://localhost:8080/greeting

Then I move to adding Swagger to this REST webapp https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api.
I add the SwaggerConfig class with the @EnableSwagger2

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig {                                    
    @Bean
    public Docket api() { 
        return new Docket(DocumentationType.SWAGGER_2)  
          .select()                                  
          .apis(RequestHandlerSelectors.any())              
          .paths(PathSelectors.any())                          
          .build();                                           
    }
}



Here I see something comforting


s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/greeting]}" onto public org.springframework.gsrestservice.Greeting org.springframework.gsrestservice.GreetingController.greeting(java.lang.String)
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/swagger-resources/configuration/ui]}" onto public org.springframework.http.ResponseEntity<springfox.documentation.swagger.web.UiConfiguration> springfox.documentation.swagger.web.ApiResourceController.uiConfiguration()
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/swagger-resources]}" onto public org.springframework.http.ResponseEntity<java.util.List<springfox.documentation.swagger.web.SwaggerResource>> springfox.documentation.swagger.web.ApiResourceController.swaggerResources()
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/swagger-resources/configuration/security]}" onto public org.springframework.http.ResponseEntity<springfox.documentation.swagger.web.SecurityConfiguration> springfox.documentation.swagger.web.ApiResourceController.securityConfiguration()
pertySourcedRequestMappingHandlerMapping : Mapped URL path [/v2/api-docs] onto method [public


so now the endpoints are:

http://localhost:8080/greeting

http://localhost:8080/swagger-resources/configuration/ui

http://localhost:8080/swagger-resources/

http://localhost:8080/swagger-resources/configuration/security

http://localhost:8080/v2/api-docs


Then I add the io.springfox:springfox-swagger-ui:2.9.2 dependency

and I get the Swagger-UI at http://localhost:8080/swagger-ui.html

My code is available here https://github.com/vernetto/springbootrestswagger

The Baeldung code is here https://github.com/eugenp/tutorials/tree/master/spring-security-rest







Monday, December 24, 2018

Maven Artifact Resolver

https://github.com/shrinkwrap/resolver#introduction-to-shrinkwrap-resolvers

add dependency org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-depchain:3.1.3 (default scope, not test scope)

package org.pierre.artifactresolver;

import java.io.File;

import org.jboss.shrinkwrap.resolver.api.maven.Maven;

public class App 
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
        File[] files = Maven.resolver().resolve("org.apache.commons:commons-lang3:3.8.1").withTransitivity().asFile();
        for (File file : files) {
         System.out.println(file.getAbsolutePath());
        }
        
    }
}



this prints:


Hello World!
c:\pierre\.m2\repository\org\apache\commons\commons-lang3\3.8.1\commons-lang3-3.8.1.jar




Friday, December 14, 2018

Cleaning up old releases in Nexus 2 and 3

In Nexus 2 there is the task "remove releases from repository", where you can further refine the scope by specifying a "repository target" (=a filter).... problem is, the only option you have is the number of the most recent versions to retain.... there is no way to specify "delete all versions older than 2 years, but in any case keep the last 10".

I have written this Spring Boot utility https://github.com/vernetto/nexusclean to generate curl commands to delete artifacts based on multiple selection criteria. But it doesn't handle parent pom, which is a limitation.

Also, be aware that the curl command to delete a component, like

curl -u admin:admin123 -X "DELETE" -w "%{http_code}" http://localhost:8281/nexus/service/local/repositories/central/content/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7

every time rebuilds the index, which is very CPU intensive. There is no way to batch multiple deletes in a single transaction.


In Nexus 3

https://github.com/xninjaxelitex/nexus3-cleanup-release-artifact





Monday, December 10, 2018

Docker broken after upgrade

sudo systemctl start docker
Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.


sudo journalctl -xe


Error starting daemon: error initializing graphdriver: /var/lib/docker contains several valid graphdrivers: devicemapper, overlay2; Please cleanup or explicit

sudo vi /etc/docker/daemon.json

append this at the end and before the closed curly brace:

,"storage-driver": "devicemapper"



sudo systemctl reset-failed docker.service
sudo systemctl start docker.service




Thursday, November 29, 2018

Nexus repo validates Docker images on production.cloudflare.docker.com

In Nexus logs I find a lot of calls to production.cloudflare.docker.com:



2018-11-05 14:13:43,416+0100 DEBUG [qtp72695066-56] ADV org.sonatype.nexus.httpclient.outbound - https://production.cloudflare.docker.com/registry-v2/docker/registry/v2/blobs/sha256/4f/4fe2ade4980c2dda4fc95858ebb981489baec8c1e4bd282ab1c3560be8ff9bde/data?verify=1541426623-n%2BHbbRXN3Rr4k6Bxofrsv6tRVFw%3D > GET /registry-v2/docker/registry/v2/blobs/sha256/4f/4fe2ade4980c2dda4fc95858ebb981489baec8c1e4bd282ab1c3560be8ff9bde/data?verify=1541426623-n%2BHbbRXN3Rr4k6Bxofrsv6tRVFw%3D HTTP/1.1
2018-11-05 14:13:43,416+0100 DEBUG [qtp72695066-56] ADV org.sonatype.nexus.internal.httpclient.SharedHttpClientConnectionManager - Connection request: [route: {tls}->http://ourproxy:8080->https://production.cloudflare.docker.com:443][total kept alive: 1; route allocated: 0 of 20; total allocated: 3 of 200]
2018-11-05 14:13:43,417+0100 DEBUG [qtp72695066-56] ADV org.sonatype.nexus.internal.httpclient.SharedHttpClientConnectionManager - Connection leased: [id: 18][route: {tls}->http://ourproxy:8080->https://production.cloudflare.docker.com:443][total kept alive: 1; route allocated: 1 of 20; total allocated: 4 of 200]
2018-11-05 14:13:43,475+0100 DEBUG [qtp72695066-4467] ADV org.sonatype.nexus.httpclient.outbound - https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/alpine:pull < HTTP/1.1 200 OK @ 129.8 ms 2018-11-05 14:13:43,475+0100 DEBUG [qtp72695066-4467] ADV org.sonatype.nexus.repository.docker.internal.DockerProxyFacetImpl - Response: HttpResponseProxy{HTTP/1.1 200 OK [Content-Type: application/json, Date: Mon, 05 Nov 2018 13:13:43 GMT, Transfer-Encoding: chunked, Strict-Transport-Security: max-age=31536000, Connection: Keep-Alive] ResponseEntityProxy{[Content-Type: application/json,Chunked: true]}}


we access internet via a Proxy Server ourproxy, which doesn't whitelist production.cloudflare.docker.com

each of them creates a file in $NEXUS_DATA/tmp/docker-content-validation-failures with an "access denied" message from ourproxy

Here https://forums.docker.com/t/corporate-firewall-remote-error-tls-handshake-failure/52965 they say we should also whitelist production.cloudflare.docker.com

I have no idea if the "docker pull" will fail, or if this "validation" can be disabled...




See also https://support.sonatype.com/hc/en-us/articles/115015442847-Whitelisting-Docker-Hub-Hosts-for-Firewalls-and-HTTP-Proxy-Servers

Nexus repository location of license

If you move your Nexus repository to a new machine, it's quite annoying to have to reinstall the license file.

The trick is to clone the folder ~/.java/.userPrefs, specifically the license is embedded in

~/.java/.userPrefs/com/sonatype/nexus/professional/prefs.xml

and it's common for Nexus2 and Nexus3

I had searched everywhere for a .lic file, to no avail of course.


This is also documented here https://support.sonatype.com/hc/en-us/articles/115000779668-Methods-to-Install-a-Nexus-Repository-Manager-3-License

java showSettings

This is a priceless feature to display all the settings of the JVM, together with -XX:+PrintCommandLineFlags it can show a world of hidden stuff.


java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=261069952 -XX:MaxHeapSize=4177119232 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC 
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)





java -XshowSettings:all -version


  
VM settings:
    Max. Heap Size (Estimated): 3.46G
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM

Property settings:
    awt.toolkit = sun.awt.X11.XToolkit
    file.encoding = UTF-8
    file.encoding.pkg = sun.io
    file.separator = /
    java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment
    java.awt.printerjob = sun.print.PSPrinterJob
    java.class.path = .
    java.class.version = 52.0
    java.endorsed.dirs = /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el6_10.x86_64/jre/lib/endorsed
    java.ext.dirs = /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el6_10.x86_64/jre/lib/ext
        /usr/java/packages/lib/ext
    java.home = /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el6_10.x86_64/jre
    java.io.tmpdir = /tmp
    java.library.path = /usr/java/packages/lib/amd64
        /usr/lib64
        /lib64
        /lib
        /usr/lib
    java.runtime.name = OpenJDK Runtime Environment
    java.runtime.version = 1.8.0_191-b12
    java.specification.name = Java Platform API Specification
    java.specification.vendor = Oracle Corporation
    java.specification.version = 1.8
    java.vendor = Oracle Corporation
    java.vendor.url = http://java.oracle.com/
    java.vendor.url.bug = http://bugreport.sun.com/bugreport/
    java.version = 1.8.0_191
    java.vm.info = mixed mode
    java.vm.name = OpenJDK 64-Bit Server VM
    java.vm.specification.name = Java Virtual Machine Specification
    java.vm.specification.vendor = Oracle Corporation
    java.vm.specification.version = 1.8
    java.vm.vendor = Oracle Corporation
    java.vm.version = 25.191-b12
    line.separator = \n 
    os.arch = amd64
    os.name = Linux
    os.version = 2.6.32-754.el6.x86_64
    path.separator = :
    sun.arch.data.model = 64
    sun.boot.class.path = /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el6_10.x86_64/jre/lib/resources.jar
        /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el6_10.x86_64/jre/lib/rt.jar
        /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el6_10.x86_64/jre/lib/sunrsasign.jar
        /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el6_10.x86_64/jre/lib/jsse.jar
        /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el6_10.x86_64/jre/lib/jce.jar
        /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el6_10.x86_64/jre/lib/charsets.jar
        /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el6_10.x86_64/jre/lib/jfr.jar
        /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el6_10.x86_64/jre/classes
    sun.boot.library.path = /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el6_10.x86_64/jre/lib/amd64
    sun.cpu.endian = little
    sun.cpu.isalist = 
    sun.io.unicode.encoding = UnicodeLittle
    sun.java.launcher = SUN_STANDARD
    sun.jnu.encoding = UTF-8
    sun.management.compiler = HotSpot 64-Bit Tiered Compilers
    sun.os.patch.level = unknown
    user.country = US
    user.dir = /root
    user.home = /root
    user.language = en
    user.name = root
    user.timezone = 

Locale settings:
    default locale = English
    default display locale = English (United States)
    default format locale = English (United States)
    available locales = , ar, ar_AE, ar_BH, ar_DZ, ar_EG, ar_IQ, ar_JO, 
        ar_KW, ar_LB, ar_LY, ar_MA, ar_OM, ar_QA, ar_SA, ar_SD, 
        ar_SY, ar_TN, ar_YE, be, be_BY, bg, bg_BG, ca, 
        ca_ES, cs, cs_CZ, da, da_DK, de, de_AT, de_CH, 
        de_DE, de_GR, de_LU, el, el_CY, el_GR, en, en_AU, 
        en_CA, en_GB, en_IE, en_IN, en_MT, en_NZ, en_PH, en_SG, 
        en_US, en_ZA, es, es_AR, es_BO, es_CL, es_CO, es_CR, 
        es_CU, es_DO, es_EC, es_ES, es_GT, es_HN, es_MX, es_NI, 
        es_PA, es_PE, es_PR, es_PY, es_SV, es_US, es_UY, es_VE, 
        et, et_EE, fi, fi_FI, fr, fr_BE, fr_CA, fr_CH, 
        fr_FR, fr_LU, ga, ga_IE, hi, hi_IN, hr, hr_HR, 
        hu, hu_HU, in, in_ID, is, is_IS, it, it_CH, 
        it_IT, iw, iw_IL, ja, ja_JP, ja_JP_JP_#u-ca-japanese, ko, ko_KR, 
        lt, lt_LT, lv, lv_LV, mk, mk_MK, ms, ms_MY, 
        mt, mt_MT, nl, nl_BE, nl_NL, no, no_NO, no_NO_NY, 
        pl, pl_PL, pt, pt_BR, pt_PT, ro, ro_RO, ru, 
        ru_RU, sk, sk_SK, sl, sl_SI, sq, sq_AL, sr, 
        sr_BA, sr_BA_#Latn, sr_CS, sr_ME, sr_ME_#Latn, sr_RS, sr_RS_#Latn, sr__#Latn, 
        sv, sv_SE, th, th_TH, th_TH_TH_#u-nu-thai, tr, tr_TR, uk, 
        uk_UA, vi, vi_VN, zh, zh_CN, zh_HK, zh_SG, zh_TW
        
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)








Monday, November 26, 2018

Java and JGit

The Jgit library makes it REALLY easy to work with Git repositories.

Here a log of examples https://github.com/centic9/jgit-cookbook

https://www.baeldung.com/jgit

Just create a basic Spring boot application, add dependency

<dependency>
 <groupId>org.eclipse.jgit</groupId>
 <artifactId>org.eclipse.jgit</artifactId>
 <version>5.1.3.201810200350-r</version>
</dependency>


and use this code

package com.example.jgittest;

import java.io.File;
import java.io.PrintWriter;

import org.eclipse.jgit.api.AddCommand;
import org.eclipse.jgit.api.CommitCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.Repository;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class JgittestApplication  implements CommandLineRunner {

 public static void main(String[] args) {
  SpringApplication.run(JgittestApplication.class, args);
 }
 @Override
 public void run(String... args) throws Exception {
  File directory1 = new File("c:\\temp\\one");
  Git git1 = Git.init().setDirectory(directory1).call();
  File newFile = new File(directory1, "pippo.txt");
  PrintWriter out = new PrintWriter(newFile);
  out.println("hello pippo");
  out.close();
  Repository rep1 = git1.getRepository();
  AddCommand add = git1.add();
  add.addFilepattern("pippo.txt");
  System.out.println("adding pippo.txt");
  add.call();
  CommitCommand commit = git1.commit();
  System.out.println("committing pippo.txt");
  commit.setMessage("initial commit").call();
  
  File directory2 = new File("c:\\temp\\two");
  if (!directory2.exists()) {
   Git git2 = Git.cloneRepository().setURI("https://github.com/eclipse/jgit.git").setDirectory(directory2).call();
  }
  
  
 }
}



Saturday, November 24, 2018

Velocity and rendering JSONObjects or Java Beans

You can use a Velocity template to render either a JsonNode or its corresponding Java bean,
without changing the velocity template.

Code is available https://github.com/vernetto/velocityjson here (the .wm file location is hardcoded with a Widows machine, sorry!)



and the full code is visible here https://github.com/vernetto/velocityjson/blob/master/src/main/java/com/example/demo/VelocityApplication.java

BEWARE the velocity template is stored under the resources folder

The only funny thing is that in the JsonNode the values retain the ""

Wednesday, November 14, 2018

Jboss CLI, change individual attributes of a security domain without having to remove and add the domain from scratch

Jboss CLI, change individual attributes of a security domain without having to remove and add the domain from scratch


If you need for instance to update the baseFilter of the AdvancedAdLdap module:



In the custom cli, execute this command:



/subsystem=security/security-domain=SPNEGO/authentication=classic/login-module=AdvancedAdLdap:write-attribute(name=module-options.baseFilter,value="(sAMAccountName={0})")





and the baseFilter is updated:

<security-domain name="SPNEGO" cache-type="default">
 <authentication>
  <login-module code="SPNEGO" flag="requisite">
   <module-option name="password-stacking" value="useFirstPass"/>
   <module-option name="serverSecurityDomain" value="host"/>
  </login-module>
  <login-module code="AdvancedAdLdap" flag="required">
   <module-option name="password-stacking" value="useFirstPass"/>
   <module-option name="bindDN" value="BLA"/>
   <module-option name="bindCredential" value="BLA"/>
   <module-option name="java.naming.provider.url" value="BLA"/>
   <module-option name="baseCtxDN" value="BLA"/>
   <module-option name="baseFilter" value="(sAMAccountName={0})"/>
   <module-option name="roleAttributeID" value="memberOf"/>
   <module-option name="rolesCtxDN" value="BLA"/>
   <module-option name="roleAttributeIsDN" value="true"/>
   <module-option name="roleNameAttributeID" value="cn"/>
   <module-option name="searchScope" value="SUBTREE_SCOPE"/>
   <module-option name="recurseRoles" value="true"/>
  </login-module>
  <login-module code="org.jboss.security.auth.spi.RoleMappingLoginModule" flag="optional">
   <module-option name="rolesProperties" value="${jboss.server.config.dir}/bla-war/roles.properties"/>
   <module-option name="replaceRole" value="false"/>
  </login-module>
 </authentication>
</security-domain>


Tuesday, November 6, 2018

Centos 7 gnome-shell high CPU on VirtualBox

top shows very high CPU usage. and UI is very very slow.

googling around, they say it's probably doing "software" rendering. it makes sense because CPU goes higher when I move something on the screen

in /var/log/Xorg.0.log I find this:

(EE) Failed to load module "vboxvideo" (module does not exist, 0)
(II) AIGLX: Screen 0 is not DRI2 capable
(EE) AIGLX: reverting to software rendering


To investigate, I run
sudo glxinfo
sudo lshw -C video
sudo yum list | grep libnvidia
sudo yum list | grep libegl


the output of glxinfo is

name of display: :0
display: :0  screen: 0
direct rendering: Yes
server glx vendor string: Chromium
server glx version string: 1.3 Chromium
server glx extensions:
    GLX_ARB_get_proc_address, GLX_ARB_multisample, 
    GLX_EXT_texture_from_pixmap, GLX_SGIX_fbconfig
client glx vendor string: Chromium
client glx version string: 1.3 Chromium
client glx extensions:
    GLX_ARB_get_proc_address, GLX_ARB_multisample, 
    GLX_EXT_texture_from_pixmap, GLX_SGIX_fbconfig
GLX version: 1.3
GLX extensions:
    GLX_ARB_get_proc_address, GLX_ARB_multisample, 
    GLX_EXT_texture_from_pixmap, GLX_SGIX_fbconfig
OpenGL vendor string: Humper
OpenGL renderer string: Chromium
OpenGL version string: 2.1 Chromium 1.9
OpenGL shading language version string: 4.30 - Build 10.18.15.4248
OpenGL extensions:
    GL_ARB_depth_texture, GL_ARB_draw_buffers, GL_ARB_fragment_program, 
    GL_ARB_fragment_shader, GL_ARB_multisample, GL_ARB_multitexture, 
    GL_ARB_occlusion_query, GL_ARB_pixel_buffer_object, 
    GL_ARB_point_parameters, GL_ARB_point_sprite, GL_ARB_shader_objects, 
    GL_ARB_shading_language_100, GL_ARB_shadow, GL_ARB_texture_border_clamp, 
    GL_ARB_texture_compression, GL_ARB_texture_cube_map, 
    GL_ARB_texture_env_add, GL_ARB_texture_env_combine, 
    GL_ARB_texture_env_crossbar, GL_ARB_texture_env_dot3, 
    GL_ARB_texture_float, GL_ARB_texture_mirrored_repeat, 
    GL_ARB_texture_non_power_of_two, GL_ARB_texture_rectangle, 
    GL_ARB_transpose_matrix, GL_ARB_vertex_buffer_object, 
    GL_ARB_vertex_program, GL_ARB_vertex_shader, GL_ARB_window_pos, 
    GL_CR_bounding_box, GL_CR_cursor_position, GL_CR_head_spu_name, 
    GL_CR_performance_info, GL_CR_print_string, GL_CR_readback_barrier_size, 
    GL_CR_saveframe, GL_CR_server_id_sharing, GL_CR_server_matrix, 
    GL_CR_state_parameter, GL_CR_synchronization, GL_CR_tile_info, 
    GL_CR_tilesort_info, GL_CR_window_size, GL_EXT_blend_color, 
    GL_EXT_blend_equation_separate, GL_EXT_blend_func_separate, 
    GL_EXT_blend_minmax, GL_EXT_blend_subtract, GL_EXT_clip_volume_hint, 
    GL_EXT_compiled_vertex_array, GL_EXT_draw_range_elements, 
    GL_EXT_fog_coord, GL_EXT_framebuffer_blit, GL_EXT_framebuffer_object, 
    GL_EXT_multi_draw_arrays, GL_EXT_secondary_color, GL_EXT_shadow_funcs, 
    GL_EXT_stencil_two_side, GL_EXT_stencil_two_side, GL_EXT_stencil_wrap, 
    GL_EXT_texture3D, GL_EXT_texture_compression_s3tc, 
    GL_EXT_texture_edge_clamp, GL_EXT_texture_env_add, 
    GL_EXT_texture_env_combine, GL_EXT_texture_filter_anisotropic, 
    GL_EXT_texture_lod_bias, GL_EXT_texture_rectangle, GL_EXT_texture_sRGB, 
    GL_IBM_texture_mirrored_repeat, GL_NV_texgen_reflection, 
    GL_SGIS_generate_mipmap, GL_SGIS_texture_edge_clamp

1 GLX Visuals
    visual  x   bf lv rg d st  colorbuffer  sr ax dp st accumbuffer  ms  cav
  id dep cl sp  sz l  ci b ro  r  g  b  a F gb bf th cl  r  g  b  a ns b eat
----------------------------------------------------------------------------
0x021 24 tc  0  32  0 r  y y   8  8  8  8 .  .  0 24  8 16 16 16 16  0 0 None

1 GLXFBConfigs:
    visual  x   bf lv rg d st  colorbuffer  sr ax dp st accumbuffer  ms  cav
  id dep cl sp  sz l  ci b ro  r  g  b  a F gb bf th cl  r  g  b  a ns b eat
----------------------------------------------------------------------------
0x021 24 tc  0  32  0 r  y .   8  8  8  8 .  .  0 24  8  0  0  0  0  1 1 None

On VirtualBox, 3D acceleration is enabled.

So far no clue... the world of Linux Video drivers is amazingly complex... too complex for a simple human like me...



Monday, November 5, 2018

Message Digest Performance

If I use the dependency groupId=commons-codec artifactId=commons-codec I get a huge performance hit on the method:

sun.security.provider.MD5.implCompress(byte[], int)


the code is:


import org.apache.commons.codec.digest.DigestUtils;
import java.io.File;
import java.io.FileInputStream;

FileInputStream fis = new FileInputStream(file);
String md5 = DigestUtils.md5Hex(fis);
fis.close();


If I use sha2 https://www.baeldung.com/sha-256-hashing-java



Thursday, November 1, 2018

Spring Shell is very cool

If you are fed up with UI-oriented applications (like, say, Messus (a.k.a. Nexus) ) you can always try to embed a Spring-powered shell, so as to have a powerful scripting cli.

Just follow this example

https://docs.spring.io/spring-shell/docs/2.0.0.RELEASE/reference/htmlsingle/

and in a few clicks you have a functional shell.

BEWARE: baeldung has an example, but it's based on the old API. You will search in vain for Bootstrap class under org/springframework/shell

spring-shell-starter
spring-shell-core
spring-shell-standard
spring-shell-standard-commands
spring-shell-shell1-adapter
spring-shell-jcommander-adapter
spring-shell-table



Sunday, October 28, 2018

Hammering Nexus 3.14

first, create an entry in your settings.xml for mvn to be able to authenticate in nexus

<server>
<id>nexus</id>
<username>admin</username>
<password>admin123</password>
</server>

then write this testnexus.sh script:

NEXUSHOME=/home/centos/nexus314
NEXUSLOG=$NEXUSHOME/sonatype-work/nexus3/log/nexus.log
rm $NEXUSLOG

cd $NEXUSHOME/nexus-3.14.0-04/bin

for i in `seq 1 1000`;
do
 echo "Iteration number " $i
 #make sure nexus is not running before you start it
 ./nexus stop
 ./nexus start
 while [ ! -f $NEXUSLOG ] ;
 do
  sleep 2
 done
 
 echo "logfile found"
 tail -f $NEXUSLOG | while read LOGLINE
 do
  [[ "$LOGLINE" == *"Started Sonatype Nexus OSS 3.14.0-04"* ]] && pkill -P $$ tail
 done
 #now that it's up, let's wait for some time
 
 echo "nexus started"
 NEXUSPID=`ps -e -o pid,command | grep org.sonatype.nexus.karaf.NexusMain | grep -v grep | awk '{print $1}'`
 echo NEXUSPID = $NEXUSPID
 #wait for a random time before we kill
 sleep $[ ( $RANDOM % 100 )  + 10 ]
 ps -ef | grep nexus
 echo killing $NEXUSPID
 kill -9 $NEXUSPID
 mv $NEXUSLOG  ${NEXUSLOG}.${i}
done


and here the 2 scripts to upload continuously stuff to nexus

testnexusupload1.sh

NEXUSHOME=/home/centos/nexus314

curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.pom
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.jar
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.md5
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.sha1
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.pom.sha1
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.pom.md5
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.jar.sha1
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.jar.md5


mvn deploy:deploy-file -DgroupId=commons-beanutils -DartifactId=commons-beanutils -Dversion=1.9.2 -DgeneratePom=true -Dpackaging=jar -DrepositoryId=nexus -Durl=http://localhost:8081/repository/maven-releases -Dfile=$NEXUSHOME/nexus-3.14.0-04/system/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.jar


testnexusupload2.sh

NEXUSHOME=/home/centos/nexus314

curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-codec/commons-codec/1.10/commons-codec-1.10.pom
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-codec/commons-codec/1.10/commons-codec-1.10.jar
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-codec/commons-codec/1.10/commons-codec-1.10.md5
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-codec/commons-codec/1.10/commons-codec-1.10.sha1
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-codec/commons-codec/1.10/commons-codec-1.10.pom.sha1
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-codec/commons-codec/1.10/commons-codec-1.10.pom.md5
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-codec/commons-codec/1.10/commons-codec-1.10.jar.sha1
curl -X DELETE -u admin:admin123 http://localhost:8081/repository/maven-releases/commons-codec/commons-codec/1.10/commons-codec-1.10.jar.md5


mvn deploy:deploy-file -DgroupId=commons-codec -DartifactId=commons-codec -Dversion=1.10 -DgeneratePom=true -Dpackaging=jar -DrepositoryId=nexus -Durl=http://localhost:8081/repository/maven-releases -Dfile=$NEXUSHOME/nexus-3.14.0-04/system/commons-codec/commons-codec/1.10/commons-codec-1.10.jar


testnexusupload3.sh (this will create always new jars)

NEXUSHOME=/home/centos/nexus314
for i in `seq 1 1000000`;
do
 mvn deploy:deploy-file -DgroupId=commons-beanutils -DartifactId=commons-beanutils -Dversion=1.10.${i} -DgeneratePom=true -Dpackaging=jar -DrepositoryId=nexus -Durl=http://localhost:8081/repository/maven-releases -Dfile=$NEXUSHOME/nexus-3.14.0-04/system/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.jar

 sleep 2
done




nohup ./testnexusupload1.sh > ./testnexusupload1.log 2>&1 &
nohup ./testnexusupload2.sh > ./testnexusupload2.log 2>&1 &
nohup ./testnexusupload3.sh > ./testnexusupload3.log 2>&1 &

or

setsid ./testnexusupload1.sh > ./testnexusupload1.log 2>&1 &
setsid ./testnexusupload2.sh > ./testnexusupload2.log 2>&1 &
setsid ./testnexusupload3.sh > ./testnexusupload3.log 2>&1 &


This way with a continuous cycle of restarts I can test the stability of the repository.
If the DB or shards are corrupted we will find out...



In fact, after some iteration I keep getting this error at startup:




2018-10-28 19:04:49,571+0100 INFO [elasticsearch[C1896386-DD1B2DA2-9E77236C-5051BC20-E1D39AE4][clusterService#updateTask][T#1]] *SYSTEM org.elasticsearch.cluster.metadata - [C1896386-DD1B2DA2-9E77236C-5051BC20-E1D39AE4] [2e9a1e67e8a325bcd6ee9f6790ff6c769e791d56] creating index, cause [api], templates [], shards [1]/[0], mappings [component]
2018-10-28 19:04:49,955+0100 INFO [elasticsearch[C1896386-DD1B2DA2-9E77236C-5051BC20-E1D39AE4][clusterService#updateTask][T#1]] *SYSTEM org.elasticsearch.cluster.routing.allocation - [C1896386-DD1B2DA2-9E77236C-5051BC20-E1D39AE4] Cluster health status changed from [RED] to [GREEN] (reason: [shards started [[2e9a1e67e8a325bcd6ee9f6790ff6c769e791d56][0]] ...]).
2018-10-28 19:04:50,065+0100 INFO [quartz-2-thread-1] *SYSTEM org.sonatype.nexus.repository.search.SearchFacetImpl - Rebuilding index of repository maven-central
2018-10-28 19:04:50,501+0100 INFO [elasticsearch[C1896386-DD1B2DA2-9E77236C-5051BC20-E1D39AE4][clusterService#updateTask][T#1]] *SYSTEM org.elasticsearch.cluster.metadata - [C1896386-DD1B2DA2-9E77236C-5051BC20-E1D39AE4] [73ae44bc066b6a7a33b4435641d8229b9b66495a] creating index, cause [api], templates [], shards [1]/[0], mappings [component]
2018-10-28 19:04:50,943+0100 ERROR [Thread-44 <command>sql.select from component where bucket = :bucket</command>] *SYSTEM com.orientechnologies.orient.core.storage.impl.local.paginated.OLocalPaginatedStorage - Exception `32DA9B7B` in storage `plocal:/home/centos/nexus314/sonatype-work/nexus3/db/component`: 2.2.36 (build d3beb772c02098ceaea89779a7afd4b7305d3788, branch 2.2.x)
com.orientechnologies.orient.core.exception.OCommandExecutionException: Error on execution of command: sql.select from component where bucket = :bucket
DB name="component"
at com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage.executeCommand(OAbstractPaginatedStorage.java:3421)
at com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage.command(OAbstractPaginatedStorage.java:3318)
at com.orientechnologies.orient.core.sql.query.OSQLQuery.run(OSQLQuery.java:78)
at com.orientechnologies.orient.core.sql.query.OSQLAsynchQuery.run(OSQLAsynchQuery.java:74)
at com.orientechnologies.orient.core.query.OQueryAbstract.execute(OQueryAbstract.java:33)
at com.orientechnologies.orient.core.sql.query.OSQLNonBlockingQuery$1.run(OSQLNonBlockingQuery.java:283)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException: null
at com.orientechnologies.orient.core.serialization.serializer.binary.impl.index.OCompositeKeySerializer.deserializeFromByteBufferObject(OCompositeKeySerializer.java:347)
at com.orientechnologies.orient.core.serialization.serializer.binary.impl.index.OCompositeKeySerializer.deserializeFromByteBufferObject(OCompositeKeySerializer.java:46)
at com.orientechnologies.orient.core.storage.impl.local.paginated.base.ODurablePage.deserializeFromDirectMemory(ODurablePage.java:166)
at com.orientechnologies.orient.core.index.sbtree.local.OSBTreeBucket.getKey(OSBTreeBucket.java:266)
at com.orientechnologies.orient.core.index.sbtree.local.OSBTreeBucket.find(OSBTreeBucket.java:134)
at com.orientechnologies.orient.core.index.sbtree.local.OSBTree.findBucket(OSBTree.java:1679)
at com.orientechnologies.orient.core.index.sbtree.local.OSBTree.access$2800(OSBTree.java:69)
at com.orientechnologies.orient.core.index.sbtree.local.OSBTree$OSBTreeCursorForward.next(OSBTree.java:1991)
at com.orientechnologies.orient.core.index.engine.OSBTreeIndexEngine$OSBTreeIndexCursor.nextEntry(OSBTreeIndexEngine.java:271)
at com.orientechnologies.orient.core.index.OIndexAbstractCursor.hasNext(OIndexAbstractCursor.java:83)
at com.orientechnologies.orient.core.index.OIndexChangesWrapper.hasNext(OIndexChangesWrapper.java:138)
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.serialIterator(OCommandExecutorSQLSelect.java:1636)
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.fetchFromTarget(OCommandExecutorSQLSelect.java:1585)
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.fetchValuesFromIndexCursor(OCommandExecutorSQLSelect.java:2466)
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.searchForIndexes(OCommandExecutorSQLSelect.java:2280)
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.searchInClasses(OCommandExecutorSQLSelect.java:1017)
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLResultsetAbstract.assignTarget(OCommandExecutorSQLResultsetAbstract.java:203)
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.assignTarget(OCommandExecutorSQLSelect.java:527)
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.executeSearch(OCommandExecutorSQLSelect.java:509)
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLSelect.execute(OCommandExecutorSQLSelect.java:485)
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLDelegate.execute(OCommandExecutorSQLDelegate.java:70)
at com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage.executeCommand(OAbstractPaginatedStorage.java:3400)
... 6 common frames omitted






This seems a known issue with a workaround/solution


https://issues.sonatype.org/browse/NEXUS-18036

java -jar ./nexus-3.14.0-04/lib/support/nexus-orient-console.jar

connect plocal:/home/centos/nexus314/sonatype-work/nexus3/db/component/ admin admin


Disconnecting from the database [null]...OK
Connecting to database [plocal:/home/centos/nexus314/sonatype-work/nexus3/db/component/] with user 'admin'...
2018-10-28 23:42:11:147 WARNI {db=component} Storage 'component' was not closed properly. Will try to recover from write ahead log... [OLocalPaginatedStorage]
2018-10-28 23:42:11:192 WARNI {db=component} Record com.orientechnologies.orient.core.storage.impl.local.paginated.wal.OCheckpointEndRecord{lsn=LSN{segment=105, position=52}} will be skipped during data restore [OLocalPaginatedStorage]
2018-10-28 23:42:11:247 WARNI {db=component} Record OFuzzyCheckpointStartRecord{lsn=LSN{segment=105, position=59}} com.orientechnologies.orient.core.storage.impl.local.paginated.wal.OFuzzyCheckpointStartRecord{lsn=null, previousCheckpoint=LSN{segment=105, position=28}} will be skipped during data restore [OLocalPaginatedStorage]
2018-10-28 23:42:11:248 WARNI {db=component} Record com.orientechnologies.orient.core.storage.impl.local.paginated.wal.OFuzzyCheckpointEndRecord{lsn=LSN{segment=105, position=99}} will be skipped during data restore [OLocalPaginatedStorage]OK



repair database --fix-links

Repairing database...
- Removing broken links...
-- Done! Fixed links: 2, modified documents: 2
Repair database complete (0 errors)


rebuild index *


Rebuilding index(es)...
Rebuilt index(es). Found 4354 link(s) in 36.727001 sec(s).


Index(es) rebuilt successfully


disconnect
exit






Wednesday, October 24, 2018

Importing and exporting dictionaries in XL-Deploy

XebiaLab XL-Deploy is a great tool, but definitely lacking important features as far as versioning and exporting/importing configuration.

If you need to programmatically generate a Dictionary (rather than using the painfully limited UI), you can take a look at this code https://github.com/xebialabs-community/xld-aws-ecs-plugin/blob/master/src/test/resources/docker/initialize/exportCIs.py


In my case, I create a dictionary "pippo.dict" with a couple of keys (pippo, paperino...)

then from the cli:

mypippo=repository.searchByName('pippo.dict')
print mypippo
['Environments/pippo/pippo.dict']

repository.exportCisAndWait('Environments/pippo/pippo.dict')
export/pippo.dict_2018-10-24_16-36-45_045.zip



then

cd /home/centos/xldeploy/xl-deploy-8.2.0-server/export
unzip pippo.dict_2018-10-24_16-36-45_045.zip
cat configuration-items.xml


there are several entries <entry key="pippo">pluto</entry>

you can add/delete/edit those entries, then create a new file (with a slightly different name, 56 instead of 36):

zip pippo.dict_2018-10-24_16-56-45_045.zip configuration-items.xml

and in the CLI:

repository.importCisAndWait('export/pippo.dict_2018-10-24_16-56-45_045.zip')

and lo and behold, the updated properties are in the dictionary!







Friday, October 19, 2018

Getting configuration information from Nexus FOR FREE

One VERY SIMPLE way to log all the Nexus 3 configuration in the nexus.log is to enable debug logging (Administration/Logging/ set the ROOT logger at DEBUG level), then navigate to the Repositories/Roles/Users administration page. You will see that precious JSON is logged in nexus.log, containing all the most minute details of the Repositories/Roles/User configuration.

Programmatically you can achieve the same with a HTTP POST to http://mynexusserver:8081/service/extdirect with this JSON request, Content-Type application/json

[{"action":"coreui_Blobstore","method":"read","data":null,"type":"rpc","tid":104},{"action":"coreui_Repository","method":"read","data":null,"type":"rpc","tid":105},{"action":"coreui_Repository","method":"readRecipes","data":null,"type":"rpc","tid":106},{"action":"coreui_Repository","method":"readReferences","data":[{"page":1,"start":0,"limit":25}],"type":"rpc","tid":107},{"action":"coreui_Repository","method":"read","data":null,"type":"rpc","tid":108}]





[{"action":"coreui_User","method":"read","data":[{"filter":[{"property":"source","value":"default"},{"property":"userId","value":""}],"page":1,"start":0,"limit":100}],"type":"rpc","tid":63},{"action":"coreui_User","method":"readSources","data":null,"type":"rpc","tid":64},{"action":"coreui_Role","method":"read","data":null,"type":"rpc","tid":65},{"action":"coreui_User","method":"read","data":[{"page":1,"start":0,"limit":100}],"type":"rpc","tid":66}]



It would be really cool if such API was made available through SwaggerUI... Nexus 3 is very very primitive as far as API is concerned.

Internally, those actions coreui_Blobstore , coreui_User, coreui_Repository are mapped this way:

action class 'org.sonatype.nexus.coreui.UserComponent' mapped to 'coreui_User'

action class 'org.sonatype.nexus.coreui.RepositoryComponent' mapped to 'coreui_Repository'

action class 'org.sonatype.nexus.coreui.BlobStoreComponent' mapped to 'coreui_Blobstore'


which are in the plugin/nexus-coreui-plugin area as Groovy classes (this for Nexus 3.10... I think in Nexus 3.13 things have changed..)







Wednesday, October 17, 2018

bintray endless redirection for repo.scala-sbt.org

The Scala folks running this repository don't seem to understand the importance of running their stuff behind a Proxy Server, so that all elements come from the same domain.... instead, they send you HTTP 302 (MOVED) and force you to hop from repo.scala-sbt.org to dl.bintray.com and then to akamai.bintray.com .... which is outrageously cumbersome if you run your Nexus repository from behind a Firewall, then you have to open individually each subdomain... otherwise you end up with the dreaded " HTTP/1.1 407 Proxy Authentication Required "



2018-10-16 16:21:19,993+0200 DEBUG [qtp72695066-17874] *UNKNOWN org.sonatype.nexus.httpclient.outbound - https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/jars/sbt-native-packager.jar > GET /scalasbt/sbt-plugin-releases/com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/jars/sbt-native-packager.jar HTTP/1.1

2018-10-16 16:21:20,102+0200 DEBUG [qtp72695066-17874] *UNKNOWN org.sonatype.nexus.httpclient.outbound - https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/jars/sbt-native-packager.jar < HTTP/1.1 302 Moved Temporarily @ 108.4 ms 2018-10-16 16:21:20,102+0200 DEBUG [qtp72695066-17874] *UNKNOWN org.sonatype.nexus.httpclient.outbound - https://dl.bintray.com/sbt/sbt-plugin-releases/com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/jars/sbt-native-packager.jar > GET /sbt/sbt-plugin-releases/com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/jars/sbt-native-packager.jar HTTP/1.1

2018-10-16 16:21:20,193+0200 DEBUG [qtp72695066-17874] *UNKNOWN org.sonatype.nexus.httpclient.outbound - https://dl.bintray.com/sbt/sbt-plugin-releases/com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/jars/sbt-native-packager.jar < HTTP/1.1 302 @ 90.77 ms 2018-10-16 16:21:20,195+0200 DEBUG [qtp72695066-17874] *UNKNOWN org.sonatype.nexus.httpclient.outbound - https://akamai.bintray.com/3f/3f786b85a05e14c7ed5c24fbefbee19fbaa345e1db5d16fa9fa348c2a4e4789e?__gda__=exp=1539700400~hmac=9d5b250bffebb7cedf93ef28933b588c8788e9a7b20415dbe12e255435bf5ede&response-content-disposition=attachment%3Bfilename%3D%22sbt-native-packager.jar%22&response-content-type=application%2Fjava-archive&requestInfo=U2FsdGVkX1_tU3jkSNxcBb5JrmKzZS9pVZUOhb41Zj_AapUhiUGbx2fl-2B2bTDZvRaC1DmJfpw37KETEYGfMyBkdRqY-gknijMaFBx-HSJPsgC4aYd6Ejwpe2uzTSrTmhIF7HIgBbnG6hm8PxLHTvaGWPkWDnEacMK9-YMvxz8zphO4eHB46kniHIOc-vop&response-X-Checksum-Sha1=f8ab68145e3a23da45be0847f114065aa2fc0f54&response-X-Checksum-Sha2=3f786b85a05e14c7ed5c24fbefbee19fbaa345e1db5d16fa9fa348c2a4e4789e > GET /3f/3f786b85a05e14c7ed5c24fbefbee19fbaa345e1db5d16fa9fa348c2a4e4789e?__gda__=exp=1539700400~hmac=9d5b250bffebb7cedf93ef28933b588c8788e9a7b20415dbe12e255435bf5ede&response-content-disposition=attachment%3Bfilename%3D%22sbt-native-packager.jar%22&response-content-type=application%2Fjava-archive&requestInfo=U2FsdGVkX1_tU3jkSNxcBb5JrmKzZS9pVZUOhb41Zj_AapUhiUGbx2fl-2B2bTDZvRaC1DmJfpw37KETEYGfMyBkdRqY-gknijMaFBx-HSJPsgC4aYd6Ejwpe2uzTSrTmhIF7HIgBbnG6hm8PxLHTvaGWPkWDnEacMK9-YMvxz8zphO4eHB46kniHIOc-vop&response-X-Checksum-Sha1=f8ab68145e3a23da45be0847f114065aa2fc0f54&response-X-Checksum-Sha2=3f786b85a05e14c7ed5c24fbefbee19fbaa345e1db5d16fa9fa348c2a4e4789e HTTP/1.1

2018-10-16 16:21:20,204+0200 DEBUG [qtp72695066-17874] *UNKNOWN org.sonatype.nexus.httpclient.outbound - https://akamai.bintray.com/3f/3f786b85a05e14c7ed5c24fbefbee19fbaa345e1db5d16fa9fa348c2a4e4789e?__gda__=exp=1539700400~hmac=9d5b250bffebb7cedf93ef28933b588c8788e9a7b20415dbe12e255435bf5ede&response-content-disposition=attachment%3Bfilename%3D%22sbt-native-packager.jar%22&response-content-type=application%2Fjava-archive&requestInfo=U2FsdGVkX1_tU3jkSNxcBb5JrmKzZS9pVZUOhb41Zj_AapUhiUGbx2fl-2B2bTDZvRaC1DmJfpw37KETEYGfMyBkdRqY-gknijMaFBx-HSJPsgC4aYd6Ejwpe2uzTSrTmhIF7HIgBbnG6hm8PxLHTvaGWPkWDnEacMK9-YMvxz8zphO4eHB46kniHIOc-vop&response-X-Checksum-Sha1=f8ab68145e3a23da45be0847f114065aa2fc0f54&response-X-Checksum-Sha2=3f786b85a05e14c7ed5c24fbefbee19fbaa345e1db5d16fa9fa348c2a4e4789e < HTTP/1.1 407 Proxy Authentication Required @ 9.761 ms




Monday, October 15, 2018

backing up the Nexus configuration

Using the built-in procedure is risky - to say the least. I was unable to make it work (the restore part, I mean).

You can do this (see https://stackoverflow.com/a/45986526/651288 ):

java -jar /opt/sonatype/nexus/lib/support/nexus-orient-console.jar

CONNECT create database plocal:/home/centos/nexus310/sonatype-work/nexus3/db/component admin admin

#to export, use this:
export database component-export



#to import, use this:
drop database
create database plocal:/home/centos/nexus310/sonatype-work/nexus3/db/component
import database component-export.json.gz


I also do this:

gunzip component-export.json.gz
python -m json.tool component-export.json > component-exportPRETTY.json


and the JSON file is quite readable, probably you can even stick it into a Git repo and relax.

just replace "component" with "config" and do all over again, to backup the configuration

From an operational point of view, Nexus 3 is simply too fragile.

Installing JIRA

https://www.atlassian.com/software/jira/download
Linux 64 bit

cd Downloads
sudo ./atlassian-jira-software-7.12.3-x64.bin
Unpacking JRE ...
Starting Installer ...

This will install JIRA Software 7.12.3 on your computer.
OK [o, Enter], Cancel [c]

Choose the appropriate installation or upgrade option.
Please choose one of the following:
Express Install (use default settings) [1], Custom Install (recommended for advanced users) [2, Enter], Upgrade an existing JIRA installation [3]
1
Details on where JIRA Software will be installed and the settings that will be used.
Installation Directory: /opt/atlassian/jira 
Home Directory: /var/atlassian/application-data/jira 
HTTP Port: 8080 
RMI Port: 8005 
Install as service: Yes 
Install [i, Enter], Exit [e]
i

Extracting files ...
                                                                           

Please wait a few moments while JIRA Software is configured.
Installation of JIRA Software 7.12.3 is complete
Start JIRA Software 7.12.3 now?
Yes [y, Enter], No [n]
y

Please wait a few moments while JIRA Software starts up.
Launching JIRA Software ...
Installation of JIRA Software 7.12.3 is complete
Your installation of JIRA Software 7.12.3 is now ready and can be accessed
via your browser.
JIRA Software 7.12.3 can be accessed at http://localhost:8080
Finishing installation ...


http://localhost:8080

generating the evaluation license key is very simple (you should create an account with Atlassian)

the product is installed for user "jira":
sudo su - jira

logs are in /opt/atlassian/jira/logs/


To troubleshoot webhooks, you should enable DEBUG loggin as default in http://localhost:8080/secure/admin/ViewLogging.jspa
then you see the webhook body being traced in /opt/atlassian/jira/logs/catalina.out

Start and stop:
sudo /etc/init.d/jira start
sudo /etc/init.d/jira stop





Spring Boot vault

https://dzone.com/articles/managing-secrets-with-vault

which is basically same as https://spring.io/blog/2016/06/24/managing-secrets-with-vault



More JIRA on Docker

See also https://www.javamonamour.org/2017/11/jira-on-docker-and-integration-with.html


docker run -d -p 8080:8080 cptactionhank/atlassian-jira:7.7.0


I need to install netstat, but I have no root access (root pw is not given), so I do:

docker exec -ti --user root elastic_agnesi /bin/sh

and I get this strange error:

OCI runtime exec failed: exec failed: container_linux.go:348: starting container process caused "chdir to cwd (\"/var/atlassian/jira\") set in config.json failed: permission denied": unknown


woorkaround:

docker exec -ti elastic_agnesi /bin/sh
chmod 777 .
chmod 777 ..
exit

and try again connecting as root.... I have no idea why, but this time it works....

Then as root do

apt install net-tools

Then I discover that only tcp (not tcp6) ports are available, because the image doesn't support IPv6 : "cat /proc/net/if_inet6" returns nothing.

Now I start my webhook intercepting application with IPv4

java -Djava.net.preferIPv4Stack=true -jar bla.jar

before:

[centos@localhost ~]$ netstat -an | grep 8090
tcp6 0 0 :::8090 :::* LISTEN

after:

[centos@localhost ~]$ netstat -an | grep 8090
tcp 0 0 0.0.0.0:8090 0.0.0.0:* LISTEN

but still curl -X POST http://localhost:8090/greeting is not working... I am giving up and will install JIRA directly on host....







Sunday, October 14, 2018

Material UI and Spring Boot




https://material-ui.com/getting-started/installation/

download latest NPM here https://nodejs.org/en/ (10.12.0-CURRENT)

npx create-react-app react-material-ui
cd react-material-ui/
npm install @material-ui/core
npm install contentful





One can use rthis sample https://github.com/mui-org/material-ui/tree/master/examples/cdn

https://github.com/mui-org/material-ui

https://material.io/design/components/data-tables.html#usage



Wednesday, October 10, 2018

Nexus Groovy scripting

Huge issue in Nexus is that you can't export/import your Users/Groups/Privileges and Repository configuration. All you can do is to take a "backup", which ends of in a folder as a completely unreadable/unversionable format.

So I was looking for

when you run a Groovy script in Nexus, you have available a predefined variable "repository", which is of type org.sonatype.nexus.script.plugin.internal.provisioning.RepositoryApiImpl

This in turn contains a reference to a blobStoreManager org.sonatype.nexus.blobstore.api.BlobStoreManager and to a repositoryManager org.sonatype.nexus.repository.manager.RepositoryManager , plus a series of convenience methods to create commonly used repository formats (you are not expected to create anything fancy, most properties are assigned by default) and groups.

Key element is a org.sonatype.nexus.repository.config.Configuration object, again very disappointing since the configuration is represented by a "attribute" map (String, Map(String, Object)) which is really a stupid idea, too generic interface.

RepositoryManager has a Iterable<Repository> browse(); which returns a collection of org.sonatype.nexus.repository.Repository

Sample script:

import org.sonatype.nexus.repository.Repository

repository.repositoryManager.browse().each { Repository repo ->
    log.info("Repository: $repo")
    log.info("Repository Configuration: $repo.configuration")
}


this dumps in nexus.log the following content:

Repository: RepositoryImpl$$EnhancerByGuice$$c5f0822b{type=proxy, format=nuget, name='nuget.org-proxy'}
Repository Configuration: Configuration{repositoryName='nuget.org-proxy', recipeName='nuget-proxy', attributes={proxy={strictContentTypeValidation=true, contentMaxAge=1440, remoteUrl=https://www.nuget.org/api/v2/, metadataMaxAge=1440}, negativeCache={}, storage={blobStoreName=default}, nugetProxy={}, httpclient={connection={blocked=false, autoBlock=true}}}}

Repository: RepositoryImpl$$EnhancerByGuice$$c5f0822b{type=hosted, format=maven2, name='maven-releases'}
Repository Configuration: Configuration{repositoryName='maven-releases', recipeName='maven2-hosted', attributes={maven={versionPolicy=RELEASE, layoutPolicy=STRICT}, storage={writePolicy=ALLOW_ONCE, strictContentTypeValidation=false, blobStoreName=default}}}

Repository: RepositoryImpl$$EnhancerByGuice$$c5f0822b{type=hosted, format=maven2, name='maven-snapshots'}
Repository Configuration: Configuration{repositoryName='maven-snapshots', recipeName='maven2-hosted', attributes={maven={versionPolicy=SNAPSHOT, layoutPolicy=STRICT}, storage={writePolicy=ALLOW, strictContentTypeValidation=false, blobStoreName=default}}}

Repository: RepositoryImpl$$EnhancerByGuice$$c5f0822b{type=proxy, format=maven2, name='maven-central'}
Repository Configuration: Configuration{repositoryName='maven-central', recipeName='maven2-proxy', attributes={proxy={contentMaxAge=-1, remoteUrl=https://repo1.maven.org/maven2/, metadataMaxAge=1440}, negativeCache={timeToLive=1440, enabled=true}, storage={strictContentTypeValidation=false, blobStoreName=default}, maven-indexer={}, httpclient={connection={blocked=false, autoBlock=true}}, maven={versionPolicy=RELEASE, layoutPolicy=PERMISSIVE}}}

Repository: RepositoryImpl$$EnhancerByGuice$$c5f0822b{type=group, format=nuget, name='nuget-group'}
Repository Configuration: Configuration{repositoryName='nuget-group', recipeName='nuget-group', attributes={storage={blobStoreName=default}, nugetProxy={}, httpclient={}, group={memberNames=[nuget-hosted, nuget.org-proxy]}}}

Repository: RepositoryImpl$$EnhancerByGuice$$c5f0822b{type=hosted, format=nuget, name='nuget-hosted'}
Repository Configuration: Configuration{repositoryName='nuget-hosted', recipeName='nuget-hosted', attributes={storage={writePolicy=ALLOW, blobStoreName=default}}}

Repository: RepositoryImpl$$EnhancerByGuice$$c5f0822b{type=group, format=maven2, name='maven-public'}
Repository Configuration: Configuration{repositoryName='maven-public', recipeName='maven2-group', attributes={maven={versionPolicy=MIXED}, group={memberNames=[maven-releases, maven-snapshots, maven-central]}, storage={blobStoreName=default}}}





which is pretty good result, at least you can capture in one go all the configuration of all your repositories.



This task will delete all your repos:

import org.sonatype.nexus.repository.Repository

repository.repositoryManager.browse().each { Repository repo ->
    log.info("DELETE Repository: $repo")
    repository.repositoryManager.delete("$repo.name")
}


All the predefined variables are

core which is a org.sonatype.nexus.internal.provisioning.CoreApiImpl

repository which is a org.sonatype.nexus.script.plugin.internal.provisioning.RepositoryApiImpl

blobStore which is a org.sonatype.nexus.internal.provisioning.BlobStoreApiImpl
createFileBlobStore(final String name, final String path)
org.sonatype.nexus.blobstore.api.BlobStoreManager blobStoreManager 

security which is a org.sonatype.nexus.security.internal.SecurityApiImpl
User addUser(final String id, final String firstName, final String lastName, final String email, final boolean active,
final String password, final List roleIds)
Role addRole(final String id, final String name, final String description, final List privileges,
final List roles)
User setUserRoles(final String userId, final List roleIds)

If you do security.getSecuritySystem() you get an instance of this:
https://github.com/sonatype/nexus-public/blob/master/components/nexus-security/src/main/java/org/sonatype/nexus/security/SecuritySystem.java


Good is that if you clone the github repo nexus-book-examples you can directly open the APIs in file:///home/centos/gitclones/nexus-book-examples/scripting/apidocs/index.html


List all users with their roles

import groovy.json.JsonOutput
users = security.getSecuritySystem().listUsers()
userjson = JsonOutput.toJson(users)
log.info("USERS $userjson")


or also

import org.sonatype.nexus.security.user.UserSearchCriteria

users = security.getSecuritySystem().searchUsers(new UserSearchCriteria())
log.info("users=" + users)


Add users and roles:

privileges = [
            "nx-search-read",
            "nx-repository-view-*-*-read",
            "nx-repository-view-*-*-browse",
            "nx-repository-view-*-*-add",
            "nx-repository-view-*-*-edit",
"nx-apikey-all"]

security.addRole("deployer", "deployer", "deployment on all repositories", privileges, [])

security.addUser(userName, firstName, lastName, email, true, password, ["deployer"])



creating blobstores:


def list = ["dockerGroup", "mynpm", "pippo", "ivy", "dockerhosted", "dockerProxy", "jcenter", "pythonProxy"]
for (item in list) {
    log.info("creating blobstore " + item)
    blobStore.createFileBlobStore(item, item)
}




creating hosted repositories

import org.sonatype.nexus.repository.storage.WritePolicy;
import org.sonatype.nexus.repository.maven.VersionPolicy;
import org.sonatype.nexus.repository.storage.WritePolicy
import org.sonatype.nexus.repository.maven.LayoutPolicy


repository.createDockerHosted(name = 'pippo', httpPort = 8123, httpsPort = null, blobStoreName = 'docker', strictContentTypeValidation=true, v1Enabled=true, writePolicy = WritePolicy.ALLOW, forceBasicAuth=false)

repository.createMavenHosted(name = 'ivyhosted', blobStoreName = 'ivy', strictContentTypeValidation = true, versionPolicy = VersionPolicy.RELEASE, writePolicy= WritePolicy.ALLOW_ONCE, layoutPolicy=LayoutPolicy.PERMISSIVE )




You cannot delete anonymous, the only way is to update it:

import org.sonatype.nexus.security.user.*
import org.sonatype.nexus.security.role.*

// the following 6 lines are not required
anonymous = security.getSecuritySystem().getUser("anonymous", "default")
log.info("Anonymous before=" + anonymous)
Set allRoles = security.getSecuritySystem().listRoles();
log.info("allRoles=" + allRoles)
advRole = allRoles.find{it.roleId=='ADVRole'}
log.info("advRole=" + advRole)

// these 2 lines below do the job
advRoleIdentifier = new RoleIdentifier('default', 'ADVRole');
security.getSecuritySystem().setUsersRoles("anonymous", "default", [advRoleIdentifier].toSet())



Script to create/update a role (without affecting existing users using that role, if existing)



import org.sonatype.nexus.security.user.*
import org.sonatype.nexus.security.role.*
import static org.sonatype.nexus.security.user.UserManager.DEFAULT_SOURCE

privileges = [
            "nx-search-read",
            "nx-repository-view-*-*-read",
            "nx-repository-view-*-*-browse",
            "nx-repository-view-*-*-add",
            "nx-repository-view-*-*-edit",
            "nx-apikey-all"
]

createOrUpdateRole("pippo", privileges, [])
createOrUpdateUser("pippouser", [ "pippo", "nx-admin" ])

def createOrUpdateRole(rolename, privileges, roles) {
    log.info("calling createOrUpdateRole with parameters rolename=" + rolename + " privileges=" + privileges + " roles=" + roles)
 Set allRoles = security.getSecuritySystem().listRoles()
 Role role = allRoles.find{it.roleId==rolename}
 if (role != null) {
     log.info("existing role=" + role)
  role.setPrivileges(privileges.toSet())
  role.setRoles(roles.toSet())
  log.info("updating role=" + role)
  // security.securitySystem.getAuthorizationManager(DEFAULT_SOURCE).deleteRole(role.roleId)
  security.securitySystem.getAuthorizationManager(DEFAULT_SOURCE).updateRole(role)
  log.info("role updated=" + role)
 }
 else {
  log.info("adding role " + rolename)
  security.addRole(rolename, rolename, rolename, privileges, roles)
  log.info("role " + rolename + " successfully added")
 }
}



def createOrUpdateUser(username, roles) {
 log.info("calling createOrUpdateUser with parameters username=" + username + " roles=" + roles)
 Set allUsers = security.getSecuritySystem().listUsers()
 User user = allUsers.find{it.userId == username}
 if (user != null) {
  log.info("updating existing user=" + user)
  Set roleIdentifiers = new HashSet()
  roles.each{ role -> roleIdentifiers.add(new RoleIdentifier("default", role))}
  security.getSecuritySystem().setUsersRoles(username, "default", roleIdentifiers)
 }
 else {
  security.addUser(username, username, username, username + "@gmail.com", true, username, roles)
 }
}






Eclipse jee-2018-09 hangs upon restarting

Eclipse jee-2018-09 hangs upon restarting

I do a "ps -ef | grep -i eclipse" then a jstack on the process, to find out that:

ModalContext" #136 prio=6 os_prio=0 tid=0x00007fbe7885f000 nid=0x2744 waiting for monitor entry [0x00007fbdc980f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
 at org.eclipse.swt.widgets.Display.asyncExec(Display.java:866)
 - waiting to lock <0x00000000c030b110> (a java.lang.Class for org.eclipse.swt.graphics.Device)
 at org.eclipse.jface.operation.AccumulatingProgressMonitor.beginTask(AccumulatingProgressMonitor.java:146)
 at org.eclipse.core.runtime.ProgressMonitorWrapper.beginTask(ProgressMonitorWrapper.java:51)
 at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$CancelableProgressMonitorWrapper.beginTask(IDEWorkbenchAdvisor.java:463)
 at org.eclipse.core.runtime.ProgressMonitorWrapper.beginTask(ProgressMonitorWrapper.java:51)
 at org.eclipse.core.internal.resources.SaveManager.save(SaveManager.java:1157)
 at org.eclipse.core.internal.resources.Workspace.save(Workspace.java:2335)
 at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$5.run(IDEWorkbenchAdvisor.java:529)
 at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:122)


"Worker-33: Building workspace" #133 prio=5 os_prio=0 tid=0x00007fbe54f7b800 nid=0x2731 waiting for monitor entry [0x00007fbdf8133000]
   java.lang.Thread.State: BLOCKED (on object monitor)
 at org.eclipse.swt.graphics.Device.isDisposed(Device.java:835)
 - waiting to lock <0x00000000c030b110> (a java.lang.Class for org.eclipse.swt.graphics.Device)
 at org.eclipse.ui.internal.UILockListener.isUI(UILockListener.java:188)
 at org.eclipse.ui.internal.UILockListener.aboutToRelease(UILockListener.java:123)
 at org.eclipse.core.internal.jobs.LockManager.aboutToRelease(LockManager.java:92)
 at org.eclipse.core.internal.jobs.OrderedLock.doRelease(OrderedLock.java:189)
 - locked <0x00000000c648be58> (a org.eclipse.core.internal.jobs.OrderedLock)
 at org.eclipse.core.internal.jobs.OrderedLock.release(OrderedLock.java:237)
 at org.eclipse.core.internal.resources.WorkManager.beginUnprotected(WorkManager.java:109)
 at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2291)
 at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2319)
 at org.eclipse.wst.jsdt.internal.core.JavaModelManager.initializeAllContainers(JavaModelManager.java:2162)
 at org.eclipse.wst.jsdt.internal.core.JavaModelManager.getJsGlobalScopeContainer(JavaModelManager.java:1536)
 at org.eclipse.wst.jsdt.core.JavaScriptCore.getJsGlobalScopeContainer(JavaScriptCore.java:1358)
 at org.eclipse.wst.jsdt.internal.core.JavaProject.resolveClasspath(JavaProject.java:2748)
 at org.eclipse.wst.jsdt.internal.core.JavaProject.getResolvedClasspath(JavaProject.java:2027)
 at org.eclipse.wst.jsdt.internal.core.DeltaProcessor.validateClasspaths(DeltaProcessor.java:2264)
 at org.eclipse.wst.jsdt.internal.core.DeltaProcessor.resourceChanged(DeltaProcessor.java:1950)
 at org.eclipse.wst.jsdt.internal.core.DeltaProcessingState.resourceChanged(DeltaProcessingState.java:389)
 at org.eclipse.core.internal.events.NotificationManager$1.run(NotificationManager.java:300)
 at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45)
 at org.eclipse.core.internal.events.NotificationManager.notify(NotificationManager.java:290)
 at org.eclipse.core.internal.events.NotificationManager.broadcastChanges(NotificationManager.java:153)
 at org.eclipse.core.internal.resources.Workspace.broadcastBuildEvent(Workspace.java:365)
 at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:141)
 at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:235)
 at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)



it seems related to this bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=522174

Just kill the bastard and move on.


Eclipse is a total piece of shit - they should simply rewrite it from scratch using a better design. Time invested in maintaining this old elephant is totally wasted.






Nexus programmatically create Repositories

Nexus API sucks - big time.

This https://blog.sonatype.com/automated-setup-of-a-repository-manager is a desperate attempt to automate stuff.


git clone https://github.com/sonatype/nexus-book-examples.git
cd ./nexus-book-examples/scripting/complex-script

docker run -d -p 8081:8081 --name nexus sonatype/nexus3:3.10.0
see https://hub.docker.com/r/sonatype/nexus3/tags/

check the logs by
docker exec -ti nexus /bin/bash
more /opt/sonatype/sonatype-work/nexus3/log/nexus.log


rm -rf /home/centos/.groovy/grapes/
rm -rf /home/centos/.m2/repository/



You can easily test your scripts from the Nexus UI (create execute script UI) , and also debut them remotely from Intellij :

https://support.sonatype.com/hc/en-us/articles/115015812727-Nexus-3-Groovy-Script-development-environment-setup


Try running this script:

repository.createMavenHosted('pippo')

it can't be easier!


The RepositoryAPI is available here

https://github.com/sonatype/nexus-public/blob/master/plugins/nexus-script-plugin/src/main/java/org/sonatype/nexus/script/plugin/RepositoryApi.java

Repository createMavenHosted(final String name,
final String blobStoreName,
final boolean strictContentTypeValidation,
final VersionPolicy versionPolicy,
final WritePolicy writePolicy,
final LayoutPolicy layoutPolicy);

example:


repository.createMavenHosted('private-again', 'default', true, org.sonatype.nexus.repository.maven.policy.VersionPolicy.SNAPSHOT, org.sonatype.nexus.repository.storage.WritePolicy.ALLOW_ONCE, org.sonatype.nexus.repository.maven.LayoutPolicy.STRICT)



To list repositories (unfortunately it returns only partial information about the Repository):

curl -X GET --header 'Accept: application/json' 'http://localhost:8081/service/rest/beta/repositories'


[ {
  "name" : "nuget.org-proxy",
  "format" : "nuget",
  "type" : "proxy",
  "url" : "http://localhost:8081/repository/nuget.org-proxy"
}, {
  "name" : "maven-releases",
  "format" : "maven2",
  "type" : "hosted",
  "url" : "http://localhost:8081/repository/maven-releases"
}, {
  "name" : "maven-snapshots",
  "format" : "maven2",
  "type" : "hosted",
  "url" : "http://localhost:8081/repository/maven-snapshots"
}, {
  "name" : "maven-central",
  "format" : "maven2",
  "type" : "proxy",
  "url" : "http://localhost:8081/repository/maven-central"
}, {
  "name" : "nuget-group",
  "format" : "nuget",
  "type" : "group",
  "url" : "http://localhost:8081/repository/nuget-group"
}, {
  "name" : "nuget-hosted",
  "format" : "nuget",
  "type" : "hosted",
  "url" : "http://localhost:8081/repository/nuget-hosted"
}, {
  "name" : "maven-public",
  "format" : "maven2",
  "type" : "group",
  "url" : "http://localhost:8081/repository/maven-public"
} ]


Ref: https://help.sonatype.com/repomanager3/rest-and-integration-api/script-api/writing-scripts about Groovy Scripting in Nexus




Tuesday, October 9, 2018

centos filesystem ntfs not configured in kernel

trying to install an external HD (Windows formatted) on a Centos box...

centos@localhost ~]$ sudo fdisk -l /dev/sdc2

Disk /dev/sdc2: 4000.7 GB, 4000650887168 bytes, 7813771264 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 33553920 bytes
Disk label type: dos
Disk identifier: 0x6e697373

This doesn't look like a partition table
Probably you selected the wrong device.

     Device Boot      Start         End      Blocks   Id  System
/dev/sdc2p1   ?  1936269394  3772285809   918008208   4f  QNX4.x 3rd part
Partition 1 does not start on physical sector boundary.
/dev/sdc2p2   ?  1917848077  2462285169   272218546+  73  Unknown
Partition 2 does not start on physical sector boundary.
/dev/sdc2p3   ?  1818575915  2362751050   272087568   2b  Unknown
Partition 3 does not start on physical sector boundary.
/dev/sdc2p4   ?  2844524554  2844579527       27487   61  SpeedStor
Partition 4 does not start on physical sector boundary.

Partition table entries are not in disk order
[centos@localhost ~]$ 


sudo yum install epel-release

Package epel-release-7-11.noarch already installed and latest version
Nothing to do


find /lib/modules/ | grep ntfs


nothing is found!

sudo yum install ntfs-3g -y



and now it works! Great! New mountpoint is /run/media/centos/Seagate\ Expansion\ Drive/


REF:

https://www.rootusers.com/how-to-mount-a-windows-ntfs-disk-in-linux/




Sunday, September 30, 2018

Nexus and Groovy for Setup Automation

Amazingly few people automate their Nexus administration. I guess the fault lies mostly in the company behind Nexus, who does very little to make their API usable and well documented.

This post https://blog.soebes.de/blog/2017/10/02/nexus-scripted-setup/ made me discover this API:

https://github.com/sonatype/nexus-public/blob/master/plugins/nexus-script-plugin/src/main/java/org/sonatype/nexus/script/plugin/RepositoryApi.java

Very good reading also here https://support.sonatype.com/hc/en-us/articles/115015812727-Nexus-3-Groovy-Script-development-environment-setup about using the Nexus book examples to automate the execution of these Groovy/Java scripts.

References http://www.javamonamour.org/2018/03/nexus-repository-administration.html on same topic of Automation (via REST api)

Wednesday, September 26, 2018

git delete all tags matching a regex

this will delete all remote tags containig the "iap-copy" string (more complex cases can be achieved with egrep)


git clone myrepourl
cd myproject
git tag --list | grep iap-copy | sort > allnaughtytags.txt
for mytag in `cat allnaughtytags.txt`; do git push --delete origin $mytag ; done 

The method is very slow.... there are much faster ways, but this is very simple and reliable

tested with git 1.9.4




Friday, September 21, 2018

Parsing command line arguments in Spring etc

lots of frameworks are reported here:
https://stackoverflow.com/questions/367706/how-do-i-parse-command-line-arguments-in-java/


but eventually I just want to do it using Spring classes

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/SimpleCommandLinePropertySource.html

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/JOptCommandLinePropertySource.html

The advantage in Spring is that you can directly bind the command line arguments to attributes, there is an example here

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/CommandLinePropertySource.html



A very simple example:

package org.pierre.clidemo;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.SimpleCommandLinePropertySource;
import org.springframework.boot.CommandLineRunner;


@SpringBootApplication
public class DemoApplication implements CommandLineRunner {

 public static void main(String[] args) {
  SpringApplication.run(DemoApplication.class, args);
 }

 @Override
 public void run(String... args) throws Exception {
  PropertySource ps = new SimpleCommandLinePropertySource(args);
  // --file=pippo.txt --language=EN_TO_DE --firstOriginal=true
  System.out.println("file=" + ps.getProperty("file"));
  System.out.println("language=" + ps.getProperty("language"));
  System.out.println("firstOriginal=" + ps.getProperty("firstOriginal"));
 }
}



and of course the JOptCommandLinePropertySource version is more robust...


Interesting also the https://projects.spring.io/spring-shell/ project, but only to write CLI applications







Wednesday, September 19, 2018

Eclipse Linux Tools (Docker Plugin) source code

https://wiki.eclipse.org/Linux_Tools_Project/Git

git clone git://git.eclipse.org/gitroot/linuxtools/org.eclipse.linuxtools.git



jars are installed NOT under the Eclipse installation folder, BUT here

/home/centos/.p2/pool/features/org.eclipse.linuxtools.docker.feature_4.0.0.201806122135
/home/centos/.p2/pool/plugins/org.eclipse.linuxtools.docker.docs_4.0.0.201806122135.jar
/home/centos/.p2/pool/plugins/org.eclipse.linuxtools.docker.core_4.0.0.201806122135.jar
/home/centos/.p2/pool/plugins/org.eclipse.linuxtools.docker.editor_1.0.0.201806122135.jar
/home/centos/.p2/pool/plugins/org.eclipse.linuxtools.docker.ui_4.0.0.201806122135.jar


Here they explain how to submit a bug http://git.eclipse.org/c/linuxtools/org.eclipse.linuxtools.git/about/

Unfortunately there is a bug in org.eclipse.linuxtools.internal.docker.ui.wizards.ContainerCopyTo

@Override
    public boolean performFinish() {
        boolean finished = mainPage.finish();
        if (finished) {
            target = mainPage.getDestination().toOSString();
            sources = mainPage.getFilesToCopy();
        }
        return finished;
    }

If you run Eclipse on Windows, and the docker daemon runs on Linux, the toOSString() formats any path into the Windows format, which is not recognized by Linux. So you can't specify "/var" because it will be turned into "\\var" which obviously fails on Linux.

https://bugs.eclipse.org/bugs/show_bug.cgi?id=539239 bug submitted





Monday, September 17, 2018

Nexus Maven repository migration

I need to migrate a Nexus 2.14 Maven repository to Nexus 3.10.

Unfortunately the Nexus product doesn't care much about migrations... probably they believe that, once installed, their product is immovable, like a sick elephant.

With a Nexus 2.14 to Nexus 2.14 migration, the repository structure is so simple that you can do it with a rsync.
But Nexus 3.10 is a totally different beast.

Luckily there are people who wrote tools:


https://github.com/simpligility/maven-repository-tools



I have to migrate from http://localhost:8081/nexus/content/repositories/releases/ (Nexus 2.14) to http://localhost:8181/repository/releases/ (Nexus 3.10)

git clone https://github.com/simpligility/maven-repository-tools.git
cd maven-repository-tools
mvn package
java -jar maven-repository-provisioner/target/maven-repository-provisioner-1.3.2-SNAPSHOT-jar-with-dependencies.jar

java -jar maven-repository-provisioner/target/maven-repository-provisioner-1.3.2-SNAPSHOT-jar-with-dependencies.jar -s http://localhost:8081/nexus/content/repositories/releases/ -t http://localhost:8181/repository/releases/ -u admin -p admin123 -a org.pierre:pvjoinfacestest:war:1.0


tragically, the tool doesn't allow wildcards.... so you must know in advance the gav of ALL the artifacts you have to migrate.... my impression is also that the .war is not really uploaded!


I am trying this one https://github.com/DarthHater/nexus-repository-import-scripts

copy https://github.com/DarthHater/nexus-repository-import-scripts/blob/master/mavenimport.sh to my /home/centos/nexus214/sonatype-work/nexus/storage/releases folder, then run

./mavenimport.sh -r http://localhost:8181/repository/releases/ -u admin -p admin123

and it works!



Friday, September 14, 2018

NordVPN programmatic API

https://github.com/jjangsangy/nordvpn/blob/master/nordvpn/api.py

'address': '/user/address',
'config': '/files/zipv2',
'nameserver': '/dns/smart',
'server': '/server',
'stats': '/server/stats',
'user': '/user/databytoken'


list of all NordVPN servers:

https://api.nordvpn.com/server

0
id 98288
ip_address "103.236.151.2"
search_keywords []
categories […]
name "Indonesia #2"
domain "id2.nordvpn.com"
price 0
flag "ID"
country "Indonesia"
location
lat -6.174444
long 106.829444
load 55
features
ikev2 true
openvpn_udp true
openvpn_tcp true
socks true
proxy true
pptp false
l2tp false
openvpn_xor_udp false
openvpn_xor_tcp false
proxy_cybersec true
proxy_ssl true
proxy_ssl_cybersec true



return my current IP
https://api.nordvpn.com/user/address


https://api.nordvpn.com/files/zipv2 downloads a config.zip file (some 20 MB) full of .ovpn files, for each server, with PKI key to connect to the server


https://api.nordvpn.com/dns/smart returns a list of IPs, probably of the NordVPN dns server


https://api.nordvpn.com/user/databytoken


https://bitbucket.org/nordial/nordapi/overview here you find how to login into API :

https://bitbucket.org/nordial/nordapi/raw/dd4e918e84b66a7842cbbf2262ad4019ead2e877/nordtoy.py







Monday, September 3, 2018

Nexus HTTP/1.1 407 Proxy Authentication Required

While trying to connect to https://repo.typesafe.com/typesafe/ivy-releases/ and https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/ over a corporate proxy with these 2 sites whitelisted, we keep getting:


org.sonatype.nexus.repository.maven.internal.proxy.MavenProxyFacet - Exception org.sonatype.nexus.repository.proxy.ProxyServiceException: HTTP/1.1 407 Proxy Authentication Required checking remote for update, proxy repo ivyreleases_proxy failed to fetch com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/ivys/ivy.xml with status line HTTP/1.1 407 Proxy Authentication Required, content not in cache.



If you enable ROOT logging at DEBUG (menu Support/Logging in Nexus console) you will see that a redirect is taking place, but the LAZY Nexus developer only logs the message and not the additional ESSENTIAL parameters to understand what is going on https://github.com/sonatype/nexus-public/blob/master/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/proxy/ProxyFacetSupport.java, that is a redirection to https://dl.bintray.com

2018-09-03 13:11:48,044+0200 DEBUG [qtp46263989-6144]  *UNKNOWN org.sonatype.nexus.repository.maven.internal.proxy.MavenProxyFacet - Fetching: GET https://repo.typesafe.com/typesafe/ivy-releases/com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/ivys/ivy.xml HTTP/1.1
2018-09-03 13:11:48,046+0200 DEBUG [qtp46263989-6144]  *UNKNOWN org.sonatype.nexus.httpclient.outbound - https://repo.typesafe.com/typesafe/ivy-releases/com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/ivys/ivy.xml > GET /typesafe/ivy-releases/com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/ivys/ivy.xml HTTP/1.1
2018-09-03 13:11:48,046+0200 DEBUG [qtp46263989-6144]  *UNKNOWN org.sonatype.nexus.internal.httpclient.SharedHttpClientConnectionManager - Connection request: [route: {tls}->http://ourproxyserver:8080->https://repo.typesafe.com:443][total kept alive: 0; route allocated: 0 of 20; total allocated: 0 of 200]
2018-09-03 13:11:48,046+0200 DEBUG [qtp46263989-6144]  *UNKNOWN org.sonatype.nexus.internal.httpclient.SharedHttpClientConnectionManager - Connection leased: [id: 478][route: {tls}->http://ourproxyserver:8080->https://repo.typesafe.com:443][total kept alive: 0; route allocated: 1 of 20; total allocated: 1 of 200]
2018-09-03 13:11:48,448+0200 DEBUG [qtp46263989-6144]  *UNKNOWN org.sonatype.nexus.httpclient.outbound - https://repo.typesafe.com/typesafe/ivy-releases/com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/ivys/ivy.xml < HTTP/1.1 302 Moved Temporarily @ 402.5 ms
2018-09-03 13:11:48,448+0200 DEBUG [qtp46263989-6144]  *UNKNOWN org.sonatype.nexus.internal.httpclient.SharedHttpClientConnectionManager - Connection [id: 478][route: {tls}->http://ourproxyserver:8080->https://repo.typesafe.com:443] can be kept alive for 30.0 seconds
2018-09-03 13:11:48,449+0200 DEBUG [qtp46263989-6144]  *UNKNOWN org.sonatype.nexus.internal.httpclient.SharedHttpClientConnectionManager - Connection released: [id: 478][route: {tls}->http://ourproxyserver:8080->https://repo.typesafe.com:443][total kept alive: 1; route allocated: 1 of 20; total allocated: 1 of 200]
2018-09-03 13:11:48,449+0200 DEBUG [qtp46263989-6144]  *UNKNOWN org.sonatype.nexus.httpclient.outbound - https://dl.bintray.com/typesafe/ivy-releases/com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/ivys/ivy.xml > GET /typesafe/ivy-releases/com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/ivys/ivy.xml HTTP/1.1
2018-09-03 13:11:48,449+0200 DEBUG [qtp46263989-6144]  *UNKNOWN org.sonatype.nexus.internal.httpclient.SharedHttpClientConnectionManager - Connection request: [route: {tls}->http://ourproxyserver:8080->https://dl.bintray.com:443][total kept alive: 1; route allocated: 0 of 20; total allocated: 1 of 200]
2018-09-03 13:11:48,449+0200 DEBUG [qtp46263989-6144]  *UNKNOWN org.sonatype.nexus.internal.httpclient.SharedHttpClientConnectionManager - Connection leased: [id: 479][route: {tls}->http://ourproxyserver:8080->https://dl.bintray.com:443][total kept alive: 1; route allocated: 1 of 20; total allocated: 2 of 200]
2018-09-03 13:11:48,466+0200 DEBUG [qtp46263989-6144]  *UNKNOWN org.sonatype.nexus.internal.httpclient.SharedHttpClientConnectionManager - Connection released: [id: 479][route: {tls}->http://ourproxyserver:8080->https://dl.bintray.com:443][total kept alive: 1; route allocated: 0 of 20; total allocated: 1 of 200]
2018-09-03 13:11:48,466+0200 DEBUG [qtp46263989-6144]  *UNKNOWN org.sonatype.nexus.httpclient.outbound - https://dl.bintray.com/typesafe/ivy-releases/com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/ivys/ivy.xml < HTTP/1.1 407 Proxy Authentication Required @ 17.12 ms
2018-09-03 13:11:48,466+0200 DEBUG [qtp46263989-6144]  *UNKNOWN org.sonatype.nexus.repository.maven.internal.proxy.MavenProxyFacet - Response: HttpResponseProxy{HTTP/1.1 407 Proxy Authentication Required [Proxy-Authenticate: NTLM, Cache-Control: no-cache, Pragma: no-cache, Content-Type: text/html; charset=utf-8, Proxy-Connection: close, Connection: close, Content-Length: 850] org.apache.http.entity.BufferedHttpEntity@3326370a}
2018-09-03 13:11:48,466+0200 DEBUG [qtp46263989-6144]  *UNKNOWN org.sonatype.nexus.repository.maven.internal.proxy.MavenProxyFacet - Status: HTTP/1.1 407 Proxy Authentication Required
2018-09-03 13:11:48,467+0200 WARN  [qtp46263989-6144]  *UNKNOWN org.sonatype.nexus.repository.maven.internal.proxy.MavenProxyFacet - Exception org.sonatype.nexus.repository.proxy.ProxyServiceException: HTTP/1.1 407 Proxy Authentication Required checking remote for update, proxy repo ivyreleases_proxy failed to fetch com.typesafe.sbt/sbt-native-packager/scala_2.12/sbt_1.0/1.3.4/ivys/ivy.xml with status line HTTP/1.1 407 Proxy Authentication Required, content not in cache.
org.sonatype.nexus.repository.proxy.ProxyServiceException: HTTP/1.1 407 Proxy Authentication Required
 at org.sonatype.nexus.repository.proxy.ProxyFacetSupport.mayThrowProxyServiceException(ProxyFacetSupport.java:426)
 at org.sonatype.nexus.repository.proxy.ProxyFacetSupport.fetch(ProxyFacetSupport.java:400)
 at org.sonatype.nexus.repository.proxy.ProxyFacetSupport.fetch(ProxyFacetSupport.java:346)
 at org.sonatype.nexus.repository.maven.internal.proxy.MavenProxyFacet.fetch(MavenProxyFacet.java:73)
 at org.sonatype.nexus.repository.proxy.ProxyFacetSupport.doGet(ProxyFacetSupport.java:220)
 at org.sonatype.nexus.repository.proxy.ProxyFacetSupport.lambda$1(ProxyFacetSupport.java:209)
 at org.sonatype.nexus.repository.proxy.ProxyFacetSupport$$Lambda$269/1592429552.call(Unknown Source)
 at org.sonatype.nexus.repository.proxy.Cooperation$CooperatingFuture.download(Cooperation.java:262)
 at org.sonatype.nexus.repository.proxy.Cooperation.download(Cooperation.java:194)
 at org.sonatype.nexus.repository.proxy.Cooperation.cooperate(Cooperation.java:93)
 at org.sonatype.nexus.repository.proxy.ProxyFacetSupport.get(ProxyFacetSupport.java:201)
 at org.sonatype.nexus.repository.proxy.ProxyHandler.handle(ProxyHandler.java:49)
 at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
 at org.sonatype.nexus.repository.storage.UnitOfWorkHandler.handle(UnitOfWorkHandler.java:39)
 at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
 at org.sonatype.nexus.repository.view.handlers.ContentHeadersHandler.handle(ContentHeadersHandler.java:44)
 at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
 at org.sonatype.nexus.repository.maven.internal.VersionPolicyHandler.handle(VersionPolicyHandler.java:61)
 at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
 at org.sonatype.nexus.repository.http.PartialFetchHandler.handle(PartialFetchHandler.java:55)
 at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
 at org.sonatype.nexus.repository.cache.NegativeCacheHandler.handle(NegativeCacheHandler.java:42)
 at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
 at org.sonatype.nexus.repository.view.handlers.ConditionalRequestHandler.handle(ConditionalRequestHandler.java:72)
 at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
 at org.sonatype.nexus.repository.assetdownloadcount.internal.AssetDownloadCountContributedHandler.handle(AssetDownloadCountContributedHandler.java:53)
 at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
 at com.sonatype.nexus.clm.internal.QuarantineContributedHandler.handle(QuarantineContributedHandler.java:68)
 at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
 at com.sonatype.nexus.usertoken.plugin.internal.UserTokenHandler.handle(UserTokenHandler.java:70)
 at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
 at org.sonatype.nexus.repository.view.handlers.HandlerContributor.handle(HandlerContributor.java:67)
 at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
 at org.sonatype.nexus.repository.view.handlers.ExceptionHandler.handle(ExceptionHandler.java:44)
 at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
 at org.sonatype.nexus.repository.security.SecurityHandler.handle(SecurityHandler.java:52)
 at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
 at org.sonatype.nexus.repository.view.handlers.TimingHandler.handle(TimingHandler.java:46)
 at org.sonatype.nexus.repository.view.Context.proceed(Context.java:80)
 at org.sonatype.nexus.repository.view.Context.start(Context.java:114)
 at org.sonatype.nexus.repository.view.Router.dispatch(Router.java:64)
 at org.sonatype.nexus.repository.view.ConfigurableViewFacet.dispatch(ConfigurableViewFacet.java:52)
 at org.sonatype.nexus.repository.view.ConfigurableViewFacet.dispatch(ConfigurableViewFacet.java:43)
 at org.sonatype.nexus.repository.httpbridge.internal.ViewServlet.dispatchAndSend(ViewServlet.java:211)
 at org.sonatype.nexus.repository.httpbridge.internal.ViewServlet.doService(ViewServlet.java:173)
 at org.sonatype.nexus.repository.httpbridge.internal.ViewServlet.service(ViewServlet.java:126)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
 at com.google.inject.servlet.ServletDefinition.doServiceImpl(ServletDefinition.java:286)
 at com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:276)
 at com.google.inject.servlet.ServletDefinition.service(ServletDefinition.java:181)
 at com.google.inject.servlet.DynamicServletPipeline.service(DynamicServletPipeline.java:71)
 at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:85)
 at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:112)
 at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
 at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
 at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
 at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
 at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
 at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
 at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
 at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
 at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
 at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
 at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
 at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
 at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
 at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
 at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
 at org.sonatype.nexus.security.SecurityFilter.executeChain(SecurityFilter.java:85)
 at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
 at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
 at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
 at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
 at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
 at org.sonatype.nexus.security.SecurityFilter.doFilterInternal(SecurityFilter.java:101)
 at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
 at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
 at org.sonatype.nexus.repository.httpbridge.internal.ExhaustRequestFilter.doFilter(ExhaustRequestFilter.java:71)
 at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
 at com.sonatype.nexus.licensing.internal.LicensingRedirectFilter.doFilter(LicensingRedirectFilter.java:108)
 at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
 at com.codahale.metrics.servlet.AbstractInstrumentedFilter.doFilter(AbstractInstrumentedFilter.java:97)
 at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
 at org.sonatype.nexus.internal.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:68)
 at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
 at org.sonatype.nexus.internal.web.EnvironmentFilter.doFilter(EnvironmentFilter.java:102)
 at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
 at org.sonatype.nexus.internal.web.HeaderPatternFilter.doFilter(HeaderPatternFilter.java:98)
 at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:82)
 at com.google.inject.servlet.DynamicFilterPipeline.dispatch(DynamicFilterPipeline.java:104)
 at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:135)
 at org.sonatype.nexus.bootstrap.osgi.DelegatingFilter.doFilter(DelegatingFilter.java:73)
 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1629)
 at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533)
 at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
 at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
 at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
 at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190)
 at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595)
 at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188)
 at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1253)
 at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168)
 at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473)
 at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564)
 at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166)
 at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1155)
 at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
 at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
 at com.codahale.metrics.jetty9.InstrumentedHandler.handle(InstrumentedHandler.java:175)
 at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
 at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
 at org.eclipse.jetty.server.Server.handle(Server.java:530)
 at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:347)
 at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:256)
 at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
 at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
 at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
 at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:247)
 at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:140)
 at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
 at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:382)
 at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:708)
 at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:626)
 at java.lang.Thread.run(Thread.java:745)





For pypi.org , you might need to whitelist also https://files.pythonhosted.org:443