Quelques idées sympas pour la gestion kanban.
Ce binding a été créé pour le cas d'une appli Spring-Boot, Spring-security, se lançant dans un Websphere 8.5.5.
Bean de configuration de l'application récupérant les variables JNDI
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
/**
* The Spring configuration for the application.
*/
@Configuration
@PropertySource(
encoding = "UTF-8",
value = "classpath:application.properties"
)
public class ApplicationConfig extends SpringConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationConfig.class.getCanonicalName());
private static final String JAVA_COMP_ENV = "java:comp/env";
private static final String PATH_STORAGE_FOLDER = "path/toto";
private static final String URL_SERVICE_URL = "url/ServiceUrl";
private static final String MY_DATASOURCE_JNDI_NAME = "my.datasource.jndi.name";
/**
* Load the configuration.
*
* @param environment the Spring environment.
*/
public ApplicationConfig(Environment environment) {
super(environment);
}
/**
* My database datasource.
*
* @return the datasource JNDI name.
*/
@Bean
public String myDatasourceJndiName() {
LOGGER.info("Database JNDI name set to {}", super.getProperty(MY_DATASOURCE_JNDI_NAME, String.class));
return super.getProperty(MY_DATASOURCE_JNDI_NAME, String.class);
}
/**
* Return the JNDI value associated a simple string.
*/
@Bean
public String theNameOfMyBean() {
LOGGER.info("Lonading simple string JNDI variable");
String jndiFoundPath = null;
try {
Context envEntryContext = (Context) new InitialContext().lookup(JAVA_COMP_ENV);
String jndiFoundVariable = (String) envEntryContext.lookup(PATH_STORAGE_FOLDER);
LOGGER.info("Binding JNDI {} gave {}", PATH_STORAGE_FOLDER, jndiFoundVariable);
return jndiFoundVariable;
} catch (NamingException e) {
LOGGER.info("Binding JNDI {} gave null (Naming exception).", PATH_STORAGE_FOLDER);
LOGGER.trace("raised error", e);
//Here you can default value or throw exception
}
LOGGER.info("Binding JNDI Bel storage folder path gave {}", jndiFoundPath);
if (jndiFoundPath == null || "".equals(jndiFoundPath)) {
LOGGER.info("Binding JNDI Bel storage folder path gave null.");
//Here you can default value or throw exception
}
return jndiFoundPath;
}
/**
* Return the JNDI value associated a URL.
*/
@Bean
public String servicesUrl() {
LOGGER.info("Lonading service URL JNDI variable");
String jndiFoundPath = null;
try {
Context envEntryContext = (Context) new InitialContext().lookup(JAVA_COMP_ENV);
URL jndiFoundUrl = (URL) envEntryContext.lookup(URL_SERVICE_URL);
LOGGER.info("Binding JNDI service url gave {}", jndiFoundUrl);
jndiFoundPath = jndiFoundUrl.toString();
} catch (NamingException e) {
LOGGER.info("Binding JNDI ws url gave null.");
LOGGER.trace("raised error", e);
//Here you can default value or throw exception
}
if (jndiFoundPath == null || "".equals(jndiFoundPath)) {
LOGGER.info("Binding JNDI Bel storage folder path gave null.");
//Here you can default value or throw exception
}
return jndiFoundPath;
}
}
Sample pour la datasource :
/**
* Load the Data source for the database.
*
* @return the data source.
*/
@Bean
@Primary
public DataSource dataSource() {
LOGGER.info("Load datasource");
try {
DataSource jndiDataSource = new JndiDataSourceLookup().getDataSource(this.getContext().getBean("myDatasourceJndiName", String.class));
if (jndiDataSource == null) {
LOGGER.info("DB - JNDI datasource returned null object - Default datasource");
jndiDataSource = new BoneCPDataSource(this.connectionPoolConfig());
}
LOGGER.info("DB - JNDI datasource is OK.");
return jndiDataSource;
} catch (BeansException | DataSourceLookupFailureException e) {
LOGGER.info("Error when lookup JNDI datasource => Bone-CP DataSource loaded");
return new BoneCPDataSource(this.connectionPoolConfig());
}
}
Le web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="reviewit-poc">
<display-name>TheNameYouWant</display-name>
<resource-ref>
<res-ref-name>url/ServiceUrl</res-ref-name>
<res-type>java.net.URL</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Unshareable</res-sharing-scope>
</resource-ref>
<resource-env-ref>
<description>BEL Storage Folder</description>
<resource-env-ref-name>path/toto</resource-env-ref-name>
<resource-env-ref-type>java.lang.String</resource-env-ref-type>
</resource-env-ref>
<resource-ref>
<res-ref-name>jdbc/myDatasource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Unshareable</res-sharing-scope>
</resource-ref>
</web-app>
Unit testing routes configuration with angular.
Je recopie :
This should work with any div or screen size:
.center-screen {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
min-height: 100vh;
}
<html>
<head>
</head>
<body>
<div class="center-screen">
I'm in the center
</div>
</body>
</html>
Une petite solution pour démarrer une rétro.
Ca me rappelle un certain mariage ^^
Enfin une explication claire sur le double data-binding angular
Je cite la réponse, qui m'a sauvé la vie plusieurs fois, et dont le ton prête à sourire :
OMG REALLY!! YOU CAME HERE ASKING FOR HELP AND THEN DIDN'T EXPLAIN HOW TO FIX IT!!!
THE SECOND PERSON CAME HERE WITH INSTRUCTIONS AND DIDN'T ANSWER THE QUESTION HOW TO TURN IT OFF!!!
WHAT IS WRONG WITH YOU PEOPLE!?
Toggling between line and column selection modes
To toggle between the line and the column selection modes, do one of the following:
On the main menu, choose Edit | Column Selection Mode.
On the context menu of the editor, choose Column Selection Mode.
Press Shift+Alt+Insert.
BURIED ON THIS PAGE: https://www.jetbrains.com/help/phpstorm/selecting-text-in-the-editor.html#column_selection
Google searches that were unfruitful: webstorm free spacing (visual studio/MSWord calls it free spacing), webstorm turn off multi-caret, webstorm turn off column selection. How is anyone supposed to find this setting?
Une représentation d'étapes qui gère la fougère.
Extrait de l'article :
"Ensuite, le dispositif prévu contre les fake news est bizarrement limité aux moments « précédant une élection nationale ». Pourquoi ? Peut-être parce qu'il y a eu deux importants précédents en période électorale : la propagation de fake news sur Emmanuel Macron juste avant la présidentielle (compte aux Bahamas, etc.) et, aux États-Unis, les attaques de Donald Trump contre Barack Obama. Mais les fausses nouvelles, pourtant, c'est toute l'année !"
Donc finalement, la terre plate et autres désinformation, on s'en moque, ce que l'on veut, c'est le scrutin.
Belle mentalité. J'espère que les journalistes se rendent bien compte de la supercherie.
Je vais mettre une copie du contenu :
"Certains groupes politiques au Sénat réfléchiraient à un rejet massif. Sans accord des deux chambres - ce qui est le cas le plus probable - les textes devront être examinés par une commission mixte paritaire, une étape qui n'aura pas lieu avant la rentrée a priori. Puis, si celle-ci n'aboutit pas, une nouvelle lecture sera faite par les deux chambres du Parlement. Au final, le gouvernement espère que le texte sera effectif avant les élections européennes de l'an prochain."
Ok : objectif faire élire la république en marche aux européennes
"Enfin, une partie du dispositif étend les pouvoirs du Conseil supérieur de l'audiovisuel à l'égard des chaînes étrangères. Ce texte vise sans la nommer notamment RT, la chaîne russe qui avait suscité la polémique lors de son arrivée en France et avait été vivement critiquée par Emmanuel Macron.
Ainsi, le gendarme de l'audiovisuel peut aller jusqu'à suspendre la diffusion d'une chaîne étrangère en période électorale ou résilier sa convention, sous certaines conditions. « On donne au CSA un rôle dans des rapports de force internationaux qui le dépassent sans doute. Regardez, ce qui s'est passé la semaine dernière : juste après une mise en demeure de RT, l'autorité de contrôle des médias russes a accusé France 24 d'avoir violé la loi russe sur les médias », remarque un observateur."
Ok, donc on cherche à supprimer l'info qui vient de la russie
Pas mal
Hibernate propose :
- Schéma dynamique mais unique pour toutes les entités
- Schéma figé mais différent selon entités
1) Rajouter un Interceptor Hibernate :
/**
* This class can rebuild requests.
*/
@Component
public class HibernateSchemaInterceptor extends EmptyInterceptor {
public final static Logger LOGGER = LoggerFactory.getLogger(HibernateSchemaInterceptor.class.getCanonicalName());
public HibernateSchemaInterceptor() {
LOGGER.info("initialize HibernateSchemaInterceptor bean.");
}
@Override
public String onPrepareStatement(String sql) {
String correctedSQL = sql;
correctedSQL = correctedSQL.replaceAll(GenericEntity.FIRST_SCHEMA_NAME, StaticServiceHolder.firstSchemaName);
correctedSQL = correctedSQL.replaceAll(GenericEntity.SECOND_SCHEMA_NAME, StaticServiceHolder.secondSchemaName);
return super.onPrepareStatement(correctedSQL);
}
}
Cette classe est appelée avant ou après l'exécution d'une requête.
2) Rajouter l'interceptor aux properties JPA
@Bean
public Properties jpaProperties() {
Properties props = new Properties();
super.putProperties("hibernate.dialect", props);
//super.putProperties("hibernate.hbm2ddl.auto", props);
props.setProperty("hibernate.enable_lazy_load_no_trans", "true");
props.setProperty("org.hibernate.flushMode", "AUTO");
props.setProperty("hibernate.ejb.interceptor", HibernateSchemaInterceptor.class.getCanonicalName());
LOGGER.info("Hibernate JPA Properties loaded");
return props;
}
L'instanciation serait faite via les EJB.
3) Définir un endroit ou l'interceptor pourra accéder aux beans variables (noms des schémas) :
/**
* This class inject itself the Spring context to make it available for classes not managed by Spring.
*/
@Component
public class StaticServiceHolder {
public static String firstSchemaName;
public static String secondSchemaName ;
@Autowired
public void setFirstSchemaName(String firstSchemaName) {
StaticServiceHolder.firstSchemaName = firstSchemaName;
}
@Autowired
public void setSecondSchemaName(String secondSchemaName) {
StaticServiceHolder. secondSchemaName = secondSchemaName;
}
}
4) Rajouter le nom des schémas "mocké" aux entités :
@Entity
@Table(name = "TABLE", schema = GenericEntity.FIRST_SCHEMA_NAME)
public class Entity implements GenericEntity {
//Dans les join table AUSSI :
@JoinTable(
name = "JT_ENTITY_ENTITY2",
schema = GenericEntity.FIRST_SCHEMA_NAME,
joinColumns = @JoinColumn(name = "ENTITY_ID"),
inverseJoinColumns = @JoinColumn(name = "ENTITY2_ID")
)
@ManyToMany
private Set<Entity2> linked;
Une vidéo claire
Définir l'interface graphique
"Leveraging the user feedback to validate your design ideas does not mean that you don’t require a vision of what the product should look like. The opposite is true. You have to innovate for your users and cannot expect to be told what the product should look like."
I really love this guy.
This guy is great !
Une base pour se poser la question de l'agilité.
Je ne suis pas fana du nouvel Octo racheté depuis peu mais cet article est bien :)
Exemple upload côté client :
fichier html
<input type="file" #package (change)="prepareFile(package.files)" class="is-small fileupload"/>
<button type="button" class="button is-small" (click)="importPackage()" [disabled]="!this.validPackage">Valider</button>
fichier ts :
selectedPackage: any;
prepareFile(files: any) {
this.selectedPackage = files;
//exemple pour bloquer l'upload si on a pas affaire à un zip :
if(files != null){
let extension = files[0].name.split('.').pop();
if(extension == "zip" || extension == "ZIP"){
this.validPackage = true;
}else{
this.validPackage= false;
}
}
}
importPackage(): void {
let file: File = this.selectedPackage[0];
this.packageService.uploadFile(file).subscribe(
result => this.onFileUploaded(result)
);
}
onFileUploaded(result: any): void {
this.selectedPackage = null;
}
packageService.ts
uploadFile(file: File): Observable<Entity[]> {
let formData: FormData = new FormData();
formData.append('file', file, file.name);
const url = `${this.getUrl()}/upload`;
return this.http.post(url, formData)
.map(res => this.extractListFromResponse(res))
.catch(res => this.handleError(res))
}
Dans notre cas, le retour de la requete est une liste d'item. A vous de voir de votre côté.
Controller côté java:
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public ResponseEntity uploadFile(@RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
try {
return new ResponseEntity<>(this.packageService.uploadPackage(file.getBytes()), HttpStatus.OK);
} catch (GenericBELException | IOException e) {
return super.forwardException("Impossible de récupérer le package " + file.getOriginalFilename(), e);
}
} else {
return this.createStructuredResponse("Impossible de récupérer le package " + file.getOriginalFilename() + ". Il était vide à la réception.", HttpStatus.NO_CONTENT);
}
}
A partir du file, vous pouvez extraire le contenu avec des BufferReader.