55import org .openmbee .mms .core .config .Constants ;
66import org .openmbee .mms .core .config .ContextHolder ;
77import org .openmbee .mms .core .config .Formats ;
8- import org .openmbee .mms .core .dao .BranchDAO ;
9- import org .openmbee .mms .core .dao .BranchIndexDAO ;
10- import org .openmbee .mms .core .dao .CommitDAO ;
11- import org .openmbee .mms .core .dao .NodeDAO ;
12- import org .openmbee .mms .core .dao .NodeIndexDAO ;
8+ import org .openmbee .mms .core .dao .*;
139import org .openmbee .mms .core .exceptions .BadRequestException ;
1410import org .openmbee .mms .core .exceptions .DeletedException ;
1511import org .openmbee .mms .core .exceptions .InternalErrorException ;
1814import org .openmbee .mms .core .objects .RefsResponse ;
1915import org .openmbee .mms .core .services .BranchService ;
2016import org .openmbee .mms .core .services .EventService ;
17+ import org .openmbee .mms .core .services .NodeService ;
2118import org .openmbee .mms .data .domains .scoped .Branch ;
2219import org .openmbee .mms .data .domains .scoped .Commit ;
2320import org .openmbee .mms .data .domains .scoped .Node ;
21+ import org .openmbee .mms .json .ElementJson ;
2422import org .openmbee .mms .json .RefJson ;
2523import org .slf4j .Logger ;
2624import org .slf4j .LoggerFactory ;
@@ -45,6 +43,15 @@ public class DefaultBranchService implements BranchService {
4543 private NodeIndexDAO nodeIndex ;
4644
4745 protected Collection <EventService > eventPublisher ;
46+ protected NodeGetHelper nodeGetHelper ;
47+
48+
49+
50+ @ Autowired
51+ public void setNodeGetHelper (NodeGetHelper nodeGetHelper ) {
52+ this .nodeGetHelper = nodeGetHelper ;
53+ }
54+
4855
4956 @ Autowired
5057 public void setBranchRepository (BranchDAO branchRepository ) {
@@ -129,8 +136,8 @@ public RefJson createBranch(String projectId, RefJson branch) {
129136 branch .setCreated (Formats .FORMATTER .format (now ));
130137 branch .setDeleted (false );
131138 branch .setProjectId (projectId );
132- branch .setStatus ( "created" ) ;
133-
139+ boolean fromCommit = branch .getParentCommitId () == null ? false : true ;
140+ branch . setStatus ( fromCommit ? "creating" : "created" );
134141 if (branch .getDocId () == null || branch .getDocId ().isEmpty ()) {
135142 String docId = branchIndex .createDocId (branch );
136143 branch .setDocId (docId );
@@ -145,18 +152,26 @@ public RefJson createBranch(String projectId, RefJson branch) {
145152 b .setParentRefId (Constants .MASTER_BRANCH );
146153 }
147154
148- //This service cannot create branches from historic versions
149- if (branch .getParentCommitId () != null ) {
150- throw new BadRequestException ("Internal Error: Invalid branch creation logic." );
151- }
152-
153155 Optional <Branch > refOption = branchRepository .findByBranchId (b .getParentRefId ());
154156 if (refOption .isPresent ()) {
155- Optional <Commit > parentCommit = commitRepository .findLatestByRef (refOption .get ());
156- parentCommit .ifPresent (parent -> {
157- b .setParentCommit (parent .getId ());
158- branch .setParentCommitId (parent .getCommitId ()); //commit id is same as its docId
159- });
157+ if (branch .getParentCommitId () != null ){
158+ Optional <Commit > commitRequestId = commitRepository .findByCommitId (branch .getParentCommitId ());
159+ commitRequestId .ifPresentOrElse (commit -> {
160+ Optional <Commit > parentCommit = commitRepository .findByRefAndTimestamp (refOption .get (), commit .getTimestamp ());
161+ parentCommit .ifPresent (parent -> {
162+ b .setParentCommit (parent .getId ());
163+ branch .setParentCommitId (parent .getCommitId ());
164+ });
165+ },
166+ () -> { throw new BadRequestException (new RefsResponse ().addMessage ("parentCommitId not found " + now .toString ()));
167+ });
168+ } else {
169+ Optional <Commit > parentCommit = commitRepository .findLatestByRef (refOption .get ());
170+ parentCommit .ifPresent (parent -> {
171+ b .setParentCommit (parent .getId ());
172+ branch .setParentCommitId (parent .getCommitId ()); //commit id is same as its docId
173+ });
174+ }
160175 }
161176
162177 if (b .getParentCommit () == null ) {
@@ -167,11 +182,14 @@ public RefJson createBranch(String projectId, RefJson branch) {
167182 try {
168183 branchIndex .update (branch );
169184 branchRepository .save (b );
170- Set <String > docIds = new HashSet <>();
171- for (Node n : nodeRepository .findAllByDeleted (false )) {
172- docIds .add (n .getDocId ());
185+ if (!fromCommit ) {
186+ Set <String > docIds = new HashSet <>();
187+ for (Node n : nodeRepository .findAllByDeleted (false )) {
188+ docIds .add (n .getDocId ());
189+ }
190+
191+ try { nodeIndex .addToRef (docIds ); } catch (Exception e ) {}
173192 }
174- try { nodeIndex .addToRef (docIds ); } catch (Exception e ) {}
175193 eventPublisher .forEach ((pub ) -> pub .publish (
176194 EventObject .create (projectId , branch .getId (), "branch_created" , branch )));
177195 return branch ;
@@ -181,6 +199,60 @@ public RefJson createBranch(String projectId, RefJson branch) {
181199 throw new InternalErrorException (e );
182200 }
183201 }
202+ public RefJson createBranchfromCommit (String projectId , RefJson parentCommitIdRef , NodeService nodeService ) {
203+ Instant now = Instant .now ();
204+
205+ if (parentCommitIdRef .getParentCommitId ().isEmpty ()){
206+ throw new BadRequestException (new RefsResponse ().addMessage ("parentCommitId not provided " + now .toString ()));
207+ }
208+
209+ ContextHolder .setContext (projectId );
210+ Optional <Commit > parentCommit = commitRepository .findByCommitId (parentCommitIdRef .getParentCommitId ());
211+
212+ // Get Commit object
213+ String parentCommitID = parentCommit .map (Commit ::getCommitId ).orElseThrow (() ->
214+ new BadRequestException (new RefsResponse ().addMessage ("parentCommitId not found " + now .toString ())));
215+
216+ // Get Commit parentRef, the branch will be created from this
217+ String parentRef = parentCommit .map (Commit ::getBranchId ).orElseThrow (() ->
218+ new BadRequestException (new RefsResponse ().addMessage ("Ref from parentCommitId not found" + now .toString ())));
219+
220+ parentCommitIdRef .setParentRefId (parentRef );
221+ ContextHolder .setContext (projectId , parentRef );
222+
223+ RefJson branchFromCommit = this .createBranch (projectId , parentCommitIdRef );
224+ ContextHolder .setContext (projectId , branchFromCommit .getId ());
225+
226+ // Get current nodes from database
227+ List <Node > nodes = nodeRepository .findAll ();
228+ // Get elements from index
229+ Collection <ElementJson > result = nodeGetHelper .processGetJsonFromNodes (nodes , parentCommitID , nodeService )
230+ .getActiveElementMap ().values ();
231+
232+ Map <String , ElementJson > nodeCommitData = new HashMap <>();
233+ for (ElementJson element : result ) {
234+ nodeCommitData .put (element .getId (), element );
235+ }
236+
237+ // Update database table to match index
238+ Set <String > docIds = new HashSet <>();
239+ for (Node node : nodes ) {
240+ if (nodeCommitData .containsKey (node .getNodeId ())){
241+ node .setDocId (nodeCommitData .get (node .getNodeId ()).getDocId ());
242+ node .setLastCommit (nodeCommitData .get (node .getNodeId ()).getCommitId ());
243+ node .setDeleted (false );
244+ docIds .add (node .getDocId ());
245+ } else {
246+ node .setDeleted (true );
247+ }
248+ }
249+ nodeRepository .updateAll (nodes );
250+ branchFromCommit .setStatus ("created" );
251+ branchIndex .update (branchFromCommit );
252+ try { nodeIndex .addToRef (docIds ); } catch (Exception e ) {}
253+
254+ return branchFromCommit ;
255+ }
184256
185257 public RefsResponse deleteBranch (String projectId , String id ) {
186258 ContextHolder .setContext (projectId );
0 commit comments