WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
74285ef
Criando o gitignore
Sep 3, 2019
88f9bcc
Iniciando o projeto
Sep 3, 2019
5158726
Criando classes domain: Expense e Category para armazenamento dos dados
Sep 3, 2019
32f736a
Integração de gastos por cartão
Sep 3, 2019
a025adc
Listagem de gastos para o usuário
Sep 3, 2019
c0c40e4
Filtro de gastos por usuário e por data
Sep 3, 2019
7cba83b
Funcionalidade: Categorização de gastos
Sep 4, 2019
3b9f8b4
Funcionalidade: Sugestão de categoria
Sep 4, 2019
2964110
Funcionalidade: Categorização automatica de gasto
Sep 4, 2019
20c6af4
Testes unitários
Sep 5, 2019
6a581d8
Adicionando mensagens de retorno em um enum
Sep 5, 2019
7861c33
Adicionando dependências de testes no pom
Sep 5, 2019
829778d
Enum para o envio das mensagens de retorno
Sep 5, 2019
bec7264
Criação da classe utils para conversão de uma String para Int
Sep 7, 2019
6648577
Adicionando configurações para execução com threads
Sep 7, 2019
72261b4
Renomeando o nome das classes para controller
Sep 7, 2019
3fe3836
SoapUI para testes
Sep 9, 2019
5aac3ca
Criação da autenticação e da autorização
Sep 9, 2019
dfc11a9
Adicionando Swagger para documentação das APIs
Sep 9, 2019
f2f1f8d
Adicionando arquivo com as variáveis de ambiente
Sep 9, 2019
d093860
Adicionando métodos para o response
Sep 9, 2019
daa25b1
Tratar exceções ao executar os comandos
Sep 9, 2019
c68aeef
Tratar as exceções ao buscar/atualizar um dado do banco de dados
Sep 9, 2019
fdb5e7d
Testes unitários
Sep 9, 2019
3223d47
Fixing: estava lançando uma exceção devido ao não tratamento do caso …
Sep 9, 2019
2b9ac87
README: procedimentos para executar o projeto
Sep 9, 2019
ba47e57
README: citando o arquivo XML do SOAPUI para realizar os requests
Sep 9, 2019
82004db
Refatorando o código
Sep 13, 2019
f3f18f6
Corrigindo testes unitários
Sep 13, 2019
a60ed2d
Retirando imports não utilizados
Sep 13, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/target/
.idea/
bin
.classpath
.project
.settings/*
5 changes: 5 additions & 0 deletions InterviewSantanderJava-soapui-project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<con:soapui-project id="c8c8f70d-6f35-47e1-9a9c-c3d2bf5a7168" activeEnvironment="Default" name="InterviewSantanderJava" resourceRoot="" soapui-version="5.5.0" abortOnError="false" runType="SEQUENTIAL" xmlns:con="http://eviware.com/soapui/config"><con:settings/><con:interface xsi:type="con:RestService" id="334d2580-73b0-4c57-9fad-8f540887c408" wadlVersion="http://wadl.dev.java.net/2009/02" name="http://localhost:8080" type="rest" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><con:settings/><con:definitionCache/><con:endpoints><con:endpoint>http://localhost:8080</con:endpoint></con:endpoints><con:resource name="Criar gasto" path="/expense-management/expenses" id="ef6bf5b3-5262-4eb0-b010-a6d1981dad69"><con:settings/><con:parameters/><con:method name="Expenses 1" id="ee9b271c-617b-435a-8402-2d1daaa3c623" method="POST"><con:settings/><con:parameters/><con:representation type="RESPONSE"><con:mediaType>application/json;charset=UTF-8</con:mediaType><con:status>200</con:status><con:params/><con:element xmlns:exp="http://localhost/expense-management/expenses">exp:Response</con:element></con:representation><con:representation type="REQUEST"><con:mediaType>application/json</con:mediaType><con:params/></con:representation><con:request name="Adicionar Gasto" id="90daaf70-b001-42a6-be40-6da17285cf15" mediaType="application/json" postQueryString="false"><con:settings><con:setting id="com.eviware.soapui.impl.wsdl.WsdlRequest@request-headers">&lt;xml-fragment/></con:setting></con:settings><con:endpoint>http://localhost:8080</con:endpoint><con:request>{ "description": "asd1231", "value": 12783.23, "userCode": 12283, "date": "2019-09-02T20:21:42.026Z" }</con:request><con:originalUri>http://localhost/expense-management/expenses</con:originalUri><con:credentials><con:username>admin</con:username><con:password>myadmin</con:password><con:selectedAuthProfile>Basic</con:selectedAuthProfile><con:addedBasicAuthenticationTypes>Basic</con:addedBasicAuthenticationTypes><con:authType>Global HTTP Settings</con:authType></con:credentials><con:jmsConfig JMSDeliveryMode="PERSISTENT"/><con:jmsPropertyConfig/><con:parameters/></con:request></con:method></con:resource><con:resource name="Buscar gasto por usuário" path="/expense-management/expense/userCode/{userCode}" id="945d07ac-36b6-4baf-83b9-ed8fa3e1f299"><con:settings/><con:parameters/><con:method name="UserCode 1" id="0f07163f-4c7b-404c-9abb-0ccea4920fc3" method="GET"><con:settings/><con:parameters><con:parameter><con:name>userCode</con:name><con:value>userCode</con:value><con:style>TEMPLATE</con:style><con:default>userCode</con:default><con:path xsi:nil="true"/><con:description xsi:nil="true"/></con:parameter></con:parameters><con:representation type="FAULT"><con:mediaType>application/json;charset=UTF-8</con:mediaType><con:status>401</con:status><con:params/><con:element xmlns:ns="http://localhost/expense-management/expense/userCode/12283">ns:Fault</con:element></con:representation><con:representation type="RESPONSE"><con:mediaType>application/json;charset=UTF-8</con:mediaType><con:status>200</con:status><con:params/><con:element xmlns:ns="http://localhost/expense-management/expense/userCode/12283">ns:Response</con:element></con:representation><con:request name="Buscar gastos por usuário" id="f5014fd3-d293-4815-9237-8d3abd2300dc" mediaType="application/json"><con:settings><con:setting id="com.eviware.soapui.impl.wsdl.WsdlRequest@request-headers">&lt;xml-fragment/></con:setting></con:settings><con:endpoint>http://localhost:8080</con:endpoint><con:request/><con:originalUri>http://localhost/expense-management/expense/userCode/12283</con:originalUri><con:credentials><con:username>client</con:username><con:password>theclient</con:password><con:selectedAuthProfile>Basic</con:selectedAuthProfile><con:addedBasicAuthenticationTypes>Basic</con:addedBasicAuthenticationTypes><con:authType>Global HTTP Settings</con:authType></con:credentials><con:jmsConfig JMSDeliveryMode="PERSISTENT"/><con:jmsPropertyConfig/><con:parameters><entry key="userCode" value="1227883" xmlns="http://eviware.com/soapui/config"/></con:parameters><con:parameterOrder><con:entry>userCode</con:entry></con:parameterOrder></con:request></con:method></con:resource><con:resource name="Buscar gasto por usuário e data" path="/expense-management/expense/userCode/{userCode}/date/{date}" id="c0886b3d-b528-43de-bcd8-1718880f7f77"><con:settings/><con:parameters/><con:method name="Date 1" id="b35a7ed1-d1d5-4242-95f8-a3a9a754a112" method="GET"><con:settings/><con:parameters><con:parameter><con:name>userCode</con:name><con:value>userCode</con:value><con:style>TEMPLATE</con:style><con:default>userCode</con:default><con:path xsi:nil="true"/><con:description xsi:nil="true"/></con:parameter><con:parameter><con:name>date</con:name><con:value>date</con:value><con:style>TEMPLATE</con:style><con:default>date</con:default><con:path xsi:nil="true"/><con:description xsi:nil="true"/></con:parameter></con:parameters><con:representation type="FAULT"><con:mediaType>application/json;charset=UTF-8</con:mediaType><con:status>400</con:status><con:params/><con:element xmlns:ns="http://localhost/expense-management/expense/userCode/12283/date/02092019">ns:Fault</con:element></con:representation><con:representation type="RESPONSE"><con:mediaType>application/json;charset=UTF-8</con:mediaType><con:status>200</con:status><con:params/><con:element xmlns:ns="http://localhost/expense-management/expense/userCode/12283/date/02092019">ns:Response</con:element></con:representation><con:request name="Buscar gastos por usuário e data" id="96af6e66-1a36-46e7-9342-d534abf79d37" mediaType="application/json"><con:settings><con:setting id="com.eviware.soapui.impl.wsdl.WsdlRequest@request-headers">&lt;xml-fragment/></con:setting></con:settings><con:endpoint>http://localhost:8080</con:endpoint><con:request/><con:originalUri>http://localhost/expense-management/expense/userCode/12283/date/02092019</con:originalUri><con:credentials><con:username>client</con:username><con:password>theclient</con:password><con:selectedAuthProfile>Basic</con:selectedAuthProfile><con:addedBasicAuthenticationTypes>Basic</con:addedBasicAuthenticationTypes><con:authType>Global HTTP Settings</con:authType></con:credentials><con:jmsConfig JMSDeliveryMode="PERSISTENT"/><con:jmsPropertyConfig/><con:parameters>
<con:entry key="date" value="02092019"/>
<con:entry key="userCode" value="12283"/>
</con:parameters><con:parameterOrder><con:entry>userCode</con:entry><con:entry>date</con:entry></con:parameterOrder></con:request></con:method></con:resource><con:resource name="Atualizar gasto" path="/expense-management/expense/{id}" id="968debbf-8f78-46c5-9b1a-24d09f0bcbcb"><con:settings/><con:parameters/><con:method name="Id 1" id="d793eee7-4c46-4680-8ec6-10c67fb5f0b6" method="PUT"><con:settings/><con:parameters><con:parameter><con:name>id</con:name><con:value>id</con:value><con:style>TEMPLATE</con:style><con:default>id</con:default><con:path xsi:nil="true"/><con:description xsi:nil="true"/></con:parameter></con:parameters><con:representation type="REQUEST"><con:mediaType>application/json</con:mediaType><con:params/></con:representation><con:representation type="RESPONSE"><con:mediaType>application/json;charset=UTF-8</con:mediaType><con:status>200</con:status><con:params/><con:element xmlns:afa7="http://localhost/expense-management/expense/6655afa7-7679-4098-9927-6c975f67fbd5">afa7:Response</con:element></con:representation><con:representation type="RESPONSE"><con:mediaType xsi:nil="true"/><con:status>0</con:status><con:params/><con:element>data</con:element></con:representation><con:representation type="RESPONSE"><con:mediaType xsi:nil="true"/><con:status>0</con:status><con:params/><con:element>data</con:element></con:representation><con:request name="Atualizar gasto" id="007a6cdd-546e-4473-a72f-08025798b631" mediaType="application/json" postQueryString="false"><con:settings><con:setting id="com.eviware.soapui.impl.wsdl.WsdlRequest@request-headers">&lt;xml-fragment/></con:setting></con:settings><con:endpoint>http://localhost:8080</con:endpoint><con:request>{ "description": "2134asd", "value": 12351.23, "userCode": 1227883, "date": "2019-09-01T17:21:42.026Z" }</con:request><con:originalUri>http://localhost/expense-management/expense/6655afa7-7679-4098-9927-6c975f67fbd5</con:originalUri><con:credentials><con:username>client</con:username><con:password>theclient</con:password><con:selectedAuthProfile>Basic</con:selectedAuthProfile><con:addedBasicAuthenticationTypes>Basic</con:addedBasicAuthenticationTypes><con:authType>Global HTTP Settings</con:authType></con:credentials><con:jmsConfig JMSDeliveryMode="PERSISTENT"/><con:jmsPropertyConfig/><con:parameters><entry key="id" value="6655afa7-7679-4098-9927-6c975f67fbd5" xmlns="http://eviware.com/soapui/config"/></con:parameters><con:parameterOrder><con:entry>id</con:entry></con:parameterOrder></con:request></con:method></con:resource><con:resource name="Nova categoria" path="/expense-management/categories" id="8cac33e9-f69a-4007-9ebc-66e7ee960f00"><con:settings/><con:parameters/><con:method name="Categories 1" id="1566de57-5937-4059-92b2-3a97a09dd8eb" method="POST"><con:settings/><con:parameters/><con:representation type="REQUEST"><con:mediaType>application/json</con:mediaType><con:params/></con:representation><con:representation type="RESPONSE"><con:mediaType>application/json;charset=UTF-8</con:mediaType><con:status>200</con:status><con:params/><con:element xmlns:cat="http://localhost/expense-management/categories">cat:Response</con:element></con:representation><con:request name="Adicionar nova categoria" id="3ab69066-90cf-4416-a525-58bca0c8c9ad" mediaType="application/json" postQueryString="false"><con:settings><con:setting id="com.eviware.soapui.impl.wsdl.WsdlRequest@request-headers">&lt;xml-fragment/></con:setting></con:settings><con:endpoint>http://localhost:8080</con:endpoint><con:request>{ "detail": "teste" }</con:request><con:originalUri>http://localhost/expense-management/categories</con:originalUri><con:credentials><con:username>client</con:username><con:password>theclient</con:password><con:selectedAuthProfile>Basic</con:selectedAuthProfile><con:addedBasicAuthenticationTypes>Basic</con:addedBasicAuthenticationTypes><con:authType>Global HTTP Settings</con:authType></con:credentials><con:jmsConfig JMSDeliveryMode="PERSISTENT"/><con:jmsPropertyConfig/><con:parameters/></con:request></con:method></con:resource><con:resource name="Sugestão de categoria" path="/expense-management/category/detail/{detailPrefix}" id="e3e5b5f9-4ade-41aa-a3de-c29c26854f69"><con:settings/><con:parameters/><con:method name="DetailPrefix 1" id="4547f4b3-73a0-403e-9aa3-26e08543b556" method="GET"><con:settings/><con:parameters><con:parameter><con:name>detailPrefix</con:name><con:value>detailPrefix</con:value><con:style>TEMPLATE</con:style><con:default>detailPrefix</con:default><con:path xsi:nil="true"/><con:description xsi:nil="true"/></con:parameter></con:parameters><con:representation type="RESPONSE"><con:mediaType>application/json;charset=UTF-8</con:mediaType><con:status>200</con:status><con:params/><con:element xmlns:tes="http://localhost/expense-management/category/detail/teste">tes:Response</con:element></con:representation><con:request name="Susgestão de categoria" id="b71a75e5-21ad-496d-a394-f5bcb3b66ff6" mediaType="application/json"><con:settings><con:setting id="com.eviware.soapui.impl.wsdl.WsdlRequest@request-headers">&lt;xml-fragment/></con:setting></con:settings><con:endpoint>http://localhost:8080</con:endpoint><con:request/><con:originalUri>http://localhost/expense-management/category/detail/teste</con:originalUri><con:credentials><con:username>client</con:username><con:password>theclient</con:password><con:selectedAuthProfile>Basic</con:selectedAuthProfile><con:addedBasicAuthenticationTypes>Basic</con:addedBasicAuthenticationTypes><con:authType>Global HTTP Settings</con:authType></con:credentials><con:jmsConfig JMSDeliveryMode="PERSISTENT"/><con:jmsPropertyConfig/><con:parameters><entry key="detailPrefix" value="teste" xmlns="http://eviware.com/soapui/config"/></con:parameters><con:parameterOrder><con:entry>detailPrefix</con:entry></con:parameterOrder></con:request></con:method></con:resource></con:interface><con:testSuite id="bd14fb62-e3c8-4bea-83e9-26ab566a079f" name="Tests"><con:settings/><con:runType>PARALLELL</con:runType><con:testCase id="0dd62eef-07f4-4803-840b-b8db2a2e3d6b" failOnError="true" failTestCaseOnErrors="true" keepSession="false" maxResults="0" name="TestCase" searchProperties="true"><con:settings/><con:loadTest id="b8d66535-62fc-4518-be71-c9ac202f881f" name="LoadTest"><con:settings><con:setting id="HttpSettings@close-connections">false</con:setting></con:settings><con:threadCount>100</con:threadCount><con:startDelay>0</con:startDelay><con:sampleInterval>250</con:sampleInterval><con:calculateTPSOnTimePassed>true</con:calculateTPSOnTimePassed><con:resetStatisticsOnThreadCountChange>true</con:resetStatisticsOnThreadCountChange><con:historyLimit>-1</con:historyLimit><con:testLimit>100000</con:testLimit><con:limitType>COUNT</con:limitType><con:loadStrategy><con:type>Simple</con:type><con:config><testDelay>0</testDelay><randomFactor>0.5</randomFactor></con:config></con:loadStrategy><con:assertion type="Step Status" name="Step Status"/><con:maxAssertionErrors>100</con:maxAssertionErrors><con:cancelExcessiveThreads>true</con:cancelExcessiveThreads><con:strategyInterval>500</con:strategyInterval></con:loadTest><con:properties/></con:testCase><con:properties/></con:testSuite><con:properties/><con:wssContainer><con:outgoing><con:name>interview</con:name><con:username>admin</con:username><con:password>myadmin</con:password><con:entry type="Encryption"><con:configuration/></con:entry></con:outgoing></con:wssContainer><con:oAuth2ProfileContainer/><con:oAuth1ProfileContainer/><con:sensitiveInformation/></con:soapui-project>
81 changes: 17 additions & 64 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,76 +1,29 @@
# Show me the code

### # DESAFIO:

API REST para Gestão de Gastos!

***

#### Configurando o Mongo
```
Funcionalidade: Integração de gastos por cartão
Apenas sistemas credenciados poderão incluir novos gastos
É esperado um volume de 100.000 inclusões por segundo
Os gastos, serão informados atraves do protoloco JSON, seguindo padrão:
{ "descricao": "alfanumerico", "valor": double americano, "codigousuario": numerico, "data": Data dem formato UTC }
```
```
Funcionalidade: Listagem de gastos*
Dado que acesso como um cliente autenticado que pode visualizar os gastos do cartão
Quando acesso a interface de listagem de gastos
Então gostaria de ver meus gastos mais atuais.

*Para esta funcionalidade é esperado 2.000 acessos por segundo.
*O cliente espera ver gastos realizados a 5 segundos atrás.
```
```
Funcionalidade: Filtro de gastos
Dado que acesso como um cliente autenticado
E acessei a interface de listagem de gastos
E configure o filtro de data igual a 27/03/1992
Então gostaria de ver meus gastos apenas deste dia.
```
```
Funcionalidade: Categorização de gastos
Dado que acesso como um cliente autenticado
Quando acesso o detalhe de um gasto
E este não possui uma categoria
Então devo conseguir incluir uma categoria para este
docker pull mongo
docker run -d -p 27018:27017 mongo
```

#### Executando o projeto
```
Funcionalidade: Sugestão de categoria
Dado que acesso como um cliente autenticado
Quando acesso o detalhe do gasto que não possui categoria
E começo a digitar a categoria que desejo
Então uma lista de sugestões de categoria deve ser exibida, estas baseadas em categorias já informadas por outro usuários.
mvn install
mvn clean spring-boot:run
```

As variáveis de ambiente estão configuradas no arquivo *application.properties*.
```
Funcionalidade: Categorização automatica de gasto
No processo de integração de gastos, a categoria deve ser incluida automaticamente
caso a descrição de um gasto seja igual a descrição de qualquer outro gasto já categorizado pelo cliente
o mesmo deve receber esta categoria no momento da inclusão do mesmo
mongo.host=localhost
mongo.port=27018
mongo.database=app1
thread.async_core_pool_size=5
thread.async_max_pool_size=50
```
### # Avaliação

Você será avaliado pela usabilidade, por respeitar o design e pela arquitetura da API.
É esperado que você consiga explicar as decisões que tomou durante o desenvolvimento através de commits.

* Springboot - Java - Maven (preferêncialmente) ([https://projects.spring.io/spring-boot/](https://projects.spring.io/spring-boot/))
* RESTFul ([https://blog.mwaysolutions.com/2014/06/05/10-best-practices-for-better-restful-api/](https://blog.mwaysolutions.com/2014/06/05/10-best-practices-for-better-restful-api/))
* DDD ([https://airbrake.io/blog/software-design/domain-driven-design](https://airbrake.io/blog/software-design/domain-driven-design))
* Microservices ([https://martinfowler.com/microservices/](https://martinfowler.com/microservices/))
* Testes unitários, teste o que achar importante (De preferência JUnit + Mockito). Mas pode usar o que você tem mais experiência, só nos explique o que ele tem de bom.
* SOAPUI para testes de carga ([https://www.soapui.org/load-testing/concept.html](https://www.soapui.org/load-testing/concept.html))
* Uso de diferentes formas de armazenamento de dados (REDIS, Cassandra, Solr/Lucene)
* Uso do git
* Diferencial: Criptografia de comunicação, com troca de chaves. ([http://noiseprotocol.org/](http://noiseprotocol.org/))
* Diferencial: CQRS ([https://martinfowler.com/bliki/CQRS.html](https://martinfowler.com/bliki/CQRS.html))
* Diferencial: Docker File + Docker Compose (com dbs) para rodar seus jars.

### # Observações gerais

Adicione um arquivo [README.md](http://README.md) com os procedimentos para executar o projeto.
Pedimos que trabalhe sozinho e não divulgue o resultado na internet.

Faça um fork desse desse repositório em seu Github e nos envie um Pull Request com o resultado, por favor informe por qual empresa você esta se candidatando.

### # Importante: não há prazo de entrega, faça com qualidade!

# BOA SORTE!
O arquivo *InterviewSantanderJava-soapui-project.xml* contém exemplos de chamadas para este projeto.
Loading