1 | /* | |
2 | * Copyright (c) 2015 Maxim Yunusov | |
3 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
4 | * you may not use this file except in compliance with the License. | |
5 | * You may obtain a copy of the License at | |
6 | * | |
7 | * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | * | |
9 | * Unless required by applicable law or agreed to in writing, software | |
10 | * distributed under the License is distributed on an "AS IS" BASIS, | |
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 | * See the License for the specific language governing permissions and | |
13 | * limitations under the License. | |
14 | */ | |
15 | ||
16 | package org.maxur.perfmodel.backend.infrastructure; | |
17 | ||
18 | import org.iq80.leveldb.WriteBatch; | |
19 | import org.jvnet.hk2.annotations.Service; | |
20 | import org.maxur.perfmodel.backend.domain.ConflictException; | |
21 | import org.maxur.perfmodel.backend.domain.Project; | |
22 | import org.maxur.perfmodel.backend.domain.Repository; | |
23 | import org.maxur.perfmodel.backend.service.Benchmark; | |
24 | import org.maxur.perfmodel.backend.service.DataSource; | |
25 | import org.slf4j.Logger; | |
26 | ||
27 | import javax.inject.Inject; | |
28 | import java.io.IOException; | |
29 | import java.util.Collection; | |
30 | import java.util.Optional; | |
31 | ||
32 | import static java.lang.String.format; | |
33 | import static java.util.Optional.empty; | |
34 | import static org.slf4j.LoggerFactory.getLogger; | |
35 | ||
36 | /** | |
37 | * Level Db Implementation of Project Repository. | |
38 | * | |
39 | * @author myunusov | |
40 | * @version 1.0 | |
41 | * @since <pre>30.08.2015</pre> | |
42 | */ | |
43 | @Service | |
44 | public class ProjectRepositoryLevelDbImpl implements Repository<Project> { | |
45 | ||
46 | private static final Logger LOGGER = getLogger(ProjectRepositoryLevelDbImpl.class); | |
47 | ||
48 | public static final String ROOT_PREFIX = "/"; | |
49 | ||
50 | @Inject | |
51 | private DataSource dataSource; | |
52 | ||
53 | @Override | |
54 | @Benchmark | |
55 | public Optional<Project> get(final String key) { | |
56 | try { | |
57 |
1
1. get : mutated return of Object value for org/maxur/perfmodel/backend/infrastructure/ProjectRepositoryLevelDbImpl::get to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return dataSource.get(key); |
58 | } catch (IOException | ClassNotFoundException e) { | |
59 |
1
1. get : mutated return of Object value for org/maxur/perfmodel/backend/infrastructure/ProjectRepositoryLevelDbImpl::get to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return throwError(e, "Cannot find project by id '%s'", key); |
60 | } | |
61 | } | |
62 | ||
63 | @Override | |
64 | @Benchmark | |
65 | public Collection<Project> findAll() { | |
66 | try { | |
67 |
1
1. findAll : mutated return of Object value for org/maxur/perfmodel/backend/infrastructure/ProjectRepositoryLevelDbImpl::findAll to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return dataSource.findAllByPrefix(ROOT_PREFIX); |
68 | } catch (IOException | ClassNotFoundException e) { | |
69 |
1
1. findAll : mutated return of Object value for org/maxur/perfmodel/backend/infrastructure/ProjectRepositoryLevelDbImpl::findAll to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return throwError(e, "Cannot get all projects"); |
70 | } | |
71 | } | |
72 | ||
73 | @Override | |
74 | @Benchmark | |
75 | public Optional<Project> findByName(final String name) { | |
76 | try { | |
77 |
1
1. findByName : mutated return of Object value for org/maxur/perfmodel/backend/infrastructure/ProjectRepositoryLevelDbImpl::findByName to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return dataSource.get(path(name)); |
78 | } catch (IOException | ClassNotFoundException e) { | |
79 |
1
1. findByName : mutated return of Object value for org/maxur/perfmodel/backend/infrastructure/ProjectRepositoryLevelDbImpl::findByName to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return throwError(e, "Cannot find project by name '%s'", name); |
80 | } | |
81 | } | |
82 | ||
83 | @Override | |
84 | @Benchmark | |
85 | public Optional<Project> remove(final String key) { | |
86 | try (WriteBatch batch = dataSource.createWriteBatch()) { | |
87 | final Optional<Project> result = dataSource.get(key); | |
88 |
1
1. remove : negated conditional → NO_COVERAGE |
if (result.isPresent()) { |
89 |
1
1. remove : removed call to org/maxur/perfmodel/backend/service/DataSource::delete → NO_COVERAGE |
dataSource.delete(key); |
90 |
1
1. remove : removed call to org/maxur/perfmodel/backend/service/DataSource::delete → NO_COVERAGE |
dataSource.delete(path(result.get().getName())); |
91 |
1
1. remove : removed call to org/maxur/perfmodel/backend/service/DataSource::commit → NO_COVERAGE |
dataSource.commit(batch); |
92 | } | |
93 | return result; | |
94 | } catch (IOException | ClassNotFoundException e) { | |
95 |
1
1. remove : mutated return of Object value for org/maxur/perfmodel/backend/infrastructure/ProjectRepositoryLevelDbImpl::remove to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return throwError(e, "Cannot remove project '%s'", key); |
96 | } | |
97 | ||
98 | } | |
99 | ||
100 | @Override | |
101 | @Benchmark | |
102 | public Optional<Project> add(final Project value) throws ConflictException { | |
103 | final String id = value.getId(); | |
104 | final String newName = value.getName(); | |
105 | try (WriteBatch batch = dataSource.createWriteBatch()) { | |
106 | final Optional<Project> other = dataSource.get(id); | |
107 |
1
1. add : negated conditional → NO_COVERAGE |
if (value.isSame(other)) { |
108 | return other; | |
109 | } | |
110 |
1
1. add : removed call to org/maxur/perfmodel/backend/domain/Project::checkUniqueId → NO_COVERAGE |
value.checkUniqueId(other); |
111 |
1
1. add : removed call to org/maxur/perfmodel/backend/domain/Project::checkNamesakes → NO_COVERAGE |
value.checkNamesakes(findByName(newName)); |
112 |
1
1. add : removed call to org/maxur/perfmodel/backend/domain/Project::makeVersion → NO_COVERAGE |
value.makeVersion(); |
113 |
1
1. add : removed call to org/maxur/perfmodel/backend/service/DataSource::put → NO_COVERAGE |
dataSource.put(id, value); |
114 |
1
1. add : removed call to org/maxur/perfmodel/backend/service/DataSource::put → NO_COVERAGE |
dataSource.put(path(newName), value.brief()); |
115 |
1
1. add : removed call to org/maxur/perfmodel/backend/service/DataSource::commit → NO_COVERAGE |
dataSource.commit(batch); |
116 | return Optional.of(value); | |
117 | } catch (IOException | ClassNotFoundException e) { | |
118 |
1
1. add : mutated return of Object value for org/maxur/perfmodel/backend/infrastructure/ProjectRepositoryLevelDbImpl::add to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return throwError(e, "Cannot save project '%s'", newName); |
119 | } | |
120 | } | |
121 | ||
122 | @Override | |
123 | @Benchmark | |
124 | // idempotent | |
125 | public Optional<Project> amend(final Project value) throws ConflictException { | |
126 | final String id = value.getId(); | |
127 | final String newName = value.getName(); | |
128 |
1
1. amend : removed call to org/maxur/perfmodel/backend/domain/Project::incVersion → NO_COVERAGE |
value.incVersion(); |
129 | ||
130 | try (WriteBatch batch = dataSource.createWriteBatch()) { | |
131 | final Optional<Project> prev = dataSource.get(id); | |
132 |
1
1. amend : negated conditional → NO_COVERAGE |
if (!prev.isPresent()) { |
133 | return empty(); | |
134 | } | |
135 |
1
1. amend : negated conditional → NO_COVERAGE |
if (value.isSame(prev)) { |
136 | return prev; | |
137 | } | |
138 |
1
1. amend : removed call to org/maxur/perfmodel/backend/domain/Project::checkConflictWith → NO_COVERAGE |
value.checkConflictWith(prev); |
139 |
1
1. amend : negated conditional → NO_COVERAGE |
final boolean mustBeRenamed = !prev.get().getName().equals(newName); |
140 |
1
1. amend : negated conditional → NO_COVERAGE |
if (mustBeRenamed) { |
141 |
1
1. amend : removed call to org/maxur/perfmodel/backend/domain/Project::checkNamesakes → NO_COVERAGE |
value.checkNamesakes(findByName(newName)); |
142 |
1
1. amend : removed call to org/maxur/perfmodel/backend/service/DataSource::delete → NO_COVERAGE |
dataSource.delete(path(prev.get().getName())); |
143 | } | |
144 |
1
1. amend : removed call to org/maxur/perfmodel/backend/service/DataSource::put → NO_COVERAGE |
dataSource.put(id, value); |
145 |
1
1. amend : removed call to org/maxur/perfmodel/backend/service/DataSource::put → NO_COVERAGE |
dataSource.put(path(newName), value.brief()); |
146 |
1
1. amend : removed call to org/maxur/perfmodel/backend/service/DataSource::commit → NO_COVERAGE |
dataSource.commit(batch); |
147 | return Optional.of(value); | |
148 | } catch (IOException | ClassNotFoundException e) { | |
149 |
1
1. amend : mutated return of Object value for org/maxur/perfmodel/backend/infrastructure/ProjectRepositoryLevelDbImpl::amend to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return throwError(e, "Cannot save project '%s'", newName); |
150 | } | |
151 | } | |
152 | ||
153 | private String path(final String name) { | |
154 |
1
1. path : mutated return of Object value for org/maxur/perfmodel/backend/infrastructure/ProjectRepositoryLevelDbImpl::path to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return ROOT_PREFIX + name; |
155 | } | |
156 | ||
157 | private static <T> T throwError(final Exception e, final String message, final String... args) { | |
158 | final String msg = format(message, args); | |
159 | LOGGER.error(msg, e); | |
160 | throw new IllegalStateException(msg, e); | |
161 | } | |
162 | ||
163 | } | |
Mutations | ||
57 |
1.1 |
|
59 |
1.1 |
|
67 |
1.1 |
|
69 |
1.1 |
|
77 |
1.1 |
|
79 |
1.1 |
|
88 |
1.1 |
|
89 |
1.1 |
|
90 |
1.1 |
|
91 |
1.1 |
|
95 |
1.1 |
|
107 |
1.1 |
|
110 |
1.1 |
|
111 |
1.1 |
|
112 |
1.1 |
|
113 |
1.1 |
|
114 |
1.1 |
|
115 |
1.1 |
|
118 |
1.1 |
|
128 |
1.1 |
|
132 |
1.1 |
|
135 |
1.1 |
|
138 |
1.1 |
|
139 |
1.1 |
|
140 |
1.1 |
|
141 |
1.1 |
|
142 |
1.1 |
|
144 |
1.1 |
|
145 |
1.1 |
|
146 |
1.1 |
|
149 |
1.1 |
|
154 |
1.1 |