tag:blogger.com,1999:blog-63242509728449970142024-02-19T07:31:36.493+01:00m4rc1no5szturchać i regularnie uderzać sierpowymm4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.comBlogger131125tag:blogger.com,1999:blog-6324250972844997014.post-81764624142415526552020-03-19T22:11:00.000+01:002020-03-19T22:11:17.455+01:00How to install maven on macOS<p>I recommended use Homebrew to install maven:</p>
<pre>brew install maven
</pre>m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-32728288725321570392020-03-15T09:40:00.000+01:002020-03-15T09:40:07.834+01:00Przeniesienie statycznej strony do AWS S3Od dłuższego czasu nosiłem się z zamiarem przejścia ze swoją stroną domową do AWS - tak dla nauki przez zabawę. Wspomniana strona (marceen.pl) jest prosta - wiele się tam nie dzieje. Jest co prawda formularz kontaktowy i mechanizm pobierający i wyświetlający wpisy z tego bloga. Postanowiłem jednak z tego wszystkiego zrezygnować. Dzięki temu strona mogła stać się statyczna i można było ją umieścić na AWS S3 bardzo niewielkim kosztem. Utrzymanie tej strony również będzie tańsze niż przy tradycyjnym hostingu. <br />
<br />
Kroki, które trzeba wykonać:<br />
<br />
<ol>
<li>Utworzenie potrzebnych bucket'ów na S3 oraz podpięcie do nich własnej domeny (Route53): <a href="https://docs.aws.amazon.com/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.html#root-domain-walkthrough-add-record-to-hostedzone">https://docs.aws.amazon.com/AmazonS3/latest/dev/website-hosting-custom-domain-walkthrough.html#root-domain-walkthrough-add-record-to-hostedzone</a></li>
<li>Utworzenie pipeline'a pomocnego przy wdrażaniu nowej wersji (CodePipeline): <a href="https://medium.com/@sithum/automate-static-website-deployment-from-github-to-s3-using-aws-codepipeline-16acca25ebc1">https://medium.com/@sithum/automate-static-website-deployment-from-github-to-s3-using-aws-codepipeline-16acca25ebc1</a></li>
</ol>
<div>
<br /></div>
m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-59513241056018486412020-02-22T13:27:00.002+01:002022-02-14T14:29:25.483+01:00Install java on macOS with allowing version switching<p>Installing with Homebrew</p>
<pre>-- Updating brew:
brew update
-- Adding the casks tap:
brew tap homebrew/cask-versions
-- Adding AdoptOpenJDK (https://adoptopenjdk.net/ and https://github.com/AdoptOpenJDK/homebrew-openjdk):
brew tap adoptopenjdk/openjdk
-- Looking for java versions:
brew search java
-- Looking for AdoptOpenJDK versions:
brew search jdk
-- Checking the details on the java version that will be installed:
brew cask info java
-- Checking the details on the AdoptOpenJDK version that will be installed:
brew cask info jdk
-- Installing current version java:
brew cask install java
-- Installing specific version of AdoptOpenJDK:
brew install --cask adoptopenjdk12
</pre>
<p>Where is my java?</p>
<pre>/usr/libexec/java_home -V
</pre>
<p>Switching java version using .bash_profile:</p>
<pre>export JAVA_8_HOME=$(/usr/libexec/java_home -v1.8)
export JAVA_9_HOME=$(/usr/libexec/java_home -v9)
export JAVA_10_HOME=$(/usr/libexec/java_home -v10)
export JAVA_11_HOME=$(/usr/libexec/java_home -v11)
export JAVA_12_HOME=$(/usr/libexec/java_home -v12)
export JAVA_13_HOME=$(/usr/libexec/java_home -v13)
alias java8='export JAVA_HOME=$JAVA_8_HOME'
alias java9='export JAVA_HOME=$JAVA_9_HOME'
alias java10='export JAVA_HOME=$JAVA_10_HOME'
alias java11='export JAVA_HOME=$JAVA_11_HOME'
alias java12='export JAVA_HOME=$JAVA_12_HOME'
alias java13='export JAVA_HOME=$JAVA_13_HOME'
# default to Java 13
java13
</pre>
source: https://stackoverflow.com/questions/52524112/how-do-i-install-java-on-mac-osx-allowing-version-switching
<p>Installing Java17</p>
source: https://java.tutorials24x7.com/blog/how-to-install-openjdk-17-on-macm4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-10875594617174161162020-02-19T07:45:00.000+01:002020-02-22T12:55:01.967+01:00iterm2: setting keyboard shortcuts to jump to beginning/end of lineAdd new keyboard shortcut in Preferences > Profiles > Keys:
<br />
<pre>FOR ACTION SEND
⌘← "SEND HEX CODE" 0x01
⌘→ "SEND HEX CODE" 0x05
⌥← "SEND ESC SEQ" b
⌥→ "SEND ESC SEQ" f
</pre>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPbrWh-tHQOARi5ZBpDxPAO78KimTm6gSa74b8k4tqpnqesgQLZCzEs0jpSzyZY5cjPMgpDaxta3ayAGQadj6Bfb1Bf4stML0rD1Foz3cf5943XX9-vMiQsrgPJmI6yuIVIZoa2mB6w9Y/s1600/iTerm2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="690" data-original-width="1128" height="392" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPbrWh-tHQOARi5ZBpDxPAO78KimTm6gSa74b8k4tqpnqesgQLZCzEs0jpSzyZY5cjPMgpDaxta3ayAGQadj6Bfb1Bf4stML0rD1Foz3cf5943XX9-vMiQsrgPJmI6yuIVIZoa2mB6w9Y/s640/iTerm2.png" width="640" /></a></div>
m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-89777143609615349082020-01-12T11:39:00.001+01:002020-01-12T23:46:18.774+01:00pgAdmin4 on Docker - exporting and importing Servers<h2>Export:</h2>
<pre>get container id:
docker ps
dump server list:
docker exec -it {container id} python setup.py --dump-servers servers.json --user {user}
get server list:
docker cp {container id}:/pgadmin4/servers.json servers.json
</pre>
<h2>Import:</h2>
<pre>launch pgadmin:
docker run -p 801:80 --name pgadmin \
-e "PGADMIN_DEFAULT_EMAIL={user}" \
-e "PGADMIN_DEFAULT_PASSWORD={pass}" \
-d dpage/pgadmin4
get container id:
docker ps
copy server list into container:
docker cp {container id}:/tmp/servers.json
import server list:
docker exec -it {container id} python setup.py --load-servers servers.json --user {user}
</pre>
<p>
source: <a href="https://www.pgadmin.org/docs/pgadmin4/latest/import_export_servers.html">https://www.pgadmin.org/docs/pgadmin4/latest/import_export_servers.html</a>
</p>
m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-78022900981528286042018-08-14T14:48:00.000+02:002018-08-14T14:48:34.918+02:00Java - Try With Resourceshttps://www.baeldung.com/java-try-with-resourcesm4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-31770742902032271052018-06-12T09:03:00.001+02:002018-06-12T09:04:30.004+02:00Rounding BigDecimal into scale 2 in WebServiceBigDecimalConverter class:
<pre>final class BigDecimalConverter {
private final static Logger logger = LoggerFactory.getLogger(BigDecimalConverter.class);
private static final int SCALE = 2;
static String convertToString(BigDecimal bigDecimal) {
if (bigDecimal == null) {
return null;
}
logger.info("Rounding bigDecimal {} into scale {}", bigDecimal, SCALE);
return bigDecimal.setScale(SCALE, RoundingMode.HALF_UP).toString();
}
}
</pre>
BigDecimalXmlAdapter class:
<pre>public class BigDecimalXmlAdapter extends XmlAdapter<String, BigDecimal> {
private final static Logger logger = LoggerFactory.getLogger(BigDecimalXmlAdapter.class);
@Override
public BigDecimal unmarshal(String s) {
logger.info("Unmarshal String: {}", s);
try {
return new BigDecimal(s);
} catch (NumberFormatException e) {
return null;
}
}
@Override
public String marshal(BigDecimal bigDecimal) {
logger.info("Marshal BigDecimal {}", bigDecimal);
return BigDecimalConverter.convertToString(bigDecimal);
}
}
</pre>
package-info.java file:
<pre>@javax.xml.bind.annotation.XmlSchema(namespace = "http://app.host.pl/api/types", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
@javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters({
@javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter(value = pl.marceen.soap.control.BigDecimalXmlAdapter.class, type = java.math.BigDecimal.class)
})
package pl.host.app.api.types;
</pre>m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-57425208434582552822018-05-17T09:51:00.000+02:002018-05-17T09:51:04.848+02:00Testing for SimpleDateFormat thread safetyhttps://www.dontpanicblog.co.uk/2013/12/08/testing-for-simpledateformat-thread-safety/m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com1tag:blogger.com,1999:blog-6324250972844997014.post-58293221690890458732018-04-04T12:38:00.001+02:002018-04-04T12:47:43.591+02:00How to examine PostgreSQL server's SSL certificate?Save script info file postgres_get_server_cert.py
<pre style="brush: bash">#!/usr/bin/env python
import argparse
import socket
import ssl
import struct
import subprocess
import sys
import urlparse
def main():
args = get_args()
target = get_target_address_from_args(args)
sock = socket.create_connection(target)
try:
certificate_as_pem = get_certificate_from_socket(sock)
print certificate_as_pem
except Exception as exc:
sys.stderr.write('Something failed while fetching certificate: %s' %
exc.message)
sys.exit(1)
finally:
sock.close()
def get_args():
parser = argparse.ArgumentParser()
parser.add_argument('database', help='Either an IP address, hostname or'
' URL with host and port')
return parser.parse_args()
def get_target_address_from_args(args):
specified_target = args.database
if '//' not in specified_target:
specified_target = '//' + specified_target
parsed = urlparse.urlparse(specified_target)
return (parsed.hostname, parsed.port or 5432)
def get_certificate_from_socket(sock):
request_ssl(sock)
ssl_context = get_ssl_context()
sock = ssl_context.wrap_socket(sock)
sock.do_handshake()
certificate_as_der = sock.getpeercert(binary_form=True)
certificate_as_pem = encode_der_as_pem(certificate_as_der)
return certificate_as_pem
def request_ssl(sock):
# 1234.5679 is the magic protocol version used to request TLS, defined
# in pgcomm.h)
version_ssl = postgres_protocol_version_to_binary(1234, 5679)
packet = '%(length)s%(version)s' % {
'length': struct.pack('!I', 8),
'version': version_ssl,
}
sock.sendall(packet)
data = read_n_bytes_from_socket(sock, 1)
if data != 'S':
raise Exception('Backend does not support TLS')
def get_ssl_context():
# Return the strongest SSL context available locally
for proto in ('PROTOCOL_TLSv1_2', 'PROTOCOL_TLSv1', 'PROTOCOL_SSLv23'):
protocol = getattr(ssl, proto, None)
if protocol:
break
return ssl.SSLContext(protocol)
def encode_der_as_pem(cert):
# Forking out to openssl to not have to add any dependencies to script,
# preferably you'd do this with pycrypto or other ssl libraries.
cmd = ['openssl', 'x509', '-inform', 'DER']
pipe = subprocess.PIPE
process = subprocess.Popen(cmd, stdin=pipe, stdout=pipe, stderr=pipe)
stdout, stderr = process.communicate(cert)
if stderr:
raise Exception('openssl errored when converting cert to PEM: %s' %
stderr)
return stdout.strip()
def read_n_bytes_from_socket(sock, n):
buf = bytearray(n)
view = memoryview(buf)
while n:
nbytes = sock.recv_into(view, n)
view = view[nbytes:] # slicing views is cheap
n -= nbytes
return str(buf)
def postgres_protocol_version_to_binary(major, minor):
return struct.pack('!I', major << 16 | minor)
if __name__ == '__main__':
main()
</pre>
Save certificate into file cert.txt
<pre>postgres_get_server_cert.py example.com:5432 | openssl x509 > cert.txt
</pre>
Check certificate dates:
<pre>postgres_get_server_cert.py example.com:5432 | openssl x509 -noout -dates
</pre>
Check full certificate:
<pre>postgres_get_server_cert.py example.com:5432 | openssl x509 -noout -text
</pre>
source:
<ul>
<li><a target="_blank" href="https://github.com/thusoy/postgres-mitm">https://github.com/thusoy/postgres-mitm</a></li>
<li><a target="_blank" href="https://dba.stackexchange.com/questions/108710/how-to-examine-postgresql-servers-ssl-certificate">https://dba.stackexchange.com/questions/108710/how-to-examine-postgresql-servers-ssl-certificate</a></li>
</ul>m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-92197650758046840412018-02-14T12:49:00.001+01:002018-06-22T12:08:34.279+02:00How to make mock to void methods with Mockito<h2>Call Real Method</h2>
Mock not void method:
<pre>Mockito.when(jsonResponseValidator.validate(any(DefaultResponse.class))).thenCallRealMethod()
</pre>
Mock void method:
<pre>Mockito.doCallRealMethod().when(jsonResponseValidator).validate(any(DefaultResponse.class));
</pre>
You can use any of the doReturn(), doThrow(), doAnswer(),doNothing(), doCallRealMethod() family of methods.
<h2>Do Throw</h2>
Mock void method with doThrow():
<pre>...
@Mock
privare TransferSender transferSender;
...
Transfer transfer = new Transfer();
Mockito.doThrow(new MyException("kabooom!").when(transferSender).send(transfer);
</pre>
source: <a href="http://static.javadoc.io/org.mockito/mockito-core/2.15.0/org/mockito/Mockito.html#12">Mockito API</a>m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-31162487583067293512017-10-06T15:47:00.000+02:002017-10-06T15:58:50.818+02:00JavaEE - wyświetlenie całego URI za pomocą UriInfoUriInfo (za pomocą którego jest możliwe wyciągnięcie całego URI) można wstrzyknąć za pomocą adnotacji @Context jako pole klasy:
<pre style="brush: java">package pl.marceen.test.boundary;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ejb.Stateless;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
@Stateless
@Path("test")
public class TestRestReceiver {
private final static Logger logger = LoggerFactory.getLogger(TestRestReceiver.class);
@Context
private UriInfo uriInfo;
@GET
@Path("logStatus")
public String logStatus() {
logger.info("Path: {}", uriInfo.getAbsolutePath());
return "OK";
}
}
</pre>
Można wstrzyknąć UriInfo również jako atrybut metody:
<pre style="brush: java">package pl.marceen.test.boundary;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ejb.Stateless;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
@Stateless
@Path("test")
public class TestRestReceiver {
private final static Logger logger = LoggerFactory.getLogger(TestRestReceiver.class);
@GET
@Path("logStatus")
public String logStatus(@Context UriInfo uriInfo) {
logger.info("Path: {}", uriInfo.getAbsolutePath());
return "OK";
}
}
</pre>m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-85149631247211531522017-01-16T12:15:00.001+01:002017-01-16T12:16:38.419+01:00Centos6 - add and remove User<h2>Add User</h2>
<pre class="brush: bash;">sudo adduser newuser
sudo passwd newuser
</pre>
<h2>Delete User</h2>
<pre class="brush: bash;">sudo userdel -r newuser
</pre>
You can add the flag “-r” to the command if you would like to simultaneously remove the users’s home directory and files.m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-27834689508297727382017-01-11T10:36:00.000+01:002018-03-29T09:00:35.521+02:00EntityManager - find list of objects<pre class="brush: java">
public List<Element> findAllElements(Task task) {
logger.info("Try to find elements - task: {}", task.getId());
return em.createNamedQuery(Element.FIND_ALL_BY_TASK, Element.class)
.setParameter("task", task)
.getResultList();
}
</pre>
m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com2tag:blogger.com,1999:blog-6324250972844997014.post-46236139221204780452016-12-30T10:23:00.001+01:002016-12-30T10:23:58.672+01:00Convert public certificate to Base64<pre class="brush: java">String base64Encoded = Base64.encodeToString(pubkey.getEncoded(), Base64.DEFAULT).
replaceAll("\n", "");
</pre>m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-91172459613359113312016-12-29T15:51:00.001+01:002016-12-29T15:52:33.729+01:00Testy logów z log4jTworzymy klasę w /src/test/java/pakiet
<pre class="brush: java">import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;
import java.util.ArrayList;
import java.util.List;
public class LogsHistorySaver extends AppenderSkeleton {
private List<Event> logs;
public void setUp() {
logs = new ArrayList<>();
Logger.getRootLogger().addAppender(this);
}
public void tearDown() {
Logger.getRootLogger().removeAppender(this);
}
public List<Event> getLogs() {
return logs;
}
@Override
protected void append(LoggingEvent event) {
logs.add(new Event(event.getLevel(), String.valueOf(event.getMessage())));
}
@Override
public void close() {
}
@Override
public boolean requiresLayout() {
return false;
}
public class Event {
private Level level;
private String message;
Event(Level level, String message) {
this.level = level;
this.message = message;
}
public Level getLevel() {
return level;
}
public String getMessage() {
return message;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Event{");
sb.append("level=").append(level);
sb.append(", message='").append(message).append('\'');
sb.append('}');
return sb.toString();
}
}
}
</pre>
I korzystamy w niej w teście w spoób następujący:
<pre class="brush: java">public class KaboomTest {
private Kaboom sut;
private LogsHistorySaver logsHistorySaver = new LogsHistorySaver();
@Before
public void setUp() throws Exception {
logsHistorySaver.setUp();
}
@Test
public void log() throws Exception {
//when
sut.build();
//then
List<LogsHistorySaver.Event> logs = logsHistorySaver.getLogs();
assertThat(logs.size()).isEqualTo(3);
assertThat(logs.get(0).getLevel()).isEqualTo(Level.INFO);
assertThat(logs.get(0).getMessage()).isEqualTo("First log");
assertThat(logs.get(1).getLevel()).isEqualTo(Level.INFO);
assertThat(logs.get(1).getMessage()).isEqualTo("Second log");
assertThat(logs.get(2).getLevel()).isEqualTo(Level.INFO);
assertThat(logs.get(2).getMessage()).isEqualTo("Third log");
}
}
</pre>m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com2tag:blogger.com,1999:blog-6324250972844997014.post-18707251543445816732016-12-28T15:27:00.002+01:002016-12-29T10:26:49.530+01:00Mockito - mock final class<p><a target="_blank" href="https://github.com/mockito/mockito">Mockito</a> w wersji 2.4.2 umożliwia mockowanie finalnych klas (oraz metod).</p>
Wystarczy dodać plik
<pre>src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
</pre> zawierający jedną linię tekstu:
<pre>mock-maker-inline
</pre>
Maven dependency:
<pre class="brush: xml">
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.4.2</version>
</dependency>
</pre>
m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-85476820657443272392016-12-28T11:28:00.003+01:002016-12-29T11:09:46.933+01:00Stream zamiast forEachBez użycia streama (trzeba definiować listę obiektów):
<pre class="brush: bash">private List<Transaction> buildTransactions(AccountNumber accountNumber) {
List<Transaction> transactions = new ArrayList<>();
accountNumber
.getAccountHistoryList()
.forEach(accountHistory -> transactions.add(transactionBuilder.build(accountHistory)));
return transactions;
}
</pre>
Używając streama możemy tworzenie listy obiektów pominąć:
<pre class="brush: bash">private List<Transaction> buildTransactions(AccountNumber accountNumber) {
return accountNumber
.getAccountHistoryList()
.stream()
.map(accountHistory -> transactionBuilder.build(accountHistory))
.collect(Collectors.toList());
}
</pre>
Update: Można jeszcze bardziej elegancko:
<pre class="brush: bash">private List<Transaction> buildTransactions(AccountNumber accountNumber) {
return accountNumber
.getAccountHistoryList()
.stream()
.map(transactionBuilder::build)
.collect(Collectors.toList());
}
</pre>
m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-24236512365257708212016-12-28T11:08:00.000+01:002016-12-28T12:09:08.774+01:00Optional.ofNullable().orElseThrow()<p>Przykład wykorzystania klasy Optional dostępnej od Java 8.</p>
<div>Bez Optionala</div>
<pre class="brush: java">public void test(Task task) throws VerificationException {
if (task.getCustomer() == null) {
logger.error(CUSTOMER_NOT_FOUND);
throw BmVerificationException.badRequest(CUSTOMER_NOT_FOUND);
}
}
</pre>
<div>Z Optionalem</div>
<pre class="brush: java">public void test(Task task) throws VerificationException {
Optional.ofNullable(task.getCustomer()).orElseThrow(this::getException);
}
private VerificationException getException() {
logger.error(CUSTOMER_NOT_FOUND);
return VerificationException.badRequest(CUSTOMER_NOT_FOUND);
}
</pre>
m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-11683867882737563632016-12-27T09:13:00.002+01:002016-12-27T15:29:06.022+01:00AssertJ - assertThatExceptionOfTypePrzykład alternatywnego testowania wyjątku - assertThatExceptionOfType
<pre class="brush: java">public class FooTest {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock
private Validator validator;
@InjectMocks
private Foo sut;
private HistoryRequest historyRequest;
@Before
public void setUp() throws Exception {
historyRequest = new HistoryRequest();
}
@Test
public void getHistoryThrowsExceptionDueToAccessDenied() throws Exception {
when(validator.validate(historyRequest)).thenReturn(new Client());
assertThatExceptionOfType(BloggerException.class)
.isThrownBy(() -> sut.getHistory(historyRequest))
.withMessage("Access denied");
}
}
</pre>m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-62028882294725655922016-12-20T16:56:00.001+01:002016-12-27T15:29:51.454+01:00GSON - ignorowanie pól przy pomocy własnej adnotacji<h2>Tworzymy własną adnotację:</h2>
<pre class="brush: java">import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Exclude {
}
</pre>
<h2>Klasę implementującą ExclusionStrategy:</h2>
<pre class="brush: java">import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
public class AnnotationExclusionStrategy implements ExclusionStrategy {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getAnnotation(Exclude.class) != null;
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
}
</pre>
<h2>Wykorzystujemy utworzoną adnotację w POJO:</h2>
<pre class="brush: java">public abstract class ExampleRequest {
protected Long requestTime;
protected String clientCode;
@Exclude
protected String hash;
}
</pre>
<h2>Budujemy gsona np w taki sposób:</h2>
<pre class="brush: java">public class TestFacade {
private static final Gson GSON;
static {
JsonDeserializer<Date> longToDateAdapter = (json, typeOfT, context) -> new Date(json.getAsJsonPrimitive().getAsLong());
GSON = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
.registerTypeAdapter(Date.class, longToDateAdapter)
.setExclusionStrategies(new AnnotationExclusionStrategy())
.create();
}
}
</pre>
Najważniejsza w tym przykładzie jest metoda setExclusionStrategies(new AnnotationExclusionStrategy()) dzięki której cała magia działa.
źródło: http://stackoverflow.com/a/27986860/767529m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-12685711465471966162016-06-24T09:27:00.002+02:002016-07-13T08:33:49.798+02:00Git z konsoli<h2>Podstawowe polecenia</h2>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOMiA5JwObfHDfFaZXTkUczUca1id4FaEqHnEkXCYGcMe6XiImgmC0J3rIu0vUwjAVX52UJc5IEH3cW2vKoR-OH_W-a-4WMakouLeo7TAO07KUY0IhGq6Ajnsxr2rp5xn2XbFLkP4wrBY/s1600/Git-Cheat-Sheet.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="449" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOMiA5JwObfHDfFaZXTkUczUca1id4FaEqHnEkXCYGcMe6XiImgmC0J3rIu0vUwjAVX52UJc5IEH3cW2vKoR-OH_W-a-4WMakouLeo7TAO07KUY0IhGq6Ajnsxr2rp5xn2XbFLkP4wrBY/s640/Git-Cheat-Sheet.png" width="640" /></a></div>
<p>źródło: <a target="_blank" href="http://zeroturnaround.com/wp-content/uploads/2016/02/Git-Cheat-Sheet.png">http://zeroturnaround.com/</a></p>
<h2>Dodatkowe polecenia</h2>
<p>Usunięcie lokalnego brancha</p>
<pre class="brush: bash">git branch -d the_local_branch</pre>
<p>Log w postaci drzewa</p>
<pre class="brush: bash">git log --graph --decorate --oneline</pre>
<pre class="brush: bash">git log --graph --full-history --all --color --pretty=format:"%x1b[31m%h%x09%x1b[32m%d%x1b[0m%x20%s"</pre>
<p>Definiowanie własnych aliasów</p>
<pre class="brush: bash">git config --global alias.tree "log --graph --full-history --all --color --pretty=format:\"%x1b[31m%h%x09%x1b[32m%d%x1b[0m%x20%s\""</pre>
m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-69261650398231511692016-05-10T13:30:00.001+02:002016-05-10T14:38:15.434+02:00Tesseract pod Centos - JNA problem<h2>Problem:</h2>
<pre class="brush: bash">Caused by: java.lang.UnsatisfiedLinkError: /tmp/jna-1347637353/jna2637488223705099160.tmp: /tmp/jna-1347637353/jna2637488223705099160.tmp: failed to map segment from shared object: Operation not permitted
at java.lang.ClassLoader$NativeLibrary.load(Native Method) [rt.jar:1.8.0_77]
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941) [rt.jar:1.8.0_77]
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824) [rt.jar:1.8.0_77]
at java.lang.Runtime.load0(Runtime.java:809) [rt.jar:1.8.0_77]
at java.lang.System.load(System.java:1086) [rt.jar:1.8.0_77]
at com.sun.jna.Native.loadNativeDispatchLibraryFromClasspath(Native.java:851) [jna-4.2.2.jar:4.2.2 (b0)]
at com.sun.jna.Native.loadNativeDispatchLibrary(Native.java:826) [jna-4.2.2.jar:4.2.2 (b0)]
at com.sun.jna.Native.<clinit>(Native.java:140) [jna-4.2.2.jar:4.2.2 (b0)]
at net.sourceforge.tess4j.TessAPI1.<clinit>(TessAPI1.java:41) [tess4j-3.1.0.jar:3.1.0]
</pre>
<h2>Rozwiązanie problemu:</h2>
<p>Taki problem występuje ponieważ katalog /tmp jest noexec. Są dwa sposoby na rozwiązanie tego problemu. Można usunąć noexec z /tmp albo zdefiniować inne miejsce zapisu dla tmp natywnych bibliotek. Ja wybrałem ten drugi sposób i ładnie działa. Wystarczy dopisać:</p>
<pre>-Djava.io.tmpdir=/jakis_katalog/tmp
</pre>
<p>źródło: <a href="https://cloudbees.zendesk.com/hc/en-us/articles/215281717-Jenkins-fails-to-start-with-JNA-error">cloudbees.zendesk.com</a></p>m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-55473877424019939882016-05-09T13:59:00.000+02:002016-07-13T07:52:52.191+02:00Java z automatyczną akceptacją licencji <p>Instalacja Java pod Ubuntu z automatyczną akceptacją licencji. Taka możliwość może być przydatna przy instalacji składników ze skryptu - np. przy stawianiu systemu w środowisku Docker'a (w Dockerfile).</p>
<pre class="brush: bash">echo "oracle-java8-installer shared/accepted-oracle-license-v1-1 select true" | sudo debconf-set-selections
sudo apt-get install -y oracle-java8-installer</pre>m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-22929559987998062922016-05-06T21:52:00.002+02:002016-05-06T21:52:33.665+02:00Git: aktualizacja listy branchy na lokalnej maszynie<pre class="brush: bash"># list all branches, local and remote
$ git branch -av
# update remote list
$ git remote update origin --prune
</pre>m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0tag:blogger.com,1999:blog-6324250972844997014.post-81160410635395031812016-05-06T12:19:00.004+02:002016-05-06T12:19:35.076+02:00Instalacja Python 2.7.10 pod CentOS<pre class="brush: bash">yum install gcc
cd /usr/src
wget https://www.python.org/ftp/python/2.7.10/Python-2.7.10.tgz
tar xzf Python-2.7.10.tgz
cd Python-2.7.10
./configure
make altinstall
# python2.7 -V
Python 2.7.10
</pre>m4rc1no5http://www.blogger.com/profile/18141377693648186669noreply@blogger.com0