Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 2 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,9 @@

The MMS SDVC is a collection of modules built on top of the Spring Framework and is a part of Open-MBEE. For more information about Open-MBEE, visit the [Open-MBEE Website](https://openmbee.org/)

For a reference on how to create an application, see [MMSRI](https://github.com/Open-MBEE/mmsri) or the "example" package. Also see README inside each module.
#### If you are interested in deploying MMS, please see the [MMSRI](https://github.com/Open-MBEE/mmsri) quickstart.

## Quick Start
### Docker
Installation instructions are found here: [Docker documentation](https://docs.docker.com/)

1. Copy the example properties file in `example/src/main/resources/` as `application.properties`
1. In the command line, run `docker-compose up --build` to create and start all the services from the configuration.
1. Swagger ui at [http://localhost:8080/v3/swagger-ui.html](http://localhost:8080/v3/swagger-ui.html)
1. Use the command `docker-compose down` to stop any containers from running and to remove the containers, networks, and images created by the `docker-compose up` command. This command should always be done before any new attempts to restart the services from the configuration.

## Developer Setup for example project
## Developer Setup
### Docker
We suggest using Docker to set up PostgreSQL and Elasticsearch. Installation
instructions are found here: [Docker documentation](https://docs.docker.com/)
Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ ext.milestoneBuild = !(snapshotBuild || releaseBuild)

subprojects {
repositories {
maven { url 'https://repo.spring.io/plugins-release' }
gradlePluginPortal()
mavenCentral()
gradlePluginPortal()
maven { url 'https://repo.spring.io/plugins-release' }
}

plugins.withType(JavaPlugin) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,9 @@ protected void commitChanges(NodeChangeInfo info) {
commit.setDocId(cmjs.getId());
commit.setTimestamp(now);
commit.setComment(cmjs.getComment());

this.commitIndex.index(cmjs);

this.commitRepository.save(commit);
this.commitIndex.index(cmjs);
this.nodeRepository.getTransactionManager().commit(status);
} catch (Exception e) {
logger.error("commitChanges error: ", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import org.springframework.data.annotation.LastModifiedDate;

@MappedSuperclass
@JsonIgnoreProperties(value = {"created", "modified"}, allowGetters = true)
@JsonIgnoreProperties(value = {"created", "modified", "id"}, allowGetters = true)
public abstract class Base implements Serializable {

private static final long serialVersionUID = 8389104517465359723L;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public abstract class BaseElasticDAOImpl<E extends Map<String, Object>> {
protected int resultLimit;
@Value("${elasticsearch.limit.term}")
protected int termLimit;
@Value("${elasticsearch.limit.get}")
protected int getLimit;
protected static int readTimeout = 1000000000;
protected RestHighLevelClient client;
private static final RequestOptions REQUEST_OPTIONS;
Expand Down Expand Up @@ -121,28 +123,41 @@ public List<E> findAllById(String index, Set<String> docIds) {
if (docIds.isEmpty()) {
return listOfResponses;
}
int cur = 0;
MultiGetRequest request = new MultiGetRequest();
for (String eid : docIds) {
request.add(index, eid);
}
MultiGetResponse response = client.mget(request, REQUEST_OPTIONS);

for (MultiGetItemResponse res : response.getResponses()) {
GetResponse item = res.getResponse();
if (item != null && item.isExists()) {
E ob = newInstance();
ob.putAll(item.getSourceAsMap());
listOfResponses.add(ob);
} else {
continue;
cur++;
if (cur == getLimit) {
getResponses(request, listOfResponses);
cur = 0;
request = new MultiGetRequest();
}
}
if (cur > 0) {
getResponses(request, listOfResponses);
}
return listOfResponses;
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private void getResponses(MultiGetRequest request, List<E> listOfResponses) throws IOException {
MultiGetResponse response = client.mget(request, REQUEST_OPTIONS);

for (MultiGetItemResponse res : response.getResponses()) {
GetResponse item = res.getResponse();
if (item != null && item.isExists()) {
E ob = newInstance();
ob.putAll(item.getSourceAsMap());
listOfResponses.add(ob);
} else {
continue;
}
}
}

public void indexAll(String index, Collection<? extends BaseJson> jsons) {
BulkProcessor bulkProcessor = getBulkProcessor(client);
for (BaseJson json : jsons) {
Expand Down
34 changes: 11 additions & 23 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
## Quick Start
### Docker
Installation instructions are found here: [Docker documentation](https://docs.docker.com/)

1. At repo's root level, run `docker-compose up --build` to create and start all the services from the configuration. This uses the `test` Spring profile
1. Swagger ui at [http://localhost:8080/v3/swagger-ui.html](http://localhost:8080/v3/swagger-ui.html)
1. Use the command `docker-compose down` to stop any containers from running and to remove the containers, networks, and images created by the `docker-compose up` command. This command should always be done before any new attempts to restart the services from the configuration.


## Run command line api test

1. run example app on localhost (see top level readme)
1. run example app on localhost
1. if using docker-compose to bring up example app, can do the following to run the tests instead of installing node

docker run -v $PWD:/etc/newman -t --network container:mms postman/newman:alpine run crud.postman_collection.json --environment="test-env.json" --delay-request=300
Expand All @@ -12,27 +21,6 @@

newman run crud.postman_collection.json -e localhost-env.json --delay-request 300

## Swagger codegen

[Gradle Plugin](https://github.com/int128/gradle-swagger-generator-plugin)

../gradlew generateSwaggerCode

Results in build/swagger-code-*

## Swagger UI of running app

Swagger 3 UI at http://localhost:8080/v3/swagger-ui.html (not dependent on gradle codegen)

yaml at http://localhost:8080/v3/api-docs.yaml - will need to fix securitySchemes for codegen

### Fixes needed from generated yaml to use in codegen

- add basic auth security scheme

basicAuth:
type: http
scheme: basic

- change schema of ElementJson to just `type: object` (otherwise client generation ignores `additionalProperties` unless using `python-experimental` which needs other changes)
- change `addtionalProperties` in openapi spec to be just `addtionalProperties: true` where it appears
Swagger 3 UI at http://localhost:8080/v3/swagger-ui.html
1 change: 1 addition & 0 deletions example/src/main/resources/application-test.properties
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ elasticsearch.limit.insert=80
elasticsearch.limit.result=10000
elasticsearch.limit.term=1000
elasticsearch.limit.scrollTimeout=1000
elasticsearch.limit.get=10000

#Configuration for TWC
#port is for REST interface
Expand Down
1 change: 1 addition & 0 deletions example/src/main/resources/application.properties.example
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ elasticsearch.limit.insert=80
elasticsearch.limit.result=10000
elasticsearch.limit.term=1000
elasticsearch.limit.scrollTimeout=1000
elasticsearch.limit.get=100000

#Configuration for TWC
#port is for REST interface
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version=4.0.0-b2
version=4.0.0-b3
group=org.openmbee.mms

springBootVersion=2.2.6.RELEASE
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.openmbee.mms.localuser.config;

import org.openmbee.mms.localuser.security.UserCreateRequest;
import org.openmbee.mms.localuser.security.UserDetailsServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -39,7 +40,11 @@ public DaoAuthenticationProvider daoAuthenticationProvider() {
try {
userDetailsService.loadUserByUsername(adminUsername);
} catch (UsernameNotFoundException e) {
userDetailsService.register(adminUsername, adminPassword, true);
UserCreateRequest req = new UserCreateRequest();
req.setAdmin(true);
req.setPassword(adminPassword);
req.setUsername(adminUsername);
userDetailsService.register(req);
logger.info(String.format("Creating root user: %s with specified password.",
adminUsername));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
import org.openmbee.mms.core.utils.AuthenticationUtils;
import org.openmbee.mms.localuser.security.UserCreateRequest;
import org.openmbee.mms.localuser.security.UserDetailsServiceImpl;
import org.openmbee.mms.localuser.security.UsersResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
Expand All @@ -34,12 +36,20 @@ public UserCreateRequest createUser(@RequestBody UserCreateRequest req) {
try {
userDetailsService.loadUserByUsername(req.getUsername());
} catch (UsernameNotFoundException e) {
userDetailsService.register(req.getUsername(), req.getPassword(), req.isAdmin());
userDetailsService.register(req);
return req;
}
throw new BadRequestException("User already exists");
}

@GetMapping(value = "/users")
@PreAuthorize(AuthorizationConstants.IS_MMSADMIN)
public UsersResponse getUsers() {
UsersResponse res = new UsersResponse();
res.setUsers(userDetailsService.getUsers());
return res;
}

@PostMapping(value = "/password", consumes = MediaType.APPLICATION_JSON_VALUE)
@PreAuthorize("isAuthenticated()")
public Object updatePassword(@RequestBody UserCreateRequest req,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,35 @@ public class UserCreateRequest implements Serializable {

private String username;
private String password;
private String email;
private String firstname;
private String lastname;
private boolean admin;

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getFirstname() {
return firstname;
}

public void setFirstname(String firstname) {
this.firstname = firstname;
}

public String getLastname() {
return lastname;
}

public void setLastname(String lastname) {
this.lastname = lastname;
}

public String getUsername() {
return this.username;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.openmbee.mms.localuser.security;

import java.util.List;
import java.util.Optional;

import org.openmbee.mms.core.exceptions.ForbiddenException;
Expand Down Expand Up @@ -39,13 +40,20 @@ public UserDetailsImpl loadUserByUsername(String username) throws UsernameNotFou
return new UserDetailsImpl(user.get());
}

public List<User> getUsers() {
return userRepository.findAll();
}

@Transactional
public User register(String username, String password, boolean isAdmin) {
public User register(UserCreateRequest req) {
User user = new User();
user.setUsername(username);
user.setPassword(passwordEncoder.encode(password));
user.setEmail(req.getEmail());
user.setFirstName(req.getFirstname());
user.setLastName(req.getLastname());
user.setUsername(req.getUsername());
user.setPassword(passwordEncoder.encode(req.getPassword()));
user.setEnabled(true);
user.setAdmin(isAdmin);
user.setAdmin(req.isAdmin());
return userRepository.save(user);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.openmbee.mms.localuser.security;

import java.util.List;
import org.openmbee.mms.data.domains.global.User;

public class UsersResponse {

private List<User> users;

public List<User> getUsers() {
return users;
}

public void setUsers(List<User> users) {
this.users = users;
}
}